Move over to ABSL logging and flags.

Removes gperftools too since that wants gflags.

Here come the fireworks.

Change-Id: I79cb7bcf60f1047fbfa28bfffc21a0fd692e4b1c
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/WORKSPACE b/WORKSPACE
index 72ce0da..6be969d 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -462,11 +462,6 @@
     url = "https://software.frc971.org/Build-Dependencies/2023-12-10-bookworm-amd64-nvidia-rootfs.tar.zst",
 )
 
-local_repository(
-    name = "com_github_gflags_gflags",
-    path = "third_party/gflags",
-)
-
 # Generated with:
 # git fetch https://github.com/wpilibsuite/ni-libraries main
 # git archive --output=allwpilib_ni-libraries_776db4e8aed31a651fa2f590e7468c69b384b42a.tar.gz --format=tar.gz 776db4e8aed31a651fa2f590e7468c69b384b42a
@@ -674,11 +669,6 @@
     version = "11",
 )
 
-local_repository(
-    name = "com_github_google_glog",
-    path = "third_party/google-glog",
-)
-
 http_archive(
     name = "com_google_googletest",
     patch_args = ["-p1"],
@@ -701,9 +691,9 @@
     name = "com_google_ceres_solver",
     patch_args = ["-p1"],
     patches = ["//third_party:ceres.patch"],
-    sha256 = "a4c32939bd694a4b59fc50c244abda5d49863a56e77437b9d3bc398e17d59e20",
-    strip_prefix = "ceres-solver-7f9cc571b03632f1df93ea35725a1f5dfffe2c72",
-    urls = ["https://github.com/ceres-solver/ceres-solver/archive/7f9cc571b03632f1df93ea35725a1f5dfffe2c72.zip"],
+    sha256 = "5fef6cd0ed744a09e20d1c341a15b0f94ed0c8df43537e198a869e6c242c99d5",
+    strip_prefix = "ceres-solver-bd323ce698748bef0686eb27cb6cea4f88bb4f44",
+    urls = ["https://github.com/ceres-solver/ceres-solver/archive/bd323ce698748bef0686eb27cb6cea4f88bb4f44.zip"],
 )
 
 http_archive(
@@ -1771,5 +1761,12 @@
     build_file = "@//debian:symengine.BUILD",
     sha256 = "1b5c3b0bc6a9f187635f93585649f24a18e9c7f2167cebcd885edeaaf211d956",
     strip_prefix = "symengine-0.12.0",
-    url = "http://software.frc971.org/Build-Dependencies/github.com/symengine/symengine/releases/download/v0.12.0/symengine-0.12.0.tar.gz",
+    url = "https://github.com/symengine/symengine/releases/download/v0.12.0/symengine-0.12.0.tar.gz",
+)
+
+http_archive(
+    name = "com_google_tcmalloc",
+    sha256 = "f11a004d7361ac6cd3e41fd573b08a92db28220934e8d4c82344ce0aeb20d1e4",
+    strip_prefix = "tcmalloc-6c3e8bf43de02934525b3760571ca8781dca1869",
+    url = "https://github.com/google/tcmalloc/archive/6c3e8bf43de02934525b3760571ca8781dca1869.zip",
 )
diff --git a/aos/BUILD b/aos/BUILD
index 83adcd6..64c6587 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -100,7 +100,8 @@
     deps = [
         "//aos/ipc_lib:aos_sync",
         "//aos/mutex",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -163,7 +164,8 @@
         "//aos/events:shm_event_loop",
         "//aos/time",
         "//aos/util:top",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -182,6 +184,14 @@
         ":uuid",
         "//aos:die",
         "//aos/logging",
+        "@com_google_absl//absl/debugging:failure_signal_handler",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/flags:parse",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
+        "@com_google_absl//absl/log:flags",
+        "@com_google_absl//absl/log:globals",
+        "@com_google_absl//absl/log:initialize",
     ],
 )
 
@@ -197,7 +207,8 @@
         ":for_rust",
         ":init",
         "//aos/logging",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log:flags",
         "@crate_index//:cxx_cc",
     ],
 )
@@ -246,7 +257,8 @@
     visibility = ["//visibility:public"],
     deps = [
         ":uuid",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -317,8 +329,9 @@
         "//aos/ipc_lib:index",
         "//aos/network:team_number",
         "//aos/util:file",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/container:btree",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -392,7 +405,8 @@
     visibility = ["//visibility:public"],
     deps = [
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -403,7 +417,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -425,7 +440,8 @@
         "//aos/flatbuffers:builder",
         "//aos/util:file",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -512,7 +528,8 @@
         "//aos/ipc_lib:data_alignment",
         "//aos/util:file",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/types:span",
     ],
@@ -564,7 +581,8 @@
         ":configuration",
         ":init",
         "//aos/util:file",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -583,7 +601,8 @@
         "//aos:init",
         "//aos/events:shm_event_loop",
         "//aos/events:simulated_event_loop",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -599,7 +618,8 @@
         ":configuration",
         ":json_to_flatbuffer",
         "//aos:init",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -616,7 +636,8 @@
         ":init",
         ":json_to_flatbuffer",
         ":realtime",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -632,8 +653,9 @@
         ":configuration",
         ":init",
         ":json_to_flatbuffer",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -649,7 +671,8 @@
         ":json_to_flatbuffer",
         "//aos:init",
         "//aos/events:shm_event_loop",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -664,7 +687,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -680,7 +704,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/strings:str_format",
     ],
@@ -696,8 +721,9 @@
     deps = [
         ":init",
         ":realtime",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_googletest//:gtest",
     ],
 )
@@ -729,9 +755,10 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_gflags_gflags//:gflags",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -794,8 +821,9 @@
         "//aos/events:simulated_event_loop",
         "//aos/events/logging:log_reader",
         "//aos/time",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/actions/action_test.cc b/aos/actions/action_test.cc
index fca60a3..3d6a199 100644
--- a/aos/actions/action_test.cc
+++ b/aos/actions/action_test.cc
@@ -6,8 +6,9 @@
 #include <ostream>
 #include <string>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/actions/actions.h"
diff --git a/aos/actions/actions.h b/aos/actions/actions.h
index 1aae62f..1245f55 100644
--- a/aos/actions/actions.h
+++ b/aos/actions/actions.h
@@ -10,7 +10,8 @@
 #include <string>
 #include <type_traits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/actions/actions_generated.h"
 #include "aos/events/event_loop.h"
diff --git a/aos/actions/actor.h b/aos/actions/actor.h
index b0b6bd4..2d4294a 100644
--- a/aos/actions/actor.h
+++ b/aos/actions/actor.h
@@ -9,8 +9,9 @@
 #include <string>
 #include <type_traits>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/string.h"
-#include "glog/logging.h"
 
 #include "aos/actions/actions_generated.h"
 #include "aos/configuration_generated.h"
diff --git a/aos/analysis/BUILD b/aos/analysis/BUILD
index 85f8783..7f1f038 100644
--- a/aos/analysis/BUILD
+++ b/aos/analysis/BUILD
@@ -18,7 +18,8 @@
         "//aos/events:simulated_event_loop",
         "//aos/events/logging:log_reader",
         "//third_party/python",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/analysis/in_process_plotter.cc b/aos/analysis/in_process_plotter.cc
index 6c45389..437c71e 100644
--- a/aos/analysis/in_process_plotter.cc
+++ b/aos/analysis/in_process_plotter.cc
@@ -3,9 +3,10 @@
 #include <algorithm>
 #include <ostream>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffer_builder.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 
diff --git a/aos/analysis/local_foxglove.cc b/aos/analysis/local_foxglove.cc
index b07a628..e30f150 100644
--- a/aos/analysis/local_foxglove.cc
+++ b/aos/analysis/local_foxglove.cc
@@ -1,6 +1,6 @@
 #include <memory>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/init.h"
 #include "aos/seasocks/seasocks_logger.h"
@@ -8,9 +8,9 @@
 #include "seasocks/Logger.h"
 #include "seasocks/Server.h"
 
-DEFINE_string(data_path, "external/foxglove_studio",
-              "Path to foxglove studio files to serve.");
-DEFINE_uint32(port, 8000, "Port to serve files at.");
+ABSL_FLAG(std::string, data_path, "external/foxglove_studio",
+          "Path to foxglove studio files to serve.");
+ABSL_FLAG(uint32_t, port, 8000, "Port to serve files at.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
@@ -18,5 +18,6 @@
   findEmbeddedContent("");
   ::seasocks::Server server(std::make_shared<aos::seasocks::SeasocksLogger>(
       ::seasocks::Logger::Level::Info));
-  server.serve(FLAGS_data_path.c_str(), FLAGS_port);
+  server.serve(absl::GetFlag(FLAGS_data_path).c_str(),
+               absl::GetFlag(FLAGS_port));
 }
diff --git a/aos/analysis/py_log_reader.cc b/aos/analysis/py_log_reader.cc
index c190acb..19b0855 100644
--- a/aos/analysis/py_log_reader.cc
+++ b/aos/analysis/py_log_reader.cc
@@ -26,8 +26,9 @@
 #include <string>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/context.h"
diff --git a/aos/aos_cli_utils.cc b/aos/aos_cli_utils.cc
index 9a2c738..1a9e1d6 100644
--- a/aos/aos_cli_utils.cc
+++ b/aos/aos_cli_utils.cc
@@ -17,25 +17,26 @@
 #include "aos/events/simulated_event_loop.h"
 #include "aos/time/time.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
 
-DEFINE_bool(
-    _bash_autocomplete, false,
+ABSL_FLAG(
+    bool, _bash_autocomplete, false,
     "Internal use: Outputs channel list for use with autocomplete script.");
 
-DEFINE_bool(_zsh_compatability, false,
-            "Internal use: Force completion to complete either channels or "
-            "message_types, zsh doesn't handle spaces well.");
+ABSL_FLAG(bool, _zsh_compatability, false,
+          "Internal use: Force completion to complete either channels or "
+          "message_types, zsh doesn't handle spaces well.");
 
-DEFINE_string(_bash_autocomplete_word, "",
-              "Internal use: Current word being autocompleted");
+ABSL_FLAG(std::string, _bash_autocomplete_word, "",
+          "Internal use: Current word being autocompleted");
 
-DEFINE_bool(all, false,
-            "If true, print out the channels for all nodes, not just the "
-            "channels which are visible on this node.");
+ABSL_FLAG(bool, all, false,
+          "If true, print out the channels for all nodes, not just the "
+          "channels which are visible on this node.");
 
-DEFINE_bool(
-    canonical, false,
+ABSL_FLAG(
+    bool, canonical, false,
     "If true, print out the canonical channel names instead of the aliases.");
 
 namespace aos {
@@ -79,14 +80,15 @@
     std::string_view channel_filter_description, bool expect_args) {
   // Don't generate failure output if the config doesn't exist while attempting
   // to autocomplete.
-  if (FLAGS__bash_autocomplete &&
-      (!(EndsWith(FLAGS_config, ".json") || EndsWith(FLAGS_config, ".bfbs")))) {
+  if (absl::GetFlag(FLAGS__bash_autocomplete) &&
+      (!(EndsWith(absl::GetFlag(FLAGS_config), ".json") ||
+         EndsWith(absl::GetFlag(FLAGS_config), ".bfbs")))) {
     std::cout << "COMPREPLY=()";
     return true;
   }
 
-  config = aos::configuration::MaybeReadConfig(FLAGS_config);
-  if (FLAGS__bash_autocomplete && !config.has_value()) {
+  config = aos::configuration::MaybeReadConfig(absl::GetFlag(FLAGS_config));
+  if (absl::GetFlag(FLAGS__bash_autocomplete) && !config.has_value()) {
     std::cout << "COMPREPLY=()";
     return true;
   }
@@ -111,7 +113,7 @@
       ShiftArgs(argc, argv);
     }
 
-    if (FLAGS__bash_autocomplete) {
+    if (absl::GetFlag(FLAGS__bash_autocomplete)) {
       Autocomplete(channel_name, message_type, channel_filter);
       return true;
     }
@@ -122,8 +124,8 @@
       std::cout << "Channels:\n";
       std::set<std::pair<std::string, std::string>> channels_to_print;
       for (const aos::Channel *channel : *channels) {
-        if (FLAGS_all || channel_filter(channel)) {
-          if (FLAGS_canonical) {
+        if (absl::GetFlag(FLAGS_all) || channel_filter(channel)) {
+          if (absl::GetFlag(FLAGS_canonical)) {
             channels_to_print.emplace(channel->name()->c_str(),
                                       channel->type()->c_str());
           } else {
@@ -187,7 +189,7 @@
         continue;
       }
 
-      if (!FLAGS_all && !channel_filter(channel)) {
+      if (!absl::GetFlag(FLAGS_all) && !channel_filter(channel)) {
         LOG(FATAL) << "matched channel does not pass the channel filter: \""
                    << channel_filter_description
                    << "\" [matched channel info]: "
@@ -226,9 +228,11 @@
                     }) == 1;
 
   const bool editing_message =
-      !channel_name.empty() && FLAGS__bash_autocomplete_word == message_type;
+      !channel_name.empty() &&
+      absl::GetFlag(FLAGS__bash_autocomplete_word) == message_type;
   const bool editing_channel =
-      !editing_message && FLAGS__bash_autocomplete_word == channel_name;
+      !editing_message &&
+      absl::GetFlag(FLAGS__bash_autocomplete_word) == channel_name;
 
   std::cout << "COMPREPLY=(";
 
@@ -236,7 +240,7 @@
   // that were're editing one of the two positional arguments.
   if (!unique_match && (editing_message || editing_channel)) {
     for (const aos::Channel *channel : *config_msg->channels()) {
-      if (FLAGS_all || channel_filter(channel)) {
+      if (absl::GetFlag(FLAGS_all) || channel_filter(channel)) {
         const std::set<std::string> aliases =
             aos::configuration::GetChannelAliases(
                 config_msg, channel->name()->string_view(),
@@ -260,7 +264,8 @@
           // Otherwise, since the message type is poulated yet not being edited,
           // the user must be editing the channel name alone, in which case only
           // suggest channel names, not pairs.
-          if (!FLAGS__zsh_compatability && message_type.empty()) {
+          if (!absl::GetFlag(FLAGS__zsh_compatability) &&
+              message_type.empty()) {
             std::cout << '\'' << *it << ' ' << channel->type()->c_str() << "' ";
           } else {
             std::cout << '\'' << *it << "' ";
diff --git a/aos/aos_cli_utils.h b/aos/aos_cli_utils.h
index 199c490..980f94f 100644
--- a/aos/aos_cli_utils.h
+++ b/aos/aos_cli_utils.h
@@ -1,7 +1,7 @@
 #ifndef AOS_AOS_CLI_UTILS_H_
 #define AOS_AOS_CLI_UTILS_H_
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
diff --git a/aos/aos_dump.cc b/aos/aos_dump.cc
index 18d2ce1..ecf4add 100644
--- a/aos/aos_dump.cc
+++ b/aos/aos_dump.cc
@@ -2,37 +2,38 @@
 
 #include <iostream>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 
 #include "aos/aos_cli_utils.h"
 #include "aos/configuration.h"
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_int64(max_vector_size, 100,
-             "If positive, vectors longer than this will not be printed");
-DEFINE_bool(json, false, "If true, print fully valid JSON");
-DEFINE_bool(fetch, false,
-            "If true, fetch the current message on the channel first");
-DEFINE_bool(pretty, false,
-            "If true, pretty print the messages on multiple lines");
-DEFINE_bool(
-    pretty_max, false,
+ABSL_FLAG(int64_t, max_vector_size, 100,
+          "If positive, vectors longer than this will not be printed");
+ABSL_FLAG(bool, json, false, "If true, print fully valid JSON");
+ABSL_FLAG(bool, fetch, false,
+          "If true, fetch the current message on the channel first");
+ABSL_FLAG(bool, pretty, false,
+          "If true, pretty print the messages on multiple lines");
+ABSL_FLAG(
+    bool, pretty_max, false,
     "If true, expand every field to its own line (expands more than -pretty)");
-DEFINE_bool(print_timestamps, true, "If true, timestamps are printed.");
-DEFINE_uint64(count, 0,
-              "If >0, aos_dump will exit after printing this many messages.");
-DEFINE_int32(rate_limit, 0,
-             "The minimum amount of time to wait in milliseconds before "
-             "sending another message");
-DEFINE_int32(timeout, -1,
-             "The max time in milliseconds to wait for messages before "
-             "exiting.  -1 means forever, 0 means don't wait.");
-DEFINE_bool(hex, false,
-            "Are integers in the messages printed in hex notation.");
+ABSL_FLAG(bool, print_timestamps, true, "If true, timestamps are printed.");
+ABSL_FLAG(uint64_t, count, 0,
+          "If >0, aos_dump will exit after printing this many messages.");
+ABSL_FLAG(int32_t, rate_limit, 0,
+          "The minimum amount of time to wait in milliseconds before "
+          "sending another message");
+ABSL_FLAG(int32_t, timeout, -1,
+          "The max time in milliseconds to wait for messages before "
+          "exiting.  -1 means forever, 0 means don't wait.");
+ABSL_FLAG(bool, hex, false,
+          "Are integers in the messages printed in hex notation.");
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Prints messages from arbitrary channels as they are received given a "
       "configuration file describing the channels to listen on.\nTypical "
       "Usage: aos_dump [--config path_to_config.json] channel_name "
@@ -56,18 +57,19 @@
 
   aos::Printer printer(
       {
-          .pretty = FLAGS_pretty,
-          .max_vector_size = static_cast<size_t>(FLAGS_max_vector_size),
-          .pretty_max = FLAGS_pretty_max,
-          .print_timestamps = FLAGS_print_timestamps,
-          .json = FLAGS_json,
+          .pretty = absl::GetFlag(FLAGS_pretty),
+          .max_vector_size =
+              static_cast<size_t>(absl::GetFlag(FLAGS_max_vector_size)),
+          .pretty_max = absl::GetFlag(FLAGS_pretty_max),
+          .print_timestamps = absl::GetFlag(FLAGS_print_timestamps),
+          .json = absl::GetFlag(FLAGS_json),
           .distributed_clock = false,
-          .hex = FLAGS_hex,
+          .hex = absl::GetFlag(FLAGS_hex),
       },
       /*flush*/ true);
 
   for (const aos::Channel *channel : cli_info.found_channels) {
-    if (FLAGS_fetch) {
+    if (absl::GetFlag(FLAGS_fetch)) {
       const std::unique_ptr<aos::RawFetcher> fetcher =
           cli_info.event_loop->MakeRawFetcher(channel);
       if (fetcher->Fetch()) {
@@ -75,11 +77,12 @@
       }
     }
 
-    if (FLAGS_count > 0 && printer.message_count() >= FLAGS_count) {
+    if (absl::GetFlag(FLAGS_count) > 0 &&
+        printer.message_count() >= absl::GetFlag(FLAGS_count)) {
       return 0;
     }
 
-    if (FLAGS_timeout == 0) {
+    if (absl::GetFlag(FLAGS_timeout) == 0) {
       continue;
     }
 
@@ -87,33 +90,36 @@
         channel, [channel, &printer, &cli_info, &next_send_time](
                      const aos::Context &context, const void * /*message*/) {
           if (context.monotonic_event_time > next_send_time) {
-            if (FLAGS_count > 0 && printer.message_count() >= FLAGS_count) {
+            if (absl::GetFlag(FLAGS_count) > 0 &&
+                printer.message_count() >= absl::GetFlag(FLAGS_count)) {
               return;
             }
 
             printer.PrintMessage(channel, context);
-            next_send_time = context.monotonic_event_time +
-                             std::chrono::milliseconds(FLAGS_rate_limit);
-            if (FLAGS_count > 0 && printer.message_count() >= FLAGS_count) {
+            next_send_time =
+                context.monotonic_event_time +
+                std::chrono::milliseconds(absl::GetFlag(FLAGS_rate_limit));
+            if (absl::GetFlag(FLAGS_count) > 0 &&
+                printer.message_count() >= absl::GetFlag(FLAGS_count)) {
               cli_info.event_loop->Exit();
             }
           }
         });
   }
 
-  if (FLAGS_timeout == 0) {
+  if (absl::GetFlag(FLAGS_timeout) == 0) {
     return 0;
   }
 
-  if (FLAGS_timeout > 0) {
+  if (absl::GetFlag(FLAGS_timeout) > 0) {
     aos::TimerHandler *handle = cli_info.event_loop->AddTimer(
         [event_loop = &cli_info.event_loop.value()]() { event_loop->Exit(); });
 
-    cli_info.event_loop->OnRun(
-        [handle, event_loop = &cli_info.event_loop.value()]() {
-          handle->Schedule(event_loop->monotonic_now() +
-                           std::chrono::milliseconds(FLAGS_timeout));
-        });
+    cli_info.event_loop->OnRun([handle,
+                                event_loop = &cli_info.event_loop.value()]() {
+      handle->Schedule(event_loop->monotonic_now() +
+                       std::chrono::milliseconds(absl::GetFlag(FLAGS_timeout)));
+    });
   }
 
   cli_info.event_loop->Run();
diff --git a/aos/aos_graph_channels.cc b/aos/aos_graph_channels.cc
index 1a89223..c03dc36 100644
--- a/aos/aos_graph_channels.cc
+++ b/aos/aos_graph_channels.cc
@@ -1,9 +1,10 @@
 #include <iomanip>
 #include <iostream>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_split.h"
-#include "gflags/gflags.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
@@ -11,7 +12,7 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/time/time.h"
 
-DEFINE_string(skip, "", "Applications to skip, seperated by ;");
+ABSL_FLAG(std::string, skip, "", "Applications to skip, seperated by ;");
 
 struct ChannelState {
   const aos::Channel *channel = nullptr;
@@ -34,7 +35,7 @@
 };
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Usage: \n"
       "  aos_graph_channels [args] logfile1 logfile2 ...\n"
       "\n"
@@ -49,7 +50,8 @@
     LOG(FATAL) << "Expected at least 1 logfile as an argument.";
   }
 
-  const std::vector<std::string> skip_list = absl::StrSplit(FLAGS_skip, ";");
+  const std::vector<std::string> skip_list =
+      absl::StrSplit(absl::GetFlag(FLAGS_skip), ";");
   aos::logger::LogReader reader(
       aos::logger::SortParts(aos::logger::FindLogs(argc, argv)));
 
diff --git a/aos/aos_graph_nodes.cc b/aos/aos_graph_nodes.cc
index 4ed9866..87b8671 100644
--- a/aos/aos_graph_nodes.cc
+++ b/aos/aos_graph_nodes.cc
@@ -1,22 +1,24 @@
 #include <iostream>
 #include <map>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_bool(all, false,
-            "If true, print out the channels for all nodes in the config file, "
-            "not just the channels which are visible on this node.");
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
-DEFINE_bool(short_types, true,
-            "Whether to show a shortened version of the type name");
+ABSL_FLAG(bool, all, false,
+          "If true, print out the channels for all nodes in the config file, "
+          "not just the channels which are visible on this node.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
+ABSL_FLAG(bool, short_types, true,
+          "Whether to show a shortened version of the type name");
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "\nCreates graph of nodes and message channels based on the robot config "
       "file.  \n\n"
       "To save to file, run as: \n"
@@ -38,13 +40,12 @@
   std::map<std::string, std::string> color_map;
 
   if (argc > 1) {
-    LOG(ERROR) << "ERROR: Got unexpected arguments\n\n";
-    gflags::ShowUsageWithFlagsRestrict(argv[0], "aos/aos_graph_nodes.cc");
+    LOG(ERROR) << "ERROR: Got unexpected arguments";
     return -1;
   }
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   const aos::Configuration *config_msg = &config.message();
   aos::ShmEventLoop event_loop(config_msg);
@@ -57,10 +58,10 @@
 
   for (const aos::Channel *channel : *config_msg->channels()) {
     VLOG(1) << "Found channel " << channel->type()->string_view();
-    if (FLAGS_all || aos::configuration::ChannelIsReadableOnNode(
-                         channel, event_loop.node())) {
+    if (absl::GetFlag(FLAGS_all) || aos::configuration::ChannelIsReadableOnNode(
+                                        channel, event_loop.node())) {
       flatbuffers::string_view type_name = channel->type()->string_view();
-      if (FLAGS_short_types) {
+      if (absl::GetFlag(FLAGS_short_types)) {
         // Strip down to just the top level of the message type
         type_name = channel->type()->string_view().substr(
             channel->type()->string_view().rfind(".") + 1, std::string::npos);
diff --git a/aos/aos_jitter.cc b/aos/aos_jitter.cc
index 5f23935..82a79ea 100644
--- a/aos/aos_jitter.cc
+++ b/aos/aos_jitter.cc
@@ -3,7 +3,8 @@
 #include <iomanip>
 #include <iostream>  // IWYU pragma: keep
 
-#include "gflags/gflags.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 
 #include "aos/aos_cli_utils.h"
 #include "aos/configuration.h"
@@ -12,15 +13,15 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/realtime.h"
 
-DEFINE_int32(priority, -1, "If set, the RT priority to run at.");
-DEFINE_double(max_jitter, 0.01,
-              "The max time in milliseconds between messages before marking it "
-              "as too late.");
-DEFINE_bool(print_jitter, true,
-            "If true, print jitter events.  These will impact RT performance.");
-DECLARE_bool(enable_ftrace);
-DEFINE_bool(print_latency_stats, false,
-            "If true, print latency stats.  These will impact RT performance.");
+ABSL_FLAG(int32_t, priority, -1, "If set, the RT priority to run at.");
+ABSL_FLAG(double, max_jitter, 0.01,
+          "The max time in milliseconds between messages before marking it "
+          "as too late.");
+ABSL_FLAG(bool, print_jitter, true,
+          "If true, print jitter events.  These will impact RT performance.");
+ABSL_DECLARE_FLAG(bool, enable_ftrace);
+ABSL_FLAG(bool, print_latency_stats, false,
+          "If true, print latency stats.  These will impact RT performance.");
 
 namespace aos {
 
@@ -37,7 +38,7 @@
           HandleMessage(context, message);
         });
 
-    if (FLAGS_print_latency_stats) {
+    if (absl::GetFlag(FLAGS_print_latency_stats)) {
       timer_handle_ = event_loop->AddTimer([this]() { PrintLatencyStats(); });
       timer_handle_->set_name("jitter");
       event_loop->OnRun([this, event_loop]() {
@@ -54,8 +55,9 @@
                              .count());
       if (context.monotonic_event_time >
           last_time_ + std::chrono::duration_cast<std::chrono::nanoseconds>(
-                           std::chrono::duration<double>(FLAGS_max_jitter))) {
-        if (FLAGS_enable_ftrace) {
+                           std::chrono::duration<double>(
+                               absl::GetFlag(FLAGS_max_jitter)))) {
+        if (absl::GetFlag(FLAGS_enable_ftrace)) {
           ftrace_->FormatMessage(
               "Got high latency event on %s -> %.9f between messages",
               channel_name_.c_str(),
@@ -65,7 +67,7 @@
           ftrace_->TurnOffOrDie();
         }
 
-        if (FLAGS_print_jitter) {
+        if (absl::GetFlag(FLAGS_print_jitter)) {
           // Printing isn't realtime, but if someone wants to run as RT, they
           // should know this.  Bypass the warning.
           ScopedNotRealtime nrt;
@@ -138,8 +140,9 @@
         &ftrace, &(cli_info.event_loop.value()), channel));
   }
 
-  if (FLAGS_priority > 0) {
-    cli_info.event_loop->SetRuntimeRealtimePriority(FLAGS_priority);
+  if (absl::GetFlag(FLAGS_priority) > 0) {
+    cli_info.event_loop->SetRuntimeRealtimePriority(
+        absl::GetFlag(FLAGS_priority));
   }
 
   cli_info.event_loop->Run();
diff --git a/aos/aos_send.cc b/aos/aos_send.cc
index 8533f47..d95768f 100644
--- a/aos/aos_send.cc
+++ b/aos/aos_send.cc
@@ -3,18 +3,20 @@
 
 #include <iostream>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/log.h"
 
 #include "aos/aos_cli_utils.h"
 #include "aos/configuration.h"
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_double(rate, -1, "Rate at which to send the message (-1 to send once).");
+ABSL_FLAG(double, rate, -1,
+          "Rate at which to send the message (-1 to send once).");
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Sends messages on arbitrary channels.\n"
       "Typical Usage: aos_send [--config path_to_config.json]"
       " channel_name message_type '{\"foo\": \"bar\"}'\n"
@@ -67,7 +69,7 @@
 
   fbb.Finish(msg_offset);
 
-  if (FLAGS_rate < 0) {
+  if (absl::GetFlag(FLAGS_rate) < 0) {
     sender->CheckOk(sender->Send(fbb.GetSize()));
   } else {
     cli_info.event_loop
@@ -76,7 +78,8 @@
         })
         ->Schedule(cli_info.event_loop->monotonic_now(),
                    std::chrono::duration_cast<std::chrono::nanoseconds>(
-                       std::chrono::duration<double>(1.0 / FLAGS_rate)));
+                       std::chrono::duration<double>(
+                           1.0 / absl::GetFlag(FLAGS_rate))));
     cli_info.event_loop->Run();
   }
 
diff --git a/aos/condition.cc b/aos/condition.cc
index f7860be..b293cb4 100644
--- a/aos/condition.cc
+++ b/aos/condition.cc
@@ -4,7 +4,8 @@
 #include <cinttypes>
 #include <ctime>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/type_traits/type_traits.h"
diff --git a/aos/config_flattener.cc b/aos/config_flattener.cc
index b623426..2685076 100644
--- a/aos/config_flattener.cc
+++ b/aos/config_flattener.cc
@@ -1,21 +1,21 @@
 #include <string>
 #include <vector>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 #include "aos/util/file.h"
 
-DEFINE_string(full_output, "",
-              "If provided, the path to write the full json configuration to.");
-DEFINE_string(
-    stripped_output, "",
-    "If provided, the path to write the stripped json configuration to.");
-DEFINE_string(
-    binary_output, "",
+ABSL_FLAG(std::string, full_output, "",
+          "If provided, the path to write the full json configuration to.");
+ABSL_FLAG(std::string, stripped_output, "",
+          "If provided, the path to write the stripped json configuration to.");
+ABSL_FLAG(
+    std::string, binary_output, "",
     "If provided, the path to write the binary flatbuffer configuration to.");
 
 namespace aos {
@@ -67,16 +67,18 @@
   // TODO(austin): Figure out how to squash the schemas onto 1 line so it is
   // easier to read?
   VLOG(1) << "Flattened config is " << merged_config_json;
-  if (!FLAGS_full_output.empty()) {
-    util::WriteStringToFileOrDie(FLAGS_full_output, merged_config_json);
+  if (!absl::GetFlag(FLAGS_full_output).empty()) {
+    util::WriteStringToFileOrDie(absl::GetFlag(FLAGS_full_output),
+                                 merged_config_json);
   }
-  if (!FLAGS_stripped_output.empty()) {
+  if (!absl::GetFlag(FLAGS_stripped_output).empty()) {
     util::WriteStringToFileOrDie(
-        FLAGS_stripped_output,
+        absl::GetFlag(FLAGS_stripped_output),
         FlatbufferToJson(&config.message(), {.multi_line = true}));
   }
-  if (!FLAGS_binary_output.empty()) {
-    aos::WriteFlatbufferToFile(FLAGS_binary_output, merged_config);
+  if (!absl::GetFlag(FLAGS_binary_output).empty()) {
+    aos::WriteFlatbufferToFile(absl::GetFlag(FLAGS_binary_output),
+                               merged_config);
   }
   return 0;
 }
diff --git a/aos/configuration.cc b/aos/configuration.cc
index 3b52e0c..fd446c2 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -16,11 +16,12 @@
 
 #include "absl/container/btree_map.h"
 #include "absl/container/btree_set.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_join.h"
 #include "absl/strings/str_split.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration_generated.h"
 #include "aos/flatbuffer_merge.h"
@@ -30,11 +31,11 @@
 #include "aos/unique_malloc_ptr.h"
 #include "aos/util/file.h"
 
-DEFINE_uint32(max_queue_size_override, 0,
-              "If nonzero, this is the max number of elements in a queue to "
-              "enforce.  If zero, use the number that the processor that this "
-              "application is compiled for can support.  This is mostly useful "
-              "for config validation, and shouldn't be touched.");
+ABSL_FLAG(uint32_t, max_queue_size_override, 0,
+          "If nonzero, this is the max number of elements in a queue to "
+          "enforce.  If zero, use the number that the processor that this "
+          "application is compiled for can support.  This is mostly useful "
+          "for config validation, and shouldn't be touched.");
 
 namespace aos {
 namespace configuration {
@@ -1007,8 +1008,8 @@
       }
 
       CHECK_LT(QueueSize(&config.message(), c) + QueueScratchBufferSize(c),
-               FLAGS_max_queue_size_override != 0
-                   ? FLAGS_max_queue_size_override
+               absl::GetFlag(FLAGS_max_queue_size_override) != 0
+                   ? absl::GetFlag(FLAGS_max_queue_size_override)
                    : std::numeric_limits<
                          ipc_lib::QueueIndex::PackedIndexType>::max())
           << ": More messages/second configured than the queue can hold on "
@@ -1535,9 +1536,10 @@
 }
 
 const Node *GetMyNode(const Configuration *config) {
-  const std::string hostname = (FLAGS_override_hostname.size() > 0)
-                                   ? FLAGS_override_hostname
-                                   : network::GetHostname();
+  const std::string hostname =
+      (absl::GetFlag(FLAGS_override_hostname).size() > 0)
+          ? absl::GetFlag(FLAGS_override_hostname)
+          : network::GetHostname();
   const Node *node = GetNodeFromHostname(config, hostname);
   if (node != nullptr) return node;
 
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index d980dad..556fea9 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -1,8 +1,9 @@
 #include "aos/configuration.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/strip.h"
 #include "flatbuffers/reflection.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/aos/containers/BUILD b/aos/containers/BUILD
index c0b365c..8da9218 100644
--- a/aos/containers/BUILD
+++ b/aos/containers/BUILD
@@ -17,7 +17,8 @@
     deps = [
         ":ring_buffer",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -61,6 +62,7 @@
         ":inlined_vector",
         "//aos:realtime",
         "//aos/testing:googletest",
+        "@com_google_absl//absl/flags:reflection",
     ],
 )
 
@@ -117,7 +119,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/containers/inlined_vector_test.cc b/aos/containers/inlined_vector_test.cc
index b8aab6b..d2d9af6 100644
--- a/aos/containers/inlined_vector_test.cc
+++ b/aos/containers/inlined_vector_test.cc
@@ -1,19 +1,21 @@
 #include "aos/containers/inlined_vector.h"
 
-#include "gflags/gflags.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
 #include "gtest/gtest.h"
 
 #include "aos/realtime.h"
 
-DECLARE_bool(die_on_malloc);
+ABSL_DECLARE_FLAG(bool, die_on_malloc);
 
 namespace aos::testing {
 
 // Checks that we don't malloc until/unless we need to increase the size of the
 // vector.
 TEST(SizedArrayTest, NoUnnecessaryMalloc) {
-  gflags::FlagSaver flag_saver;
-  FLAGS_die_on_malloc = true;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_die_on_malloc, true);
   RegisterMallocHook();
   InlinedVector<int, 5> a;
   {
diff --git a/aos/containers/resizeable_buffer.h b/aos/containers/resizeable_buffer.h
index 1af888d..db4a102 100644
--- a/aos/containers/resizeable_buffer.h
+++ b/aos/containers/resizeable_buffer.h
@@ -8,7 +8,8 @@
 #include <cstdlib>
 #include <memory>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos {
 
diff --git a/aos/containers/ring_buffer_test.cc b/aos/containers/ring_buffer_test.cc
index b7b0f17..ed388f3 100644
--- a/aos/containers/ring_buffer_test.cc
+++ b/aos/containers/ring_buffer_test.cc
@@ -3,7 +3,8 @@
 #include <memory>
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 namespace aos::testing {
diff --git a/aos/containers/sized_array_test.cc b/aos/containers/sized_array_test.cc
index 5fc4b38..8813370 100644
--- a/aos/containers/sized_array_test.cc
+++ b/aos/containers/sized_array_test.cc
@@ -174,7 +174,7 @@
   // Verify that we didn't reallocate
   EXPECT_EQ(pre_front, a.data());
 
-  EXPECT_DEATH(a.emplace_back(5), "Aborted at");
+  EXPECT_DEATH(a.emplace_back(5), "SIGILL received at");
 }
 
 // Tests inserting at various positions in the array.
diff --git a/aos/dump_rtprio.cc b/aos/dump_rtprio.cc
index 74ade74..4ea540d 100644
--- a/aos/dump_rtprio.cc
+++ b/aos/dump_rtprio.cc
@@ -19,14 +19,17 @@
 #include <set>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/time/time.h"
 #include "aos/util/top.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
 
 namespace {
 
@@ -253,7 +256,7 @@
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   event_loop.SkipTimingReport();
diff --git a/aos/events/BUILD b/aos/events/BUILD
index c61b3e5..c49655a 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -65,7 +65,8 @@
     visibility = ["//visibility:public"],
     deps = [
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -76,7 +77,8 @@
     deps = [
         ":epoll",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -196,7 +198,8 @@
         ":simulated_event_loop",
         "//aos/testing:googletest",
         "//aos/testing:path",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -214,7 +217,8 @@
         ":ping_fbs",
         ":pong_fbs",
         "//aos:json_to_flatbuffer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -231,7 +235,8 @@
         "//aos:configuration",
         "//aos:init",
         "//aos:json_to_flatbuffer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -379,7 +384,8 @@
         ":event_loop",
         ":ping_fbs",
         ":pong_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -398,7 +404,8 @@
         "//aos:configuration",
         "//aos:init",
         "//aos:json_to_flatbuffer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -430,7 +437,8 @@
         ":event_loop_fbs",
         "//aos:configuration",
         "//aos/util:error_counter",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -535,7 +543,8 @@
     deps = [
         "//aos:configuration_fbs",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -664,7 +673,8 @@
         ":simulated_event_loop",
         "//aos/network:testing_time_converter",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -707,7 +717,8 @@
     deps = [
         "//aos/events:shm_event_loop",
         "//third_party:gstreamer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -726,7 +737,8 @@
         "//aos/testing:googletest",
         "//aos/testing:path",
         "//third_party:gstreamer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/events/aos_timing_report_streamer.cc b/aos/events/aos_timing_report_streamer.cc
index 58b44e6..fdf468d 100644
--- a/aos/events/aos_timing_report_streamer.cc
+++ b/aos/events/aos_timing_report_streamer.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -6,27 +6,30 @@
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_string(config, "aos_config.json", "The path to the config to use.");
-DEFINE_string(application, "",
-              "Application filter to use. Empty for no filter.");
-DEFINE_bool(stream, true, "Stream out all the timing reports that we receive.");
-DEFINE_bool(accumulate, true,
-            "Display accumulation of all timing reports that we've seen when "
-            "the process is terminated.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "The path to the config to use.");
+ABSL_FLAG(std::string, application, "",
+          "Application filter to use. Empty for no filter.");
+ABSL_FLAG(bool, stream, true,
+          "Stream out all the timing reports that we receive.");
+ABSL_FLAG(bool, accumulate, true,
+          "Display accumulation of all timing reports that we've seen when "
+          "the process is terminated.");
 
 namespace aos {
 int Main() {
   aos::FlatbufferVector<aos::Configuration> config(
-      aos::configuration::ReadConfig(FLAGS_config));
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config)));
   ShmEventLoop event_loop(&config.message());
   TimingReportDump dumper(&event_loop,
-                          FLAGS_accumulate
+                          absl::GetFlag(FLAGS_accumulate)
                               ? TimingReportDump::AccumulateStatistics::kYes
                               : TimingReportDump::AccumulateStatistics::kNo,
-                          FLAGS_stream ? TimingReportDump::StreamResults::kYes
-                                       : TimingReportDump::StreamResults::kNo);
-  if (!FLAGS_application.empty()) {
-    dumper.ApplicationFilter(FLAGS_application);
+                          absl::GetFlag(FLAGS_stream)
+                              ? TimingReportDump::StreamResults::kYes
+                              : TimingReportDump::StreamResults::kNo);
+  if (!absl::GetFlag(FLAGS_application).empty()) {
+    dumper.ApplicationFilter(absl::GetFlag(FLAGS_application));
   }
   event_loop.Run();
   return EXIT_SUCCESS;
diff --git a/aos/events/epoll.cc b/aos/events/epoll.cc
index d5f5162..2a266d6 100644
--- a/aos/events/epoll.cc
+++ b/aos/events/epoll.cc
@@ -17,7 +17,8 @@
 #include <utility>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 
diff --git a/aos/events/epoll_test.cc b/aos/events/epoll_test.cc
index e1be563..83139f0 100644
--- a/aos/events/epoll_test.cc
+++ b/aos/events/epoll_test.cc
@@ -3,7 +3,8 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 namespace aos::internal::testing {
diff --git a/aos/events/event_loop.cc b/aos/events/event_loop.cc
index 424971d..212bc45 100644
--- a/aos/events/event_loop.cc
+++ b/aos/events/event_loop.cc
@@ -1,15 +1,17 @@
 #include "aos/events/event_loop.h"
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/configuration_generated.h"
 #include "aos/logging/implementations.h"
 #include "aos/realtime.h"
 
-DEFINE_bool(timing_reports, true, "Publish timing reports.");
-DEFINE_int32(timing_report_ms, 1000,
-             "Period in milliseconds to publish timing reports at.");
+ABSL_FLAG(bool, timing_reports, true, "Publish timing reports.");
+ABSL_FLAG(int32_t, timing_report_ms, 1000,
+          "Period in milliseconds to publish timing reports at.");
 
 namespace aos {
 namespace {
@@ -157,7 +159,9 @@
 EventLoop::EventLoop(const Configuration *configuration)
     : version_string_(default_version_string_),
       timing_report_(flatbuffers::DetachedBuffer()),
-      configuration_(configuration) {}
+      configuration_(configuration) {
+  CHECK(configuration != nullptr);
+}
 
 EventLoop::~EventLoop() {
   if (!senders_.empty()) {
@@ -545,7 +549,7 @@
 }
 
 void EventLoop::MaybeScheduleTimingReports() {
-  if (FLAGS_timing_reports && !skip_timing_report_) {
+  if (absl::GetFlag(FLAGS_timing_reports) && !skip_timing_report_) {
     CHECK(!timing_report_sender_) << ": Timing reports already scheduled.";
     // Make a raw sender for the report.
     const Channel *channel = configuration::GetChannel(
@@ -578,8 +582,9 @@
     timing_reports_timer->set_name("timing_reports");
     OnRun([this, timing_reports_timer]() {
       timing_reports_timer->Schedule(
-          monotonic_now() + std::chrono::milliseconds(FLAGS_timing_report_ms),
-          std::chrono::milliseconds(FLAGS_timing_report_ms));
+          monotonic_now() +
+              std::chrono::milliseconds(absl::GetFlag(FLAGS_timing_report_ms)),
+          std::chrono::milliseconds(absl::GetFlag(FLAGS_timing_report_ms)));
     });
 
     UpdateTimingReport();
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index c8cf487..891d5c8 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -8,8 +8,10 @@
 #include <string_view>
 
 #include "absl/container/btree_set.h"
+#include "absl/flags/declare.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 #include "tl/expected.hpp"
 
 #include "aos/configuration.h"
@@ -30,8 +32,8 @@
 #include "aos/util/status.h"
 #include "aos/uuid.h"
 
-DECLARE_bool(timing_reports);
-DECLARE_int32(timing_report_ms);
+ABSL_DECLARE_FLAG(bool, timing_reports);
+ABSL_DECLARE_FLAG(int32_t, timing_report_ms);
 
 namespace aos {
 
diff --git a/aos/events/event_loop_event.h b/aos/events/event_loop_event.h
index 4d1ff07..6e823f0 100644
--- a/aos/events/event_loop_event.h
+++ b/aos/events/event_loop_event.h
@@ -5,7 +5,8 @@
 
 #include <chrono>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 
diff --git a/aos/events/event_loop_param_test.cc b/aos/events/event_loop_param_test.cc
index 4975540..1e6b3a4 100644
--- a/aos/events/event_loop_param_test.cc
+++ b/aos/events/event_loop_param_test.cc
@@ -5,7 +5,10 @@
 #include <unordered_map>
 #include <unordered_set>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -1458,7 +1461,8 @@
 // Verify that timer intervals and duration function properly.
 TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
   // Force a slower rate so we are guaranteed to have reports for our timer.
-  FLAGS_timing_report_ms = 2000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 2000);
 
   const int kCount = 5;
 
@@ -1586,8 +1590,8 @@
 // Test that setting a default version string results in it getting populated
 // correctly.
 TEST_P(AbstractEventLoopTest, DefaultVersionStringInTimingReport) {
-  gflags::FlagSaver flag_saver;
-  FLAGS_timing_report_ms = 1000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
 
   EventLoop::SetDefaultVersionString("default_version_string");
 
@@ -1625,8 +1629,8 @@
 // Test that overriding the default version string results in it getting
 // populated correctly.
 TEST_P(AbstractEventLoopTest, OverrideDersionStringInTimingReport) {
-  gflags::FlagSaver flag_saver;
-  FLAGS_timing_report_ms = 1000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
 
   EventLoop::SetDefaultVersionString("default_version_string");
 
@@ -2101,7 +2105,8 @@
 TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
   // Force a slower rate so we are guaranteed to have reports for our phased
   // loop.
-  FLAGS_timing_report_ms = 2000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 2000);
 
   const chrono::milliseconds kOffset = chrono::milliseconds(400);
   const int kCount = 5;
@@ -2237,7 +2242,8 @@
 TEST_P(AbstractEventLoopTest, PhasedLoopChangingOffsetTest) {
   // Force a slower rate so we are guaranteed to have reports for our phased
   // loop.
-  FLAGS_timing_report_ms = 2000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 2000);
 
   const chrono::milliseconds kOffset = chrono::milliseconds(400);
   const chrono::milliseconds kInterval = chrono::milliseconds(1000);
@@ -2624,7 +2630,8 @@
 
 // Tests that senders count correctly in the timing report.
 TEST_P(AbstractEventLoopTest, SenderTimingReport) {
-  FLAGS_timing_report_ms = 1000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
   auto loop1 = MakePrimary();
 
   auto loop2 = Make("watcher_loop");
@@ -2745,8 +2752,8 @@
 // Tests that the RawSender::Send(void*, size_t) overload tracks things properly
 // in its timing report.
 TEST_P(AbstractEventLoopTest, CopySenderTimingReport) {
-  gflags::FlagSaver flag_saver;
-  FLAGS_timing_report_ms = 1000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
   auto loop1 = Make();
   auto loop2 = MakePrimary();
 
@@ -2801,8 +2808,8 @@
 
 // Tests that the RawSender::Send(SharedSpan) overload works.
 TEST_P(AbstractEventLoopTest, SharedSenderTimingReport) {
-  gflags::FlagSaver flag_saver;
-  FLAGS_timing_report_ms = 1000;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
   auto loop1 = Make();
   auto loop2 = MakePrimary();
 
@@ -2863,7 +2870,7 @@
 
 // Tests that senders count correctly in the timing report.
 TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
-  FLAGS_timing_report_ms = 1000;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
   auto loop1 = MakePrimary();
   loop1->MakeWatcher("/test", [](const TestMessage &) {});
 
@@ -2930,7 +2937,7 @@
 
 // Tests that fetchers count correctly in the timing report.
 TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
-  FLAGS_timing_report_ms = 1000;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
   auto loop1 = MakePrimary();
   auto loop2 = Make("sender_loop");
 
diff --git a/aos/events/event_loop_runtime_test.cc b/aos/events/event_loop_runtime_test.cc
index 6bd4c70..a1c20eb 100644
--- a/aos/events/event_loop_runtime_test.cc
+++ b/aos/events/event_loop_runtime_test.cc
@@ -1,4 +1,5 @@
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/event_loop_runtime_test_lib_rs_cxxgen.h"
diff --git a/aos/events/event_loop_tmpl.h b/aos/events/event_loop_tmpl.h
index 25aa36c..a112b36 100644
--- a/aos/events/event_loop_tmpl.h
+++ b/aos/events/event_loop_tmpl.h
@@ -5,7 +5,8 @@
 #include <cstdint>
 #include <type_traits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 
diff --git a/aos/events/event_scheduler.h b/aos/events/event_scheduler.h
index 68fcf28..a9226df 100644
--- a/aos/events/event_scheduler.h
+++ b/aos/events/event_scheduler.h
@@ -8,7 +8,8 @@
 #include <utility>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/epoll.h"
 #include "aos/events/event_loop.h"
diff --git a/aos/events/glib_main_loop.cc b/aos/events/glib_main_loop.cc
index bee8a81..b3bd2b3 100644
--- a/aos/events/glib_main_loop.cc
+++ b/aos/events/glib_main_loop.cc
@@ -1,6 +1,7 @@
 #include "aos/events/glib_main_loop.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos {
 namespace {
diff --git a/aos/events/glib_main_loop.h b/aos/events/glib_main_loop.h
index 080bc57..782043b 100644
--- a/aos/events/glib_main_loop.h
+++ b/aos/events/glib_main_loop.h
@@ -247,7 +247,7 @@
       signal_handler_id_(g_signal_connect(
           instance, detailed_signal,
           G_CALLBACK(&GlibSignalCallback::InvokeSignal), user_data())) {
-  CHECK_GT(signal_handler_id_, 0);
+  CHECK_GT(signal_handler_id_, 0u);
   VLOG(1) << this << " connected glib signal with " << user_data() << " as "
           << signal_handler_id_ << " on " << instance << ": "
           << detailed_signal;
diff --git a/aos/events/glib_main_loop_test.cc b/aos/events/glib_main_loop_test.cc
index 6fced6d..cd5c109 100644
--- a/aos/events/glib_main_loop_test.cc
+++ b/aos/events/glib_main_loop_test.cc
@@ -2,8 +2,9 @@
 
 #include <thread>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "glib-2.0/glib.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
diff --git a/aos/events/logging/BUILD b/aos/events/logging/BUILD
index 2bb87b6..7df8823 100644
--- a/aos/events/logging/BUILD
+++ b/aos/events/logging/BUILD
@@ -81,9 +81,10 @@
         "//aos:init",
         "//aos:json_to_flatbuffer",
         "//aos/events:shm_event_loop",
-        "@com_github_gflags_gflags//:gflags",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -93,7 +94,8 @@
     hdrs = ["file_operations.h"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -119,7 +121,9 @@
         ":file_operations",
         "//aos/time",
         "//aos/util:file",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/types:span",
     ],
@@ -135,7 +139,8 @@
         "//aos/containers:resizeable_buffer",
         "//aos/testing:googletest",
         "//aos/testing:tmpdir",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -195,9 +200,10 @@
         "//aos/events:event_loop",
         "//aos/network:remote_message_fbs",
         "//aos/util:file",
-        "@com_github_gflags_gflags//:gflags",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ] + select({
         "//tools:cpu_k8": [
@@ -220,8 +226,9 @@
     deps = [
         ":logfile_utils",
         "//aos:init",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -265,7 +272,8 @@
         "//aos/containers:resizeable_buffer",
         "//aos/time",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -281,7 +289,8 @@
         ":buffer_encoder",
         ":buffer_encoder_param_test",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -302,7 +311,8 @@
         "//aos/containers:resizeable_buffer",
         "//aos/util:crc32",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
         "@snappy",
     ],
@@ -319,7 +329,8 @@
         ":buffer_encoder_param_test",
         ":snappy_encoder",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -340,7 +351,9 @@
         "//aos/containers:resizeable_buffer",
         "//third_party:lzma",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -363,7 +376,8 @@
         "//aos/containers:resizeable_buffer",
         "@aws_sdk//:core",
         "@aws_sdk//:s3",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/types:span",
     ],
@@ -380,7 +394,9 @@
         ":buffer_encoder_param_test",
         ":lzma_encoder",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -399,7 +415,8 @@
         ":logger_fbs",
         "//aos/testing:googletest",
         "//aos/testing:random_seed",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -418,7 +435,8 @@
         "//aos/containers:error_list",
         "//aos/containers:sized_array",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -546,8 +564,9 @@
         "//aos:json_to_flatbuffer",
         "//aos:sha256",
         "//aos/events:simulated_event_loop",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -564,8 +583,9 @@
         "//aos:configuration",
         "//aos/events:simulated_event_loop",
         "//aos/network:multinode_timestamp_filter",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -583,8 +603,9 @@
         "//aos:init",
         "//aos/events:simulated_event_loop",
         "//aos/network:multinode_timestamp_filter",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -601,8 +622,9 @@
         "//aos:init",
         "//aos/events:simulated_event_loop",
         "//aos/network:multinode_timestamp_filter",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -618,8 +640,9 @@
         "//aos:init",
         "//aos:json_to_flatbuffer",
         "//aos/util:file",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -636,8 +659,9 @@
         "//aos:json_to_flatbuffer",
         "//aos/events:simulated_event_loop",
         "//aos/time",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -660,8 +684,9 @@
         "//aos:init",
         "//aos/events:shm_event_loop",
         "//aos/logging:log_namer",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -1009,8 +1034,9 @@
         "//aos:init",
         "//aos:json_to_flatbuffer",
         "//aos/events/logging:log_reader",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -1025,7 +1051,8 @@
         "//aos:init",
         "//aos/containers:resizeable_buffer",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/events/logging/boot_timestamp.h b/aos/events/logging/boot_timestamp.h
index dc5967c..0440ea7 100644
--- a/aos/events/logging/boot_timestamp.h
+++ b/aos/events/logging/boot_timestamp.h
@@ -9,7 +9,8 @@
 #include <iostream>
 #include <limits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 
diff --git a/aos/events/logging/buffer_encoder.cc b/aos/events/logging/buffer_encoder.cc
index b352d5d..b6350a5 100644
--- a/aos/events/logging/buffer_encoder.cc
+++ b/aos/events/logging/buffer_encoder.cc
@@ -4,7 +4,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/flatbuffers.h"
 
diff --git a/aos/events/logging/buffer_encoder.h b/aos/events/logging/buffer_encoder.h
index db09d32..5235d7b 100644
--- a/aos/events/logging/buffer_encoder.h
+++ b/aos/events/logging/buffer_encoder.h
@@ -1,9 +1,10 @@
 #ifndef AOS_EVENTS_LOGGING_BUFFER_ENCODER_H_
 #define AOS_EVENTS_LOGGING_BUFFER_ENCODER_H_
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 
 #include "aos/containers/resizeable_buffer.h"
 #include "aos/events/logging/logger_generated.h"
diff --git a/aos/events/logging/buffer_encoder_param_test.h b/aos/events/logging/buffer_encoder_param_test.h
index 8b6648d..7a05e98 100644
--- a/aos/events/logging/buffer_encoder_param_test.h
+++ b/aos/events/logging/buffer_encoder_param_test.h
@@ -6,7 +6,8 @@
 #include <random>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/logfile_utils.h"
diff --git a/aos/events/logging/buffer_encoder_test.cc b/aos/events/logging/buffer_encoder_test.cc
index 127fb4f..69dd7de 100644
--- a/aos/events/logging/buffer_encoder_test.cc
+++ b/aos/events/logging/buffer_encoder_test.cc
@@ -4,7 +4,8 @@
 #include <fstream>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/aos/events/logging/config_remapper.cc b/aos/events/logging/config_remapper.cc
index 088d393..763cbc3 100644
--- a/aos/events/logging/config_remapper.cc
+++ b/aos/events/logging/config_remapper.cc
@@ -2,6 +2,8 @@
 
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/escaping.h"
 #include "flatbuffers/flatbuffers.h"
 
diff --git a/aos/events/logging/file_operations.cc b/aos/events/logging/file_operations.cc
index d54c8b6..abd9942 100644
--- a/aos/events/logging/file_operations.cc
+++ b/aos/events/logging/file_operations.cc
@@ -3,8 +3,9 @@
 #include <algorithm>
 #include <ostream>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/match.h"
-#include "glog/logging.h"
 
 namespace aos::logger::internal {
 
diff --git a/aos/events/logging/log_backend.cc b/aos/events/logging/log_backend.cc
index f8a6846..d2f0d77 100644
--- a/aos/events/logging/log_backend.cc
+++ b/aos/events/logging/log_backend.cc
@@ -4,19 +4,21 @@
 
 #include <filesystem>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
-#include "glog/logging.h"
 
 #include "aos/events/logging/file_operations.h"
 #include "aos/util/file.h"
 
-DEFINE_bool(
-    sync, false,
+ABSL_FLAG(
+    bool, sync, false,
     "If true, sync data to disk as we go so we don't get too far ahead.  Also "
     "fadvise that we are done with the memory once it hits disk.");
 
-DEFINE_uint32(queue_reserve, 32, "Pre-reserved size of write queue.");
+ABSL_FLAG(uint32_t, queue_reserve, 32, "Pre-reserved size of write queue.");
 
 namespace aos::logger {
 namespace {
@@ -42,7 +44,7 @@
 }  // namespace
 
 logger::QueueAligner::QueueAligner() {
-  aligned_queue_.reserve(FLAGS_queue_reserve);
+  aligned_queue_.reserve(absl::GetFlag(FLAGS_queue_reserve));
 }
 
 void logger::QueueAligner::FillAlignedQueue(
@@ -285,7 +287,7 @@
     return WriteCode::kOutOfSpace;
   }
 
-  if (FLAGS_sync) {
+  if (absl::GetFlag(FLAGS_sync)) {
     // Flush asynchronously and force the data out of the cache.
     sync_file_range(fd_, total_write_bytes_, written, SYNC_FILE_RANGE_WRITE);
     if (last_synced_bytes_ != 0) {
diff --git a/aos/events/logging/log_backend_test.cc b/aos/events/logging/log_backend_test.cc
index 0603b33..fc29979 100644
--- a/aos/events/logging/log_backend_test.cc
+++ b/aos/events/logging/log_backend_test.cc
@@ -5,9 +5,10 @@
 #include <fstream>
 #include <random>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_join.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/aos/events/logging/log_cat.cc b/aos/events/logging/log_cat.cc
index d7347be..38a9136 100644
--- a/aos/events/logging/log_cat.cc
+++ b/aos/events/logging/log_cat.cc
@@ -6,8 +6,9 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 #include "absl/strings/escaping.h"
-#include "gflags/gflags.h"
 
 #include "aos/aos_cli_utils.h"
 #include "aos/configuration.h"
@@ -17,52 +18,52 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/sha256.h"
 
-DEFINE_string(
-    name, "",
+ABSL_FLAG(
+    std::string, name, "",
     "Name to match for printing out channels. Empty means no name filter.");
-DEFINE_string(type, "",
-              "Channel type to match for printing out channels. Empty means no "
-              "type filter.");
-DEFINE_bool(json, false, "If true, print fully valid JSON");
-DEFINE_bool(fetch, false,
-            "If true, also print out the messages from before the start of the "
-            "log file");
-DEFINE_bool(raw, false,
-            "If true, just print the data out unsorted and unparsed");
-DEFINE_string(raw_header, "",
-              "If set, the file to read the header from in raw mode");
-DEFINE_bool(distributed_clock, false,
-            "If true, print out the distributed time");
-DEFINE_bool(format_raw, true,
-            "If true and --raw is specified, print out raw data, but use the "
-            "schema to format the data.");
-DEFINE_int64(max_vector_size, 100,
-             "If positive, vectors longer than this will not be printed");
-DEFINE_bool(pretty, false,
-            "If true, pretty print the messages on multiple lines");
-DEFINE_bool(
-    pretty_max, false,
+ABSL_FLAG(std::string, type, "",
+          "Channel type to match for printing out channels. Empty means no "
+          "type filter.");
+ABSL_FLAG(bool, json, false, "If true, print fully valid JSON");
+ABSL_FLAG(bool, fetch, false,
+          "If true, also print out the messages from before the start of the "
+          "log file");
+ABSL_FLAG(bool, raw, false,
+          "If true, just print the data out unsorted and unparsed");
+ABSL_FLAG(std::string, raw_header, "",
+          "If set, the file to read the header from in raw mode");
+ABSL_FLAG(bool, distributed_clock, false,
+          "If true, print out the distributed time");
+ABSL_FLAG(bool, format_raw, true,
+          "If true and --raw is specified, print out raw data, but use the "
+          "schema to format the data.");
+ABSL_FLAG(int64_t, max_vector_size, 100,
+          "If positive, vectors longer than this will not be printed");
+ABSL_FLAG(bool, pretty, false,
+          "If true, pretty print the messages on multiple lines");
+ABSL_FLAG(
+    bool, pretty_max, false,
     "If true, expand every field to its own line (expands more than -pretty)");
-DEFINE_bool(print_timestamps, true, "If true, timestamps are printed.");
-DEFINE_bool(print, true,
-            "If true, actually print the messages.  If false, discard them, "
-            "confirming they can be parsed.");
-DEFINE_uint64(
-    count, 0,
+ABSL_FLAG(bool, print_timestamps, true, "If true, timestamps are printed.");
+ABSL_FLAG(bool, print, true,
+          "If true, actually print the messages.  If false, discard them, "
+          "confirming they can be parsed.");
+ABSL_FLAG(
+    uint64_t, count, 0,
     "If >0, log_cat will exit after printing this many messages.  This "
     "includes messages from before the start of the log if --fetch is set.");
-DEFINE_bool(print_parts_only, false,
-            "If true, only print out the results of logfile sorting.");
-DEFINE_bool(channels, false,
-            "If true, print out all the configured channels for this log.");
-DEFINE_double(monotonic_start_time, 0.0,
-              "If set, only print messages sent at or after this many seconds "
-              "after epoch.");
-DEFINE_double(monotonic_end_time, 0.0,
-              "If set, only print messages sent at or before this many seconds "
-              "after epoch.");
-DEFINE_bool(hex, false,
-            "Are integers in the messages printed in hex notation.");
+ABSL_FLAG(bool, print_parts_only, false,
+          "If true, only print out the results of logfile sorting.");
+ABSL_FLAG(bool, channels, false,
+          "If true, print out all the configured channels for this log.");
+ABSL_FLAG(double, monotonic_start_time, 0.0,
+          "If set, only print messages sent at or after this many seconds "
+          "after epoch.");
+ABSL_FLAG(double, monotonic_end_time, 0.0,
+          "If set, only print messages sent at or before this many seconds "
+          "after epoch.");
+ABSL_FLAG(bool, hex, false,
+          "Are integers in the messages printed in hex notation.");
 
 using aos::monotonic_clock;
 namespace chrono = std::chrono;
@@ -70,12 +71,14 @@
 // Prints out raw log parts to stdout.
 int PrintRaw(int argc, char **argv) {
   if (argc == 1) {
-    CHECK(!FLAGS_raw_header.empty());
-    aos::logger::MessageReader raw_header_reader(FLAGS_raw_header);
-    std::cout << aos::FlatbufferToJson(raw_header_reader.raw_log_file_header(),
-                                       {.multi_line = FLAGS_pretty,
-                                        .max_vector_size = static_cast<size_t>(
-                                            FLAGS_max_vector_size)})
+    CHECK(!absl::GetFlag(FLAGS_raw_header).empty());
+    aos::logger::MessageReader raw_header_reader(
+        absl::GetFlag(FLAGS_raw_header));
+    std::cout << aos::FlatbufferToJson(
+                     raw_header_reader.raw_log_file_header(),
+                     {.multi_line = absl::GetFlag(FLAGS_pretty),
+                      .max_vector_size = static_cast<size_t>(
+                          absl::GetFlag(FLAGS_max_vector_size))})
               << std::endl;
     return 0;
   }
@@ -108,9 +111,10 @@
         maybe_header_data);
     if (maybe_header.Verify()) {
       std::cout << aos::FlatbufferToJson(
-                       log_file_header, {.multi_line = FLAGS_pretty,
-                                         .max_vector_size = static_cast<size_t>(
-                                             FLAGS_max_vector_size)})
+                       log_file_header,
+                       {.multi_line = absl::GetFlag(FLAGS_pretty),
+                        .max_vector_size = static_cast<size_t>(
+                            absl::GetFlag(FLAGS_max_vector_size))})
                 << std::endl;
       LOG(WARNING) << "Found duplicate LogFileHeader in " << reader.filename();
       log_file_header =
@@ -126,26 +130,26 @@
   // And now use the final sha256 to match the raw_header.
   std::optional<aos::logger::MessageReader> raw_header_reader;
   const aos::logger::LogFileHeader *full_header = &log_file_header.message();
-  if (!FLAGS_raw_header.empty()) {
-    raw_header_reader.emplace(FLAGS_raw_header);
-    std::cout << aos::FlatbufferToJson(full_header,
-                                       {.multi_line = FLAGS_pretty,
-                                        .max_vector_size = static_cast<size_t>(
-                                            FLAGS_max_vector_size)})
+  if (!absl::GetFlag(FLAGS_raw_header).empty()) {
+    raw_header_reader.emplace(absl::GetFlag(FLAGS_raw_header));
+    std::cout << aos::FlatbufferToJson(
+                     full_header, {.multi_line = absl::GetFlag(FLAGS_pretty),
+                                   .max_vector_size = static_cast<size_t>(
+                                       absl::GetFlag(FLAGS_max_vector_size))})
               << std::endl;
     CHECK_EQ(full_header->configuration_sha256()->string_view(),
              aos::Sha256(raw_header_reader->raw_log_file_header().span()));
     full_header = raw_header_reader->log_file_header();
   }
 
-  if (!FLAGS_print) {
+  if (!absl::GetFlag(FLAGS_print)) {
     return 0;
   }
 
-  std::cout << aos::FlatbufferToJson(full_header,
-                                     {.multi_line = FLAGS_pretty,
-                                      .max_vector_size = static_cast<size_t>(
-                                          FLAGS_max_vector_size)})
+  std::cout << aos::FlatbufferToJson(
+                   full_header, {.multi_line = absl::GetFlag(FLAGS_pretty),
+                                 .max_vector_size = static_cast<size_t>(
+                                     absl::GetFlag(FLAGS_max_vector_size))})
             << std::endl;
   CHECK(full_header->has_configuration())
       << ": Missing configuration! You may want to provide the path to the "
@@ -178,21 +182,25 @@
           << channel->type()->c_str();
     }
 
-    if (FLAGS_format_raw && message.message().data() != nullptr) {
+    if (absl::GetFlag(FLAGS_format_raw) &&
+        message.message().data() != nullptr) {
       std::cout << aos::configuration::StrippedChannelToString(channel) << " "
-                << aos::FlatbufferToJson(message, {.multi_line = FLAGS_pretty,
-                                                   .max_vector_size = 4})
+                << aos::FlatbufferToJson(
+                       message, {.multi_line = absl::GetFlag(FLAGS_pretty),
+                                 .max_vector_size = 4})
                 << ": "
                 << aos::FlatbufferToJson(
                        channel->schema(), message.message().data()->data(),
-                       {FLAGS_pretty,
-                        static_cast<size_t>(FLAGS_max_vector_size)})
+                       {absl::GetFlag(FLAGS_pretty),
+                        static_cast<size_t>(
+                            absl::GetFlag(FLAGS_max_vector_size))})
                 << std::endl;
     } else {
       std::cout << aos::configuration::StrippedChannelToString(channel) << " "
                 << aos::FlatbufferToJson(
-                       message, {FLAGS_pretty,
-                                 static_cast<size_t>(FLAGS_max_vector_size)})
+                       message, {absl::GetFlag(FLAGS_pretty),
+                                 static_cast<size_t>(
+                                     absl::GetFlag(FLAGS_max_vector_size))})
                 << std::endl;
     }
   }
@@ -219,26 +227,26 @@
         event_loop_->configuration()->channels();
 
     const monotonic_clock::time_point start_time =
-        (FLAGS_monotonic_start_time == 0.0
+        (absl::GetFlag(FLAGS_monotonic_start_time) == 0.0
              ? monotonic_clock::min_time
              : monotonic_clock::time_point(
                    std::chrono::duration_cast<monotonic_clock::duration>(
                        std::chrono::duration<double>(
-                           FLAGS_monotonic_start_time))));
+                           absl::GetFlag(FLAGS_monotonic_start_time)))));
     const monotonic_clock::time_point end_time =
-        (FLAGS_monotonic_end_time == 0.0
+        (absl::GetFlag(FLAGS_monotonic_end_time) == 0.0
              ? monotonic_clock::max_time
              : monotonic_clock::time_point(
                    std::chrono::duration_cast<monotonic_clock::duration>(
                        std::chrono::duration<double>(
-                           FLAGS_monotonic_end_time))));
+                           absl::GetFlag(FLAGS_monotonic_end_time)))));
 
     for (flatbuffers::uoffset_t i = 0; i < channels->size(); i++) {
       const aos::Channel *channel = channels->Get(i);
       const flatbuffers::string_view name = channel->name()->string_view();
       const flatbuffers::string_view type = channel->type()->string_view();
-      if (name.find(FLAGS_name) != std::string::npos &&
-          type.find(FLAGS_type) != std::string::npos) {
+      if (name.find(absl::GetFlag(FLAGS_name)) != std::string::npos &&
+          type.find(absl::GetFlag(FLAGS_type)) != std::string::npos) {
         if (!aos::configuration::ChannelIsReadableOnNode(channel,
                                                          event_loop_->node())) {
           continue;
@@ -250,14 +258,15 @@
                                               end_time](
                                                  const aos::Context &context,
                                                  const void * /*message*/) {
-          if (!FLAGS_print) {
+          if (!absl::GetFlag(FLAGS_print)) {
             return;
           }
-          if (FLAGS_count > 0 && printer_->message_count() >= FLAGS_count) {
+          if (absl::GetFlag(FLAGS_count) > 0 &&
+              printer_->message_count() >= absl::GetFlag(FLAGS_count)) {
             return;
           }
 
-          if (!FLAGS_fetch && !started_) {
+          if (!absl::GetFlag(FLAGS_fetch) && !started_) {
             return;
           }
 
@@ -267,7 +276,8 @@
           }
 
           printer_->PrintMessage(node_name_, node_factory_, channel, context);
-          if (FLAGS_count > 0 && printer_->message_count() >= FLAGS_count) {
+          if (absl::GetFlag(FLAGS_count) > 0 &&
+              printer_->message_count() >= absl::GetFlag(FLAGS_count)) {
             factory_->Exit();
           }
         });
@@ -278,7 +288,7 @@
   void SetStarted(bool started, aos::monotonic_clock::time_point monotonic_now,
                   aos::realtime_clock::time_point realtime_now) {
     started_ = started;
-    if (FLAGS_json) {
+    if (absl::GetFlag(FLAGS_json)) {
       return;
     }
     if (started_) {
@@ -318,7 +328,7 @@
 };
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Usage:\n"
       "  log_cat [args] logfile1 logfile2 ...\n"
       "\n"
@@ -332,7 +342,7 @@
       "the logged data.");
   aos::InitGoogle(&argc, &argv);
 
-  if (FLAGS_raw) {
+  if (absl::GetFlag(FLAGS_raw)) {
     return PrintRaw(argc, argv);
   }
 
@@ -345,17 +355,17 @@
 
   for (auto &it : logfiles) {
     VLOG(1) << it;
-    if (FLAGS_print_parts_only) {
+    if (absl::GetFlag(FLAGS_print_parts_only)) {
       std::cout << it << std::endl;
     }
   }
-  if (FLAGS_print_parts_only) {
+  if (absl::GetFlag(FLAGS_print_parts_only)) {
     return 0;
   }
 
   aos::logger::LogReader reader(logfiles);
 
-  if (FLAGS_channels) {
+  if (absl::GetFlag(FLAGS_channels)) {
     const aos::Configuration *config = reader.configuration();
     for (const aos::Channel *channel : *config->channels()) {
       std::cout << channel->name()->c_str() << " " << channel->type()->c_str()
@@ -373,8 +383,8 @@
       const aos::Channel *channel = channels->Get(i);
       const flatbuffers::string_view name = channel->name()->string_view();
       const flatbuffers::string_view type = channel->type()->string_view();
-      if (name.find(FLAGS_name) != std::string::npos &&
-          type.find(FLAGS_type) != std::string::npos) {
+      if (name.find(absl::GetFlag(FLAGS_name)) != std::string::npos &&
+          type.find(absl::GetFlag(FLAGS_type)) != std::string::npos) {
         found_channel = true;
       }
     }
@@ -385,13 +395,14 @@
 
   aos::Printer printer(
       {
-          .pretty = FLAGS_pretty,
-          .max_vector_size = static_cast<size_t>(FLAGS_max_vector_size),
-          .pretty_max = FLAGS_pretty_max,
-          .print_timestamps = FLAGS_print_timestamps,
-          .json = FLAGS_json,
-          .distributed_clock = FLAGS_distributed_clock,
-          .hex = FLAGS_hex,
+          .pretty = absl::GetFlag(FLAGS_pretty),
+          .max_vector_size =
+              static_cast<size_t>(absl::GetFlag(FLAGS_max_vector_size)),
+          .pretty_max = absl::GetFlag(FLAGS_pretty_max),
+          .print_timestamps = absl::GetFlag(FLAGS_print_timestamps),
+          .json = absl::GetFlag(FLAGS_json),
+          .distributed_clock = absl::GetFlag(FLAGS_distributed_clock),
+          .hex = absl::GetFlag(FLAGS_hex),
       },
       false);
 
diff --git a/aos/events/logging/log_config_extractor.cc b/aos/events/logging/log_config_extractor.cc
index f2df5b3..628bf72 100644
--- a/aos/events/logging/log_config_extractor.cc
+++ b/aos/events/logging/log_config_extractor.cc
@@ -2,9 +2,11 @@
 #include <iostream>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration_generated.h"
 #include "aos/events/logging/log_reader.h"
@@ -13,19 +15,20 @@
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_string(output_path, "/tmp/",
-              "Destination folder for output files. If this flag is not used, "
-              "it stores the files in /tmp/.");
-DEFINE_bool(convert_to_json, false,
-            "If true, can be used to convert bfbs to json.");
-DEFINE_bool(bfbs, false,
-            "If true, write as a binary flatbuffer inside the output_path.");
-DEFINE_bool(json, false, "If true, write as a json inside the output_path.");
-DEFINE_bool(stripped, false,
-            "If true, write as a stripped json inside the output_path.");
-DEFINE_bool(quiet, false,
-            "If true, do not print configuration to stdout. If false, print "
-            "stripped json");
+ABSL_FLAG(std::string, output_path, "/tmp/",
+          "Destination folder for output files. If this flag is not used, "
+          "it stores the files in /tmp/.");
+ABSL_FLAG(bool, convert_to_json, false,
+          "If true, can be used to convert bfbs to json.");
+ABSL_FLAG(bool, bfbs, false,
+          "If true, write as a binary flatbuffer inside the output_path.");
+ABSL_FLAG(bool, json, false,
+          "If true, write as a json inside the output_path.");
+ABSL_FLAG(bool, stripped, false,
+          "If true, write as a stripped json inside the output_path.");
+ABSL_FLAG(bool, quiet, false,
+          "If true, do not print configuration to stdout. If false, print "
+          "stripped json");
 
 namespace aos {
 
@@ -43,27 +46,27 @@
   auto config_flatbuffer = configuration::MergeConfiguration(
       RecursiveCopyFlatBuffer(config), schemas);
 
-  if (FLAGS_bfbs) {
+  if (absl::GetFlag(FLAGS_bfbs)) {
     WriteFlatbufferToFile(output_path + ".bfbs", config_flatbuffer);
     LOG(INFO) << "Done writing bfbs to " << output_path << ".bfbs";
   }
 
-  if (FLAGS_json) {
+  if (absl::GetFlag(FLAGS_json)) {
     WriteFlatbufferToJson(output_path + ".json", config_flatbuffer);
     LOG(INFO) << "Done writing json to " << output_path << ".json";
   }
 
-  if (FLAGS_stripped || !FLAGS_quiet) {
+  if (absl::GetFlag(FLAGS_stripped) || !absl::GetFlag(FLAGS_quiet)) {
     auto *channels = config_flatbuffer.mutable_message()->mutable_channels();
     for (size_t i = 0; i < channels->size(); i++) {
       channels->GetMutableObject(i)->clear_schema();
     }
-    if (FLAGS_stripped) {
+    if (absl::GetFlag(FLAGS_stripped)) {
       WriteFlatbufferToJson(output_path + ".stripped.json", config_flatbuffer);
       LOG(INFO) << "Done writing stripped json to " << output_path
                 << ".stripped.json";
     }
-    if (!FLAGS_quiet) {
+    if (!absl::GetFlag(FLAGS_quiet)) {
       std::cout << FlatbufferToJson(config_flatbuffer) << std::endl;
     }
   }
@@ -72,7 +75,7 @@
 int Main(int argc, char *argv[]) {
   CHECK(argc > 1) << "Must provide an argument";
 
-  std::string output_path = FLAGS_output_path;
+  std::string output_path = absl::GetFlag(FLAGS_output_path);
   if (output_path.back() != '/') {
     output_path += "/";
   }
@@ -93,7 +96,7 @@
     aos::FlatbufferDetachedBuffer<aos::Configuration> buffer(
         aos::JsonToFlatbuffer(stdin_data, aos::ConfigurationTypeTable()));
     WriteConfig(&buffer.message(), output_path);
-  } else if (FLAGS_convert_to_json) {
+  } else if (absl::GetFlag(FLAGS_convert_to_json)) {
     aos::FlatbufferDetachedBuffer config = aos::configuration::ReadConfig(arg);
     WriteFlatbufferToJson(output_path + ".json", config);
     LOG(INFO) << "Done writing json to " << output_path << ".json";
@@ -109,7 +112,7 @@
 }  // namespace aos
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Binary to output the configuration of a log.\n"
       "# print config as stripped json to stdout\n"
       "# path to log should always be absolute path.\n"
diff --git a/aos/events/logging/log_edit.cc b/aos/events/logging/log_edit.cc
index 4585ab7..33cd120 100644
--- a/aos/events/logging/log_edit.cc
+++ b/aos/events/logging/log_edit.cc
@@ -1,6 +1,7 @@
 #include <iostream>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -9,32 +10,32 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/util/file.h"
 
-DEFINE_string(logfile, "/tmp/logfile.bfbs",
-              "Name of the logfile to read from.");
-DEFINE_bool(
-    replace, false,
-    "If true, replace the header on the log file with the JSON header.");
-DEFINE_string(
-    header, "",
+ABSL_FLAG(std::string, logfile, "/tmp/logfile.bfbs",
+          "Name of the logfile to read from.");
+ABSL_FLAG(bool, replace, false,
+          "If true, replace the header on the log file with the JSON header.");
+ABSL_FLAG(
+    std::string, header, "",
     "If provided, this is the path to the JSON with the log file header.  If "
     "not provided, _header.json will be appended to --logfile.");
 
-DEFINE_int32(
-    max_message_size, 128 * 1024 * 1024,
-    "Max size of a message to be written.  This sets the buffers inside "
-    "the encoders.");
+ABSL_FLAG(int32_t, max_message_size, 128 * 1024 * 1024,
+          "Max size of a message to be written.  This sets the buffers inside "
+          "the encoders.");
+ABSL_FLAG(bool, direct, false,
+          "If true, write using O_DIRECT and write 512 byte aligned blocks "
+          "whenever possible.");
 
-DEFINE_bool(direct, false,
-            "If true, write using O_DIRECT and write 512 byte aligned blocks "
-            "whenever possible.");
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(R"(This tool lets us manipulate log files.)");
+  absl::SetProgramUsageMessage(R"(This tool lets us manipulate log files.)");
   aos::InitGoogle(&argc, &argv);
 
   std::string header_json_path =
-      FLAGS_header.empty() ? (FLAGS_logfile + "_header.json") : FLAGS_header;
+      absl::GetFlag(FLAGS_header).empty()
+          ? (absl::GetFlag(FLAGS_logfile) + "_header.json")
+          : absl::GetFlag(FLAGS_header);
 
-  if (FLAGS_replace) {
+  if (absl::GetFlag(FLAGS_replace)) {
     const ::std::string header_json =
         aos::util::ReadFileToStringOrDie(header_json_path);
     flatbuffers::FlatBufferBuilder fbb;
@@ -46,16 +47,18 @@
     aos::SizePrefixedFlatbufferDetachedBuffer<aos::logger::LogFileHeader>
         header(fbb.Release());
 
-    const std::string orig_path = FLAGS_logfile + ".orig";
-    PCHECK(rename(FLAGS_logfile.c_str(), orig_path.c_str()) == 0);
+    const std::string orig_path = absl::GetFlag(FLAGS_logfile) + ".orig";
+    PCHECK(rename(absl::GetFlag(FLAGS_logfile).c_str(), orig_path.c_str()) ==
+           0);
 
     aos::logger::SpanReader span_reader(orig_path);
     CHECK(!span_reader.ReadMessage().empty()) << ": Empty header, aborting";
 
-    aos::logger::FileBackend file_backend("/", FLAGS_direct);
+    aos::logger::FileBackend file_backend("/", absl::GetFlag(FLAGS_direct));
     aos::logger::DetachedBufferWriter buffer_writer(
-        file_backend.RequestFile(FLAGS_logfile),
-        std::make_unique<aos::logger::DummyEncoder>(FLAGS_max_message_size));
+        file_backend.RequestFile(absl::GetFlag(FLAGS_logfile)),
+        std::make_unique<aos::logger::DummyEncoder>(
+            absl::GetFlag(FLAGS_max_message_size)));
     {
       aos::logger::DataEncoder::SpanCopier copier(header.span());
       buffer_writer.CopyMessage(&copier, aos::monotonic_clock::min_time);
@@ -73,7 +76,7 @@
       }
     }
   } else {
-    aos::logger::MessageReader reader(FLAGS_logfile);
+    aos::logger::MessageReader reader(absl::GetFlag(FLAGS_logfile));
     aos::util::WriteStringToFileOrDie(
         header_json_path,
         aos::FlatbufferToJson(reader.log_file_header(), {.multi_line = true}));
diff --git a/aos/events/logging/log_namer.cc b/aos/events/logging/log_namer.cc
index c065f68..e8fb524 100644
--- a/aos/events/logging/log_namer.cc
+++ b/aos/events/logging/log_namer.cc
@@ -6,9 +6,11 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 
 #include "aos/containers/error_list.h"
 #include "aos/containers/sized_array.h"
@@ -17,7 +19,7 @@
 #include "aos/flatbuffer_merge.h"
 #include "aos/uuid.h"
 
-DECLARE_int32(flush_size);
+ABSL_DECLARE_FLAG(int32_t, flush_size);
 
 namespace aos::logger {
 
@@ -762,7 +764,7 @@
       encoder_factory_([](size_t max_message_size) {
         // TODO(austin): For slow channels, can we allocate less memory?
         return std::make_unique<DummyEncoder>(max_message_size,
-                                              FLAGS_flush_size);
+                                              absl::GetFlag(FLAGS_flush_size));
       }) {}
 
 MultiNodeLogNamer::~MultiNodeLogNamer() {
diff --git a/aos/events/logging/log_namer.h b/aos/events/logging/log_namer.h
index 2c0982a..dcacd1b 100644
--- a/aos/events/logging/log_namer.h
+++ b/aos/events/logging/log_namer.h
@@ -8,8 +8,9 @@
 #include <vector>
 
 #include "absl/container/btree_map.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 
 #include "aos/events/logging/logfile_utils.h"
 #include "aos/events/logging/logger_generated.h"
diff --git a/aos/events/logging/log_reader.cc b/aos/events/logging/log_reader.cc
index 81f8466..ae5f0ef 100644
--- a/aos/events/logging/log_reader.cc
+++ b/aos/events/logging/log_reader.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/flags/flag.h"
 #include "absl/strings/escaping.h"
 #include "absl/types/span.h"
 #include "flatbuffers/flatbuffers.h"
@@ -30,47 +31,47 @@
 #include "aos/util/file.h"
 #include "aos/uuid.h"
 
-DEFINE_bool(skip_missing_forwarding_entries, false,
-            "If true, drop any forwarding entries with missing data.  If "
-            "false, CHECK.");
+ABSL_FLAG(bool, skip_missing_forwarding_entries, false,
+          "If true, drop any forwarding entries with missing data.  If "
+          "false, CHECK.");
 
-DECLARE_bool(timestamps_to_csv);
-DEFINE_bool(
-    enable_timestamp_loading, true,
+ABSL_DECLARE_FLAG(bool, timestamps_to_csv);
+ABSL_FLAG(
+    bool, enable_timestamp_loading, true,
     "Enable loading all the timestamps into RAM at startup if they are in "
     "separate files.  This fixes any timestamp queueing problems for the cost "
     "of storing timestamps in RAM only on logs with timestamps logged in "
     "separate files from data.  Only disable this if you are reading a really "
     "long log file and are experiencing memory problems due to loading all the "
     "timestamps into RAM.");
-DEFINE_bool(
-    force_timestamp_loading, false,
+ABSL_FLAG(
+    bool, force_timestamp_loading, false,
     "Force loading all the timestamps into RAM at startup.  This fixes any "
     "timestamp queueing problems for the cost of storing timestamps in RAM and "
     "potentially reading each log twice.");
 
-DEFINE_bool(skip_order_validation, false,
-            "If true, ignore any out of orderness in replay");
+ABSL_FLAG(bool, skip_order_validation, false,
+          "If true, ignore any out of orderness in replay");
 
-DEFINE_double(
-    time_estimation_buffer_seconds, 2.0,
+ABSL_FLAG(
+    double, time_estimation_buffer_seconds, 2.0,
     "The time to buffer ahead in the log file to accurately reconstruct time.");
 
-DEFINE_string(
-    start_time, "",
+ABSL_FLAG(
+    std::string, start_time, "",
     "If set, start at this point in time in the log on the realtime clock.");
-DEFINE_string(
-    end_time, "",
+ABSL_FLAG(
+    std::string, end_time, "",
     "If set, end at this point in time in the log on the realtime clock.");
 
-DEFINE_bool(drop_realtime_messages_before_start, false,
-            "If set, will drop any messages sent before the start of the "
-            "logfile in realtime replay. Setting this guarantees consistency "
-            "in timing with the original logfile, but means that you lose "
-            "access to fetched low-frequency messages.");
+ABSL_FLAG(bool, drop_realtime_messages_before_start, false,
+          "If set, will drop any messages sent before the start of the "
+          "logfile in realtime replay. Setting this guarantees consistency "
+          "in timing with the original logfile, but means that you lose "
+          "access to fetched low-frequency messages.");
 
-DEFINE_double(
-    threaded_look_ahead_seconds, 2.0,
+ABSL_FLAG(
+    double, threaded_look_ahead_seconds, 2.0,
     "Time, in seconds, to add to look-ahead when using multi-threaded replay. "
     "Can validly be zero, but higher values are encouraged for realtime replay "
     "in order to prevent the replay from ever having to block on waiting for "
@@ -190,8 +191,8 @@
       replay_channels_(replay_channels),
       config_remapper_(log_files_.config().get(), replay_configuration_,
                        replay_channels_) {
-  SetStartTime(FLAGS_start_time);
-  SetEndTime(FLAGS_end_time);
+  SetStartTime(absl::GetFlag(FLAGS_start_time));
+  SetEndTime(absl::GetFlag(FLAGS_end_time));
 
   {
     // Log files container validates that log files shared the same config.
@@ -442,13 +443,13 @@
   filters_ =
       std::make_unique<message_bridge::MultiNodeNoncausalOffsetEstimator>(
           event_loop_factory_->configuration(), logged_configuration(),
-          log_files_.boots(), FLAGS_skip_order_validation,
+          log_files_.boots(), absl::GetFlag(FLAGS_skip_order_validation),
           timestamp_queue_strategy ==
                   TimestampQueueStrategy::kQueueTimestampsAtStartup
               ? chrono::seconds(0)
               : chrono::duration_cast<chrono::nanoseconds>(
                     chrono::duration<double>(
-                        FLAGS_time_estimation_buffer_seconds)));
+                        absl::GetFlag(FLAGS_time_estimation_buffer_seconds))));
 
   std::vector<TimestampMapper *> timestamp_mappers;
   for (const Node *node : configuration::GetNodes(configuration())) {
@@ -625,7 +626,7 @@
                                                : monotonic_clock::min_time);
   }
 
-  if (FLAGS_timestamps_to_csv) {
+  if (absl::GetFlag(FLAGS_timestamps_to_csv)) {
     filters_->Start(event_loop_factory);
   }
 }
@@ -640,8 +641,8 @@
 
 TimestampQueueStrategy LogReader::ComputeTimestampQueueStrategy() const {
   if ((log_files_.TimestampsStoredSeparately() &&
-       FLAGS_enable_timestamp_loading) ||
-      FLAGS_force_timestamp_loading) {
+       absl::GetFlag(FLAGS_enable_timestamp_loading)) ||
+      absl::GetFlag(FLAGS_force_timestamp_loading)) {
     return TimestampQueueStrategy::kQueueTimestampsAtStartup;
   } else {
     return TimestampQueueStrategy::kQueueTogether;
@@ -658,13 +659,13 @@
   filters_ =
       std::make_unique<message_bridge::MultiNodeNoncausalOffsetEstimator>(
           event_loop->configuration(), logged_configuration(),
-          log_files_.boots(), FLAGS_skip_order_validation,
+          log_files_.boots(), absl::GetFlag(FLAGS_skip_order_validation),
           timestamp_queue_strategy ==
                   TimestampQueueStrategy::kQueueTimestampsAtStartup
               ? chrono::seconds(0)
               : chrono::duration_cast<chrono::nanoseconds>(
                     chrono::duration<double>(
-                        FLAGS_time_estimation_buffer_seconds)));
+                        absl::GetFlag(FLAGS_time_estimation_buffer_seconds))));
 
   std::vector<TimestampMapper *> timestamp_mappers;
   for (const Node *node : configuration::GetNodes(configuration())) {
@@ -860,7 +861,7 @@
         state->event_loop()->context().monotonic_event_time;
     if (event_loop_factory_ != nullptr) {
       // Only enforce exact timing in simulation.
-      if (!FLAGS_skip_order_validation) {
+      if (!absl::GetFlag(FLAGS_skip_order_validation)) {
         CHECK(monotonic_now == timestamped_message.monotonic_event_time.time)
             << ": " << FlatbufferToJson(state->event_loop()->node()) << " Now "
             << monotonic_now << " trying to send "
@@ -884,11 +885,12 @@
             state->monotonic_start_time(
                 timestamped_message.monotonic_event_time.boot) ||
         event_loop_factory_ != nullptr ||
-        !FLAGS_drop_realtime_messages_before_start) {
+        !absl::GetFlag(FLAGS_drop_realtime_messages_before_start)) {
       if (timestamped_message.data != nullptr && !state->found_last_message()) {
         if (timestamped_message.monotonic_remote_time !=
                 BootTimestamp::min_time() &&
-            !FLAGS_skip_order_validation && event_loop_factory_ != nullptr) {
+            !absl::GetFlag(FLAGS_skip_order_validation) &&
+            event_loop_factory_ != nullptr) {
           // Confirm that the message was sent on the sending node before the
           // destination node (this node).  As a proxy, do this by making sure
           // that time on the source node is past when the message was sent.
@@ -899,7 +901,7 @@
           // fix that.
           BootTimestamp monotonic_remote_now =
               state->monotonic_remote_now(timestamped_message.channel_index);
-          if (!FLAGS_skip_order_validation) {
+          if (!absl::GetFlag(FLAGS_skip_order_validation)) {
             CHECK_EQ(timestamped_message.monotonic_remote_time.boot,
                      monotonic_remote_now.boot)
                 << state->event_loop()->node()->name()->string_view() << " to "
@@ -974,7 +976,7 @@
                       state->monotonic_remote_start_time(
                           timestamped_message.monotonic_remote_time.boot,
                           timestamped_message.channel_index) &&
-                  !FLAGS_skip_missing_forwarding_entries)) {
+                  !absl::GetFlag(FLAGS_skip_missing_forwarding_entries))) {
         if (!state->found_last_message()) {
           // We've found a timestamp without data that we expect to have data
           // for. This likely means that we are at the end of the log file.
@@ -1130,8 +1132,8 @@
       // primed).
       state->QueueThreadUntil(
           next_time + std::chrono::duration_cast<std::chrono::nanoseconds>(
-                          std::chrono::duration<double>(
-                              FLAGS_threaded_look_ahead_seconds)));
+                          std::chrono::duration<double>(absl::GetFlag(
+                              FLAGS_threaded_look_ahead_seconds))));
       state->MaybeSetClockOffset();
       state->Schedule(next_time.time);
       state->SetUpStartupTimer();
@@ -1787,7 +1789,8 @@
     message_queuer_->SetState(
         message.value().monotonic_event_time +
         std::chrono::duration_cast<std::chrono::nanoseconds>(
-            std::chrono::duration<double>(FLAGS_threaded_look_ahead_seconds)));
+            std::chrono::duration<double>(
+                absl::GetFlag(FLAGS_threaded_look_ahead_seconds))));
     VLOG(1) << "Popped " << message.value()
             << configuration::CleanedChannelToString(
                    event_loop_->configuration()->channels()->Get(
@@ -1872,8 +1875,9 @@
       TimestampQueueStrategy::kQueueTimestampsAtStartup)
     return;
 
-  timestamp_mapper_->QueueFor(chrono::duration_cast<chrono::seconds>(
-      chrono::duration<double>(FLAGS_time_estimation_buffer_seconds)));
+  timestamp_mapper_->QueueFor(
+      chrono::duration_cast<chrono::seconds>(chrono::duration<double>(
+          absl::GetFlag(FLAGS_time_estimation_buffer_seconds))));
 }
 
 void LogReader::State::Deregister() {
diff --git a/aos/events/logging/log_reader.h b/aos/events/logging/log_reader.h
index 85d4d2c..1334b86 100644
--- a/aos/events/logging/log_reader.h
+++ b/aos/events/logging/log_reader.h
@@ -8,9 +8,10 @@
 #include <tuple>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/condition.h"
 #include "aos/events/event_loop.h"
diff --git a/aos/events/logging/log_replayer.cc b/aos/events/logging/log_replayer.cc
index 22d8b39..970b828 100644
--- a/aos/events/logging/log_replayer.cc
+++ b/aos/events/logging/log_replayer.cc
@@ -7,9 +7,11 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration_generated.h"
 #include "aos/events/event_loop.h"
@@ -28,30 +30,31 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/util/file.h"
 
-DEFINE_string(config, "", "If specified, overrides logged configuration.");
-DEFINE_bool(
-    plot_timing, true,
+ABSL_FLAG(std::string, config, "",
+          "If specified, overrides logged configuration.");
+ABSL_FLAG(
+    bool, plot_timing, true,
     "If set, generates a plot of the replay timing--namely, the errors between "
     "when we "
     "should've sent messages and when we actually sent replayed messages.");
-DEFINE_bool(skip_sender_channels, true,
-            "If set, skips replay of the channels applications replay on");
-DEFINE_bool(skip_replay, false,
-            "If set, skips actually running the replay. Useful for writing a "
-            "config without running replay");
-DEFINE_bool(
-    print_config, false,
+ABSL_FLAG(bool, skip_sender_channels, true,
+          "If set, skips replay of the channels applications replay on");
+ABSL_FLAG(bool, skip_replay, false,
+          "If set, skips actually running the replay. Useful for writing a "
+          "config without running replay");
+ABSL_FLAG(
+    bool, print_config, false,
     "If set, prints the config that will be used for replay to stdout as json");
-DEFINE_string(
-    replay_config, "",
+ABSL_FLAG(
+    std::string, replay_config, "",
     "Path to the configuration used for log replay which includes items such "
     "as channels to remap, and applications to target for replay. If not set, "
     "log_reader will run on shm event loop. ");
-DEFINE_string(merge_with_config, "",
-              "A valid json string to be merged with config. This is used to "
-              "add extra applications needed to run only for log_replayer");
-DEFINE_bool(print_stats, true,
-            "if set, prints the LogReplayerStats message as JSON to stdout");
+ABSL_FLAG(std::string, merge_with_config, "",
+          "A valid json string to be merged with config. This is used to "
+          "add extra applications needed to run only for log_replayer");
+ABSL_FLAG(bool, print_stats, true,
+          "if set, prints the LogReplayerStats message as JSON to stdout");
 
 namespace aos::logger {
 
@@ -61,11 +64,11 @@
 
   aos::logger::LogReader config_reader(logfiles);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      FLAGS_config.empty()
+      absl::GetFlag(FLAGS_config).empty()
           ? CopyFlatBuffer<aos::Configuration>(config_reader.configuration())
-          : aos::configuration::ReadConfig(FLAGS_config);
+          : aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
-  if (FLAGS_plot_timing) {
+  if (absl::GetFlag(FLAGS_plot_timing)) {
     // Go through the effort to add a ReplayTiming channel to ensure that we
     // can capture timing information from the replay.
     const aos::Configuration *raw_config = &config.message();
@@ -89,18 +92,19 @@
       aos::FlatbufferSpan<reflection::Schema>(aos::LogReplayerStatsSchema()),
       aos::configuration::GetMyNode(raw_config), channel_overrides);
 
-  if (!FLAGS_merge_with_config.empty()) {
-    config = aos::configuration::MergeWithConfig(&config.message(),
-                                                 FLAGS_merge_with_config);
+  if (!absl::GetFlag(FLAGS_merge_with_config).empty()) {
+    config = aos::configuration::MergeWithConfig(
+        &config.message(), absl::GetFlag(FLAGS_merge_with_config));
   }
 
   std::optional<aos::FlatbufferDetachedBuffer<ReplayConfig>> replay_config =
-      FLAGS_replay_config.empty()
+      absl::GetFlag(FLAGS_replay_config).empty()
           ? std::nullopt
           : std::make_optional(aos::JsonToFlatbuffer<ReplayConfig>(
-                aos::util::ReadFileToStringOrDie(FLAGS_replay_config.data())));
+                aos::util::ReadFileToStringOrDie(
+                    absl::GetFlag(FLAGS_replay_config).data())));
   std::vector<std::pair<std::string, std::string>> message_filter;
-  if (FLAGS_skip_sender_channels && replay_config.has_value()) {
+  if (absl::GetFlag(FLAGS_skip_sender_channels) && replay_config.has_value()) {
     CHECK(replay_config.value().message().has_active_nodes());
     std::vector<const Node *> active_nodes;
     for (const auto &node : *replay_config.value().message().active_nodes()) {
@@ -142,12 +146,12 @@
     }
   }
 
-  if (FLAGS_print_config) {
+  if (absl::GetFlag(FLAGS_print_config)) {
     // TODO(Naman): Replace with config writer if it will be cleaner
     std::cout << FlatbufferToJson(reader.configuration()) << std::endl;
   }
 
-  if (!FLAGS_skip_replay) {
+  if (!absl::GetFlag(FLAGS_skip_replay)) {
     aos::ShmEventLoop event_loop(reader.configuration());
 
     event_loop.SkipAosLog();
@@ -198,7 +202,7 @@
 
     reader.OnEnd(event_loop.node(), [&event_loop]() { event_loop.Exit(); });
 
-    if (FLAGS_plot_timing) {
+    if (absl::GetFlag(FLAGS_plot_timing)) {
       aos::Sender<aos::timing::ReplayTiming> replay_timing_sender =
           event_loop.MakeSender<aos::timing::ReplayTiming>("/timing");
       reader.set_timing_accuracy_sender(event_loop.node(),
@@ -209,7 +213,7 @@
 
     reader.Deregister();
 
-    if (FLAGS_print_stats) {
+    if (absl::GetFlag(FLAGS_print_stats)) {
       aos::Fetcher<aos::LogReplayerStats> stats_fetcher =
           event_loop.MakeFetcher<aos::LogReplayerStats>("/replay");
       CHECK(stats_fetcher.Fetch()) << "Failed to fetch LogReplayerStats!";
@@ -223,7 +227,7 @@
 }  // namespace aos::logger
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       R"message(Binary to replay the full contents of a logfile into shared memory.
                 #replay_config should be set in order to replay a set of nodes, applications and channels
                 #print config and skip replay, if you only want to print the config and not do log replay
diff --git a/aos/events/logging/log_stats.cc b/aos/events/logging/log_stats.cc
index a45a167..6e6efc9 100644
--- a/aos/events/logging/log_stats.cc
+++ b/aos/events/logging/log_stats.cc
@@ -2,8 +2,9 @@
 #include <iostream>
 #include <queue>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 #include "absl/strings/str_format.h"
-#include "gflags/gflags.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
@@ -11,23 +12,23 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/time/time.h"
 
-DEFINE_string(
-    name, "",
+ABSL_FLAG(
+    std::string, name, "",
     "Name to match for printing out channels. Empty means no name filter.");
 
-DEFINE_string(node, "", "Node to print stats out for.");
+ABSL_FLAG(std::string, node, "", "Node to print stats out for.");
 
-DEFINE_bool(excessive_size_only, false,
-            "Only print channels that have a set max message size that is more "
-            "than double of the max message size.");
+ABSL_FLAG(bool, excessive_size_only, false,
+          "Only print channels that have a set max message size that is more "
+          "than double of the max message size.");
 
-DEFINE_double(
-    run_for, 0.0,
+ABSL_FLAG(
+    double, run_for, 0.0,
     "If set to a positive value, only process the log for this many seconds. "
     "Otherwise, process the log until the end of the log.");
 
-DEFINE_bool(
-    print_repack_size_diffs, false,
+ABSL_FLAG(
+    bool, print_repack_size_diffs, false,
     "Analyze how many bytes could be saved in each message when converted to "
     "JSON and back. This can be helpful to identify code that is generating "
     "inefficiently packed flatbuffer messages.");
@@ -340,7 +341,7 @@
         continue;
       }
 
-      if (channel->name()->string_view().find(FLAGS_name) ==
+      if (channel->name()->string_view().find(absl::GetFlag(FLAGS_name)) ==
           std::string::npos) {
         continue;
       }
@@ -354,7 +355,7 @@
       auto watcher = [this, channel_stats_index](const aos::Context &context) {
         this->UpdateStats(context, channel_stats_index);
       };
-      if (FLAGS_print_repack_size_diffs) {
+      if (absl::GetFlag(FLAGS_print_repack_size_diffs)) {
         event_loop_->MakeRawWatcher(
             channel, std::bind(watcher, ::std::placeholders::_1));
       } else {
@@ -376,7 +377,7 @@
   void PrintStats() {
     // Print out the stats per channel and for the logfile.
     for (size_t i = 0; i != channel_stats_.size(); i++) {
-      if (!FLAGS_excessive_size_only ||
+      if (!absl::GetFlag(FLAGS_excessive_size_only) ||
           (channel_stats_[i].max_message_size() * 2) <
               static_cast<size_t>(channel_stats_[i].channel()->max_size())) {
         if (channel_stats_[i].total_num_messages() > 0) {
@@ -390,7 +391,7 @@
               std::max(logfile_stats_.logfile_end_time,
                        channel_stats_[i].channel_end_time());
 
-          if (!FLAGS_excessive_size_only) {
+          if (!absl::GetFlag(FLAGS_excessive_size_only)) {
             std::cout << "   " << channel_stats_[i].total_num_messages()
                       << " msgs, " << channel_stats_[i].avg_messages_per_sec()
                       << "hz avg, " << channel_stats_[i].max_messages_per_sec()
@@ -406,7 +407,7 @@
                     << channel_stats_[i].Percentile() << ", "
                     << channel_stats_[i].AvgLatency();
           std::cout << std::endl;
-          if (FLAGS_print_repack_size_diffs) {
+          if (absl::GetFlag(FLAGS_print_repack_size_diffs)) {
             std::cout << "   " << channel_stats_[i].avg_packed_size_reduction()
                       << " bytes packed reduction avg, "
                       << channel_stats_[i].max_packed_size_reduction()
@@ -441,7 +442,7 @@
 };
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Usage: \n"
       "  log_stats [args] logfile1 logfile2 ...\n"
       "This program provides statistics on a given log file. Supported "
@@ -470,7 +471,7 @@
   const aos::Node *node = nullptr;
 
   if (aos::configuration::MultiNode(reader.configuration())) {
-    if (FLAGS_node.empty()) {
+    if (absl::GetFlag(FLAGS_node).empty()) {
       LOG(INFO) << "Need a --node specified.  The log file has:";
       for (const aos::Node *node : reader.LoggedNodes()) {
         LOG(INFO) << "  " << node->name()->string_view();
@@ -478,7 +479,8 @@
       reader.Deregister();
       return 1;
     } else {
-      node = aos::configuration::GetNode(reader.configuration(), FLAGS_node);
+      node = aos::configuration::GetNode(reader.configuration(),
+                                         absl::GetFlag(FLAGS_node));
     }
   }
 
@@ -498,10 +500,10 @@
     log_stats_application = nullptr;
   });
 
-  if (FLAGS_run_for > 0.0) {
+  if (absl::GetFlag(FLAGS_run_for) > 0.0) {
     event_loop_factory.RunFor(
         std::chrono::duration_cast<std::chrono::nanoseconds>(
-            std::chrono::duration<double>(FLAGS_run_for)));
+            std::chrono::duration<double>(absl::GetFlag(FLAGS_run_for))));
   } else {
     event_loop_factory.Run();
   }
diff --git a/aos/events/logging/logfile_sorting.cc b/aos/events/logging/logfile_sorting.cc
index fdb4eab..756138c 100644
--- a/aos/events/logging/logfile_sorting.cc
+++ b/aos/events/logging/logfile_sorting.cc
@@ -9,6 +9,9 @@
 #include <vector>
 
 #include "absl/container/btree_map.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_join.h"
 
 #include "aos/containers/error_list.h"
@@ -24,8 +27,8 @@
 #include "aos/events/logging/s3_file_operations.h"
 #endif
 
-DEFINE_bool(quiet_sorting, false,
-            "If true, sort with minimal messages about truncated files.");
+ABSL_FLAG(bool, quiet_sorting, false,
+          "If true, sort with minimal messages about truncated files.");
 
 namespace aos::logger {
 namespace {
@@ -388,7 +391,7 @@
     std::optional<SizePrefixedFlatbufferVector<LogFileHeader>> log_header =
         ReadHeader(reader);
     if (!log_header) {
-      if (!FLAGS_quiet_sorting) {
+      if (!absl::GetFlag(FLAGS_quiet_sorting)) {
         LOG(WARNING) << "Skipping " << part.name << " without a header";
       }
       corrupted.emplace_back(part.name);
@@ -519,7 +522,7 @@
       std::optional<SizePrefixedFlatbufferVector<MessageHeader>> first_message =
           ReadNthMessage(part.name, 0);
       if (!first_message) {
-        if (!FLAGS_quiet_sorting) {
+        if (!absl::GetFlag(FLAGS_quiet_sorting)) {
           LOG(WARNING) << "Skipping " << part.name << " without any messages";
         }
         corrupted.emplace_back(part.name);
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index 0d10a99..f920681 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -9,10 +9,11 @@
 #include <climits>
 #include <filesystem>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/escaping.h"
 #include "flatbuffers/flatbuffers.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/snappy_encoder.h"
@@ -34,39 +35,38 @@
 #include "aos/events/logging/s3_fetcher.h"
 #endif
 
-DEFINE_int32(flush_size, 128 * 1024,
-             "Number of outstanding bytes to allow before flushing to disk.");
-DEFINE_double(
-    flush_period, 5.0,
-    "Max time to let data sit in the queue before flushing in seconds.");
+ABSL_FLAG(int32_t, flush_size, 128 * 1024,
+          "Number of outstanding bytes to allow before flushing to disk.");
+ABSL_FLAG(double, flush_period, 5.0,
+          "Max time to let data sit in the queue before flushing in seconds.");
 
-DEFINE_double(
-    max_network_delay, 1.0,
+ABSL_FLAG(
+    double, max_network_delay, 1.0,
     "Max time to assume a message takes to cross the network before we are "
     "willing to drop it from our buffers and assume it didn't make it.  "
     "Increasing this number can increase memory usage depending on the packet "
     "loss of your network or if the timestamps aren't logged for a message.");
 
-DEFINE_double(
-    max_out_of_order, -1,
+ABSL_FLAG(
+    double, max_out_of_order, -1,
     "If set, this overrides the max out of order duration for a log file.");
 
-DEFINE_bool(workaround_double_headers, true,
-            "Some old log files have two headers at the beginning.  Use the "
-            "last header as the actual header.");
+ABSL_FLAG(bool, workaround_double_headers, true,
+          "Some old log files have two headers at the beginning.  Use the "
+          "last header as the actual header.");
 
-DEFINE_bool(crash_on_corrupt_message, true,
-            "When true, MessageReader will crash the first time a message "
-            "with corrupted format is found. When false, the crash will be "
-            "suppressed, and any remaining readable messages will be "
-            "evaluated to present verified vs corrupted stats.");
+ABSL_FLAG(bool, crash_on_corrupt_message, true,
+          "When true, MessageReader will crash the first time a message "
+          "with corrupted format is found. When false, the crash will be "
+          "suppressed, and any remaining readable messages will be "
+          "evaluated to present verified vs corrupted stats.");
 
-DEFINE_bool(ignore_corrupt_messages, false,
-            "When true, and crash_on_corrupt_message is false, then any "
-            "corrupt message found by MessageReader be silently ignored, "
-            "providing access to all uncorrupted messages in a logfile.");
+ABSL_FLAG(bool, ignore_corrupt_messages, false,
+          "When true, and crash_on_corrupt_message is false, then any "
+          "corrupt message found by MessageReader be silently ignored, "
+          "providing access to all uncorrupted messages in a logfile.");
 
-DECLARE_bool(quiet_sorting);
+ABSL_DECLARE_FLAG(bool, quiet_sorting);
 
 namespace aos::logger {
 namespace {
@@ -280,11 +280,12 @@
   // point queueing up any more data in memory. Also flush once we have enough
   // data queued up or if it has been long enough.
   while (encoder_->space() == 0 ||
-         encoder_->queued_bytes() > static_cast<size_t>(FLAGS_flush_size) ||
+         encoder_->queued_bytes() >
+             static_cast<size_t>(absl::GetFlag(FLAGS_flush_size)) ||
          encoder_->queue_size() >= IOV_MAX ||
-         (now > last_flush_time_ +
-                    chrono::duration_cast<chrono::nanoseconds>(
-                        chrono::duration<double>(FLAGS_flush_period)) &&
+         (now > last_flush_time_ + chrono::duration_cast<chrono::nanoseconds>(
+                                       chrono::duration<double>(absl::GetFlag(
+                                           FLAGS_flush_period))) &&
           encoder_->queued_bytes() != 0)) {
     VLOG(1) << "Chose to flush at " << now << ", last " << last_flush_time_
             << " queued bytes " << encoder_->queued_bytes();
@@ -1140,7 +1141,7 @@
     part_readers_.clear();
   }
   if (log_source_ == nullptr) {
-    part_readers_.emplace_back(id, FLAGS_quiet_sorting);
+    part_readers_.emplace_back(id, absl::GetFlag(FLAGS_quiet_sorting));
   } else {
     part_readers_.emplace_back(id, log_source_->GetDecoder(id));
   }
@@ -1168,7 +1169,8 @@
   // way that it can't happen anymore.  We've seen some logs where the body
   // parses as a header recently, so the simple solution of always looking is
   // failing us.
-  if (FLAGS_workaround_double_headers && !result.message().has_logger_sha1()) {
+  if (absl::GetFlag(FLAGS_workaround_double_headers) &&
+      !result.message().has_logger_sha1()) {
     while (true) {
       absl::Span<const uint8_t> maybe_header_data = span_reader->PeekMessage();
       if (maybe_header_data.empty()) {
@@ -1227,8 +1229,10 @@
     : span_reader_(std::move(span_reader)),
       raw_log_file_header_(
           SizePrefixedFlatbufferVector<LogFileHeader>::Empty()) {
-  set_crash_on_corrupt_message_flag(FLAGS_crash_on_corrupt_message);
-  set_ignore_corrupt_messages_flag(FLAGS_ignore_corrupt_messages);
+  set_crash_on_corrupt_message_flag(
+      absl::GetFlag(FLAGS_crash_on_corrupt_message));
+  set_ignore_corrupt_messages_flag(
+      absl::GetFlag(FLAGS_ignore_corrupt_messages));
 
   std::optional<SizePrefixedFlatbufferVector<LogFileHeader>>
       raw_log_file_header = ReadHeader(&span_reader_);
@@ -1244,9 +1248,9 @@
   total_verified_before_ = span_reader_.TotalConsumed();
 
   max_out_of_order_duration_ =
-      FLAGS_max_out_of_order > 0
+      absl::GetFlag(FLAGS_max_out_of_order) > 0
           ? chrono::duration_cast<chrono::nanoseconds>(
-                chrono::duration<double>(FLAGS_max_out_of_order))
+                chrono::duration<double>(absl::GetFlag(FLAGS_max_out_of_order)))
           : chrono::nanoseconds(log_file_header()->max_out_of_order_duration());
 
   VLOG(1) << "Opened " << span_reader_.filename() << " as node "
@@ -2622,7 +2626,8 @@
                messages.begin()->timestamp +
                        node_data.channels[msg->channel_index].time_to_live +
                        chrono::duration_cast<chrono::nanoseconds>(
-                           chrono::duration<double>(FLAGS_max_network_delay)) <
+                           chrono::duration<double>(
+                               absl::GetFlag(FLAGS_max_network_delay))) <
                    last_popped_message_time_) {
           messages.pop_front();
         }
diff --git a/aos/events/logging/logfile_utils_out_of_space_test_runner.cc b/aos/events/logging/logfile_utils_out_of_space_test_runner.cc
index f6fb499..4247c12 100644
--- a/aos/events/logging/logfile_utils_out_of_space_test_runner.cc
+++ b/aos/events/logging/logfile_utils_out_of_space_test_runner.cc
@@ -2,19 +2,21 @@
 
 #include <array>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/logging/logfile_utils.h"
 #include "aos/init.h"
 
-DECLARE_int32(flush_size);
-DEFINE_string(tmpfs, "", "tmpfs with the desired size");
+ABSL_DECLARE_FLAG(int32_t, flush_size);
+ABSL_FLAG(std::string, tmpfs, "", "tmpfs with the desired size");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
-  FLAGS_flush_size = 1;
-  CHECK(!FLAGS_tmpfs.empty()) << ": Must specify a tmpfs location";
+  absl::SetFlag(&FLAGS_flush_size, 1);
+  CHECK(!absl::GetFlag(FLAGS_tmpfs).empty())
+      << ": Must specify a tmpfs location";
 
   std::array<uint8_t, 10240> data;
   data.fill(0);
@@ -22,7 +24,7 @@
   // Don't use odirect
   aos::logger::FileBackend file_backend("/", false);
   aos::logger::DetachedBufferWriter writer(
-      file_backend.RequestFile(FLAGS_tmpfs + "/file"),
+      file_backend.RequestFile(absl::GetFlag(FLAGS_tmpfs) + "/file"),
       std::make_unique<aos::logger::DummyEncoder>(data.size()));
   for (int i = 0; i < 8; ++i) {
     aos::logger::DataEncoder::SpanCopier coppier(data);
diff --git a/aos/events/logging/logfile_utils_test.cc b/aos/events/logging/logfile_utils_test.cc
index 87c6f5d..b97579a 100644
--- a/aos/events/logging/logfile_utils_test.cc
+++ b/aos/events/logging/logfile_utils_test.cc
@@ -5,11 +5,12 @@
 #include <random>
 #include <string>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
 #include "absl/strings/escaping.h"
 #include "external/com_github_google_flatbuffers/src/annotated_binary_text_gen.h"
 #include "external/com_github_google_flatbuffers/src/binary_annotator.h"
 #include "flatbuffers/reflection_generated.h"
-#include "gflags/gflags.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/logfile_sorting.h"
@@ -3094,7 +3095,7 @@
   }
 
   {
-    gflags::FlagSaver fs;
+    absl::FlagSaver fs;
 
     MessageReader reader(logfile);
     reader.set_crash_on_corrupt_message_flag(false);
@@ -3116,7 +3117,7 @@
   }
 
   {
-    gflags::FlagSaver fs;
+    absl::FlagSaver fs;
 
     MessageReader reader(logfile);
     reader.set_crash_on_corrupt_message_flag(false);
@@ -3239,6 +3240,30 @@
       std::mt19937(::aos::testing::RandomSeed())};
 
   std::vector<uint8_t> data_;
+
+  const aos::FlatbufferDetachedBuffer<Configuration> config_{
+      JsonToFlatbuffer<Configuration>(
+          R"({
+  "channels": [
+    {
+      "name": "/a",
+      "type": "aos.logger.testing.TestMessage"
+    },
+    {
+      "name": "/b",
+      "type": "aos.logger.testing.TestMessage"
+    },
+    {
+      "name": "/c",
+      "type": "aos.logger.testing.TestMessage"
+    },
+    {
+      "name": "/d",
+      "type": "aos.logger.testing.TestMessage"
+    }
+  ]
+}
+)")};
 };
 
 // Uses the binary schema to annotate a provided flatbuffer.  Returns the
@@ -3268,7 +3293,7 @@
 // tested below.
 class TimeEventLoop : public EventLoop {
  public:
-  TimeEventLoop() : EventLoop(nullptr) {}
+  TimeEventLoop(const aos::Configuration *config) : EventLoop(config) {}
 
   aos::monotonic_clock::time_point monotonic_now() const final {
     return aos::monotonic_clock::min_time;
@@ -3403,7 +3428,7 @@
 
       // Ok, now we want to confirm that we can build up arbitrary pieces of
       // said flatbuffer.  Try all of them since it is cheap.
-      TimeEventLoop event_loop;
+      TimeEventLoop event_loop(&config_.message());
       for (size_t i = 0; i < repacked_message.size(); i += 8) {
         for (size_t j = i; j < repacked_message.size(); j += 8) {
           std::vector<uint8_t> destination(repacked_message.size(), 67u);
@@ -3475,7 +3500,7 @@
 
     // Ok, now we want to confirm that we can build up arbitrary pieces of said
     // flatbuffer.  Try all of them since it is cheap.
-    TimeEventLoop event_loop;
+    TimeEventLoop event_loop(&config_.message());
     for (size_t i = 0; i < repacked_message.size(); i += 8) {
       for (size_t j = i; j < repacked_message.size(); j += 8) {
         std::vector<uint8_t> destination(repacked_message.size(), 67u);
diff --git a/aos/events/logging/logger_main.cc b/aos/events/logging/logger_main.cc
index f99fe4c..73b6694 100644
--- a/aos/events/logging/logger_main.cc
+++ b/aos/events/logging/logger_main.cc
@@ -6,41 +6,45 @@
 #ifdef LZMA
 #include "aos/events/logging/lzma_encoder.h"
 #endif
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/logging/snappy_encoder.h"
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/logging/log_namer.h"
 
-DEFINE_bool(direct, false,
-            "If true, write using O_DIRECT and write 512 byte aligned blocks "
-            "whenever possible.");
+ABSL_FLAG(bool, direct, false,
+          "If true, write using O_DIRECT and write 512 byte aligned blocks "
+          "whenever possible.");
 
-DEFINE_string(config, "aos_config.json", "Config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the logger.  This leaves it lower priority "
-            "and increases the likelihood of dropping messages and crashing.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the logger.  This leaves it lower priority "
+          "and increases the likelihood of dropping messages and crashing.");
 
-DEFINE_bool(snappy_compress, false, "If true, compress log data using snappy.");
+ABSL_FLAG(bool, snappy_compress, false,
+          "If true, compress log data using snappy.");
 
 #ifdef LZMA
-DEFINE_bool(xz_compress, false, "If true, compress log data using xz.");
+ABSL_FLAG(bool, xz_compress, false, "If true, compress log data using xz.");
 #endif
 
-DEFINE_double(rotate_every, 0.0,
-              "If set, rotate the logger after this many seconds");
+ABSL_FLAG(double, rotate_every, 0.0,
+          "If set, rotate the logger after this many seconds");
 
 #ifdef LZMA
-DEFINE_int32(xz_compression_level, 9, "Compression level for the LZMA Encoder");
+ABSL_FLAG(int32_t, xz_compression_level, 9,
+          "Compression level for the LZMA Encoder");
 #endif
 
-DECLARE_int32(flush_size);
+ABSL_DECLARE_FLAG(int32_t, flush_size);
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "This program provides a simple logger binary that logs all SHMEM data "
       "directly to a file specified at the command line. It does not manage "
       "filenames, so it will just crash if you attempt to overwrite an "
@@ -49,27 +53,28 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
   auto log_namer = std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
       &event_loop, std::make_unique<aos::logger::RenamableFileBackend>(
                        absl::StrCat(aos::logging::GetLogName("fbs_log"), "/"),
-                       FLAGS_direct));
+                       absl::GetFlag(FLAGS_direct)));
 
-  if (FLAGS_snappy_compress) {
+  if (absl::GetFlag(FLAGS_snappy_compress)) {
     log_namer->set_extension(aos::logger::SnappyDecoder::kExtension);
     log_namer->set_encoder_factory([](size_t max_message_size) {
-      return std::make_unique<aos::logger::SnappyEncoder>(max_message_size,
-                                                          FLAGS_flush_size);
+      return std::make_unique<aos::logger::SnappyEncoder>(
+          max_message_size, absl::GetFlag(FLAGS_flush_size));
     });
 #ifdef LZMA
-  } else if (FLAGS_xz_compress) {
+  } else if (absl::GetFlag(FLAGS_xz_compress)) {
     log_namer->set_extension(aos::logger::LzmaEncoder::kExtension);
     log_namer->set_encoder_factory([](size_t max_message_size) {
       return std::make_unique<aos::logger::LzmaEncoder>(
-          max_message_size, FLAGS_xz_compression_level, FLAGS_flush_size);
+          max_message_size, absl::GetFlag(FLAGS_xz_compression_level),
+          absl::GetFlag(FLAGS_flush_size));
     });
 #endif
   }
@@ -78,10 +83,10 @@
       event_loop.monotonic_now();
   aos::logger::Logger logger(&event_loop);
 
-  if (FLAGS_rotate_every != 0.0) {
+  if (absl::GetFlag(FLAGS_rotate_every) != 0.0) {
     logger.set_on_logged_period([&](aos::monotonic_clock::time_point t) {
-      if (t > last_rotation_time +
-                  std::chrono::duration<double>(FLAGS_rotate_every)) {
+      if (t > last_rotation_time + std::chrono::duration<double>(
+                                       absl::GetFlag(FLAGS_rotate_every))) {
         logger.Rotate();
         last_rotation_time = t;
       }
@@ -89,7 +94,7 @@
   }
 
   event_loop.OnRun([&log_namer, &logger]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/aos/events/logging/logger_test.cc b/aos/events/logging/logger_test.cc
index c810203..bf5e414 100644
--- a/aos/events/logging/logger_test.cc
+++ b/aos/events/logging/logger_test.cc
@@ -2,8 +2,9 @@
 
 #include <filesystem>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/aos/events/logging/lzma_encoder.cc b/aos/events/logging/lzma_encoder.cc
index 5e9fa7a..f4a075a 100644
--- a/aos/events/logging/lzma_encoder.cc
+++ b/aos/events/logging/lzma_encoder.cc
@@ -1,8 +1,10 @@
 #include "aos/events/logging/lzma_encoder.h"
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
-DEFINE_int32(lzma_threads, 1, "Number of threads to use for encoding");
+ABSL_FLAG(int32_t, lzma_threads, 1, "Number of threads to use for encoding");
 
 namespace aos::logger {
 namespace {
@@ -58,14 +60,14 @@
   CHECK_LE(compression_preset_, 9u)
       << ": Compression preset must be in the range [0, 9].";
 
-  if (FLAGS_lzma_threads <= 1) {
+  if (absl::GetFlag(FLAGS_lzma_threads) <= 1) {
     lzma_ret status =
         lzma_easy_encoder(&stream_, compression_preset_, LZMA_CHECK_CRC64);
     CHECK(LzmaCodeIsOk(status));
   } else {
     lzma_mt mt_options;
     memset(&mt_options, 0, sizeof(mt_options));
-    mt_options.threads = FLAGS_lzma_threads;
+    mt_options.threads = absl::GetFlag(FLAGS_lzma_threads);
     mt_options.block_size = block_size;
     // Compress for at most 100 ms before relinquishing control back to the main
     // thread.
diff --git a/aos/events/logging/lzma_encoder_test.cc b/aos/events/logging/lzma_encoder_test.cc
index 92b4f54..2eb1281 100644
--- a/aos/events/logging/lzma_encoder_test.cc
+++ b/aos/events/logging/lzma_encoder_test.cc
@@ -1,5 +1,7 @@
 #include "aos/events/logging/lzma_encoder.h"
 
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -7,14 +9,14 @@
 #include "aos/testing/tmpdir.h"
 #include "aos/util/file.h"
 
-DECLARE_int32(lzma_threads);
+ABSL_DECLARE_FLAG(int32_t, lzma_threads);
 
 namespace aos::logger::testing {
 
 INSTANTIATE_TEST_SUITE_P(
     MtLzma, BufferEncoderTest,
     ::testing::Combine(::testing::Values([](size_t max_message_size) {
-                         FLAGS_lzma_threads = 3;
+                         absl::SetFlag(&FLAGS_lzma_threads, 3);
                          return std::make_unique<LzmaEncoder>(max_message_size,
                                                               2, 4096);
                        }),
@@ -26,7 +28,7 @@
 INSTANTIATE_TEST_SUITE_P(
     MtLzmaThreaded, BufferEncoderTest,
     ::testing::Combine(::testing::Values([](size_t max_message_size) {
-                         FLAGS_lzma_threads = 3;
+                         absl::SetFlag(&FLAGS_lzma_threads, 3);
                          return std::make_unique<LzmaEncoder>(max_message_size,
                                                               5, 4096);
                        }),
@@ -38,7 +40,7 @@
 INSTANTIATE_TEST_SUITE_P(
     Lzma, BufferEncoderTest,
     ::testing::Combine(::testing::Values([](size_t max_message_size) {
-                         FLAGS_lzma_threads = 1;
+                         absl::SetFlag(&FLAGS_lzma_threads, 1);
                          return std::make_unique<LzmaEncoder>(max_message_size,
                                                               2, 4096);
                        }),
@@ -50,7 +52,7 @@
 INSTANTIATE_TEST_SUITE_P(
     LzmaThreaded, BufferEncoderTest,
     ::testing::Combine(::testing::Values([](size_t max_message_size) {
-                         FLAGS_lzma_threads = 1;
+                         absl::SetFlag(&FLAGS_lzma_threads, 1);
                          return std::make_unique<LzmaEncoder>(max_message_size,
                                                               5, 4096);
                        }),
diff --git a/aos/events/logging/multinode_logger_test_lib.cc b/aos/events/logging/multinode_logger_test_lib.cc
index 3bf6207..b48f78a 100644
--- a/aos/events/logging/multinode_logger_test_lib.cc
+++ b/aos/events/logging/multinode_logger_test_lib.cc
@@ -1,5 +1,9 @@
 #include "aos/events/logging/multinode_logger_test_lib.h"
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
+
 #include "aos/events/event_loop.h"
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/logfile_utils.h"
@@ -9,7 +13,7 @@
 #include "aos/events/simulated_event_loop.h"
 #include "aos/testing/tmpdir.h"
 
-DECLARE_bool(force_timestamp_loading);
+ABSL_DECLARE_FLAG(bool, force_timestamp_loading);
 
 namespace aos::logger::testing {
 
@@ -111,9 +115,9 @@
       pi1_reboot_logfiles_(MakePi1RebootLogfiles()),
       logfiles_(MakeLogFiles(logfile_base1_, logfile_base2_)),
       structured_logfiles_(StructureLogFiles()) {
-  FLAGS_force_timestamp_loading =
-      std::get<0>(GetParam()).timestamp_buffering ==
-      ForceTimestampBuffering::kForceBufferTimestamps;
+  absl::SetFlag(&FLAGS_force_timestamp_loading,
+                std::get<0>(GetParam()).timestamp_buffering ==
+                    ForceTimestampBuffering::kForceBufferTimestamps);
 
   util::UnlinkRecursive(tmp_dir_ + "/logs");
   std::filesystem::create_directory(tmp_dir_ + "/logs");
diff --git a/aos/events/logging/multinode_logger_test_lib.h b/aos/events/logging/multinode_logger_test_lib.h
index 3c71632..386339d 100644
--- a/aos/events/logging/multinode_logger_test_lib.h
+++ b/aos/events/logging/multinode_logger_test_lib.h
@@ -1,8 +1,8 @@
 #ifndef AOS_EVENTS_LOGGING_MULTINODE_LOGGER_TEST_LIB_H
 #define AOS_EVENTS_LOGGING_MULTINODE_LOGGER_TEST_LIB_H
 
+#include "absl/flags/reflection.h"
 #include "absl/strings/str_format.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 
 #include "aos/events/event_loop.h"
@@ -172,7 +172,7 @@
 
   void AddExtension(std::string_view extension);
 
-  gflags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
 
   // Config and factory.
   aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
diff --git a/aos/events/logging/realtime_replay_test.cc b/aos/events/logging/realtime_replay_test.cc
index dd4aaf0..7db9442 100644
--- a/aos/events/logging/realtime_replay_test.cc
+++ b/aos/events/logging/realtime_replay_test.cc
@@ -9,15 +9,14 @@
 #include "aos/testing/path.h"
 #include "aos/testing/tmpdir.h"
 
-DECLARE_string(override_hostname);
+ABSL_DECLARE_FLAG(std::string, override_hostname);
 
 namespace aos::logger::testing {
 
 class RealtimeLoggerTest : public ::testing::Test {
  protected:
   RealtimeLoggerTest()
-      : shm_dir_(aos::testing::TestTmpDir() + "/aos"),
-        config_file_(
+      : config_file_(
             aos::testing::ArtifactPath("aos/events/pingpong_config.json")),
         config_(aos::configuration::ReadConfig(config_file_)),
         event_loop_factory_(&config_.message()),
@@ -27,17 +26,12 @@
         pong_(pong_event_loop_.get()),
         tmpdir_(aos::testing::TestTmpDir()),
         base_name_(tmpdir_ + "/logfile/") {
-    FLAGS_shm_base = shm_dir_;
-
     // Nuke the shm and log dirs, to ensure we aren't being affected by any
     // preexisting tests.
-    aos::util::UnlinkRecursive(shm_dir_);
+    aos::util::UnlinkRecursive(absl::GetFlag(FLAGS_shm_base));
     aos::util::UnlinkRecursive(base_name_);
   }
 
-  gflags::FlagSaver flag_saver_;
-  std::string shm_dir_;
-
   const std::string config_file_;
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
 
@@ -54,8 +48,7 @@
 class RealtimeMultiNodeLoggerTest : public ::testing::Test {
  protected:
   RealtimeMultiNodeLoggerTest()
-      : shm_dir_(aos::testing::TestTmpDir() + "/aos"),
-        config_file_(aos::testing::ArtifactPath(
+      : config_file_(aos::testing::ArtifactPath(
             "aos/events/logging/multinode_pingpong_combined_config.json")),
         config_(aos::configuration::ReadConfig(config_file_)),
         event_loop_factory_(&config_.message()),
@@ -64,17 +57,12 @@
         ping_(ping_event_loop_.get()),
         tmpdir_(aos::testing::TestTmpDir()),
         base_name_(tmpdir_ + "/logfile/") {
-    FLAGS_shm_base = shm_dir_;
-
     // Nuke the shm and log dirs, to ensure we aren't being affected by any
     // preexisting tests.
-    aos::util::UnlinkRecursive(shm_dir_);
+    aos::util::UnlinkRecursive(absl::GetFlag(FLAGS_shm_base));
     aos::util::UnlinkRecursive(base_name_);
   }
 
-  gflags::FlagSaver flag_saver_;
-  std::string shm_dir_;
-
   const std::string config_file_;
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
 
@@ -178,7 +166,7 @@
 // Tests that ReplayChannels causes no messages to be replayed other than what
 // is included on a multi node config
 TEST_F(RealtimeMultiNodeLoggerTest, ReplayChannelsPingTest) {
-  FLAGS_override_hostname = "raspberrypi";
+  absl::SetFlag(&FLAGS_override_hostname, "raspberrypi");
   {
     std::unique_ptr<EventLoop> logger_event_loop =
         event_loop_factory_.MakeEventLoop(
@@ -223,7 +211,7 @@
 // Tests that when remapping a channel included in ReplayChannels messages are
 // sent on the remapped channel
 TEST_F(RealtimeMultiNodeLoggerTest, RemappedReplayChannelsTest) {
-  FLAGS_override_hostname = "raspberrypi";
+  absl::SetFlag(&FLAGS_override_hostname, "raspberrypi");
   {
     std::unique_ptr<EventLoop> logger_event_loop =
         event_loop_factory_.MakeEventLoop(
@@ -275,7 +263,7 @@
 // exist in the log being replayed, and there's no messages on those
 // channels as well.
 TEST_F(RealtimeMultiNodeLoggerTest, DoesNotExistInReplayChannelsTest) {
-  FLAGS_override_hostname = "raspberrypi";
+  absl::SetFlag(&FLAGS_override_hostname, "raspberrypi");
   {
     std::unique_ptr<EventLoop> logger_event_loop =
         event_loop_factory_.MakeEventLoop(
@@ -335,7 +323,7 @@
 // the channel being remapped.
 TEST_F(RealtimeMultiNodeLoggerDeathTest,
        RemapLoggedChannelNotIncludedInReplayChannels) {
-  FLAGS_override_hostname = "raspberrypi";
+  absl::SetFlag(&FLAGS_override_hostname, "raspberrypi");
   {
     std::unique_ptr<EventLoop> logger_event_loop =
         event_loop_factory_.MakeEventLoop(
diff --git a/aos/events/logging/s3_fetcher.cc b/aos/events/logging/s3_fetcher.cc
index 4207286..557c3da 100644
--- a/aos/events/logging/s3_fetcher.cc
+++ b/aos/events/logging/s3_fetcher.cc
@@ -3,8 +3,9 @@
 #include <aws/core/Aws.h>
 #include <aws/s3/model/ListObjectsV2Request.h>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
-#include "glog/logging.h"
 
 // When we first start reading a log folder, we end up reading the first part of
 // each file twice. We could speed this up by restructuring the API so all the
diff --git a/aos/events/logging/single_node_merge.cc b/aos/events/logging/single_node_merge.cc
index a34e4c2..01eeb6b 100644
--- a/aos/events/logging/single_node_merge.cc
+++ b/aos/events/logging/single_node_merge.cc
@@ -2,7 +2,7 @@
 #include <string>
 #include <vector>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/logfile_sorting.h"
 #include "aos/events/logging/logfile_utils.h"
@@ -13,7 +13,7 @@
 // log.  It doesn't solve the timestamp problem, but is still quite useful for
 // debugging what happened in a log.
 
-DEFINE_string(node, "", "The node to dump sorted messages for");
+ABSL_FLAG(std::string, node, "", "The node to dump sorted messages for");
 
 namespace aos::logger {
 
@@ -39,7 +39,7 @@
       // Filter the parts relevant to each node when building the mapper.
       mappers.emplace_back(std::make_unique<TimestampMapper>(
           node_name, log_files, TimestampQueueStrategy::kQueueTogether));
-      if (node_name == FLAGS_node) {
+      if (node_name == absl::GetFlag(FLAGS_node)) {
         node_mapper = mappers.back().get();
       }
     } else {
@@ -47,7 +47,8 @@
     }
   }
 
-  CHECK(node_mapper != nullptr) << ": Failed to find node " << FLAGS_node;
+  CHECK(node_mapper != nullptr)
+      << ": Failed to find node " << absl::GetFlag(FLAGS_node);
 
   // Hook the peers up so data gets matched.
   for (std::unique_ptr<TimestampMapper> &mapper1 : mappers) {
@@ -61,7 +62,7 @@
   // Now, read all the timestamps for each node.  This is simpler than the
   // logger on purpose.  It loads in *all* the timestamps in 1 go per node,
   // ignoring memory usage.
-  const Node *node = configuration::GetNode(config, FLAGS_node);
+  const Node *node = configuration::GetNode(config, absl::GetFlag(FLAGS_node));
 
   LOG(INFO) << "Reading all data for " << node->name()->string_view();
   const size_t node_index = configuration::GetNodeIndex(config, node);
@@ -74,7 +75,7 @@
     if (m == nullptr) {
       break;
     }
-    std::cout << "on " << FLAGS_node << " from "
+    std::cout << "on " << absl::GetFlag(FLAGS_node) << " from "
               << config->nodes()
                      ->Get(configuration::GetNodeIndex(
                          config, config->channels()
diff --git a/aos/events/logging/ssd_profiler.cc b/aos/events/logging/ssd_profiler.cc
index 093e17b..034ac28 100644
--- a/aos/events/logging/ssd_profiler.cc
+++ b/aos/events/logging/ssd_profiler.cc
@@ -8,8 +8,9 @@
 #include <csignal>
 #include <filesystem>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/containers/resizeable_buffer.h"
 #include "aos/events/logging/log_backend.h"
@@ -19,33 +20,34 @@
 
 namespace chrono = std::chrono;
 
-DEFINE_string(file, "/media/sda1/foo", "File to write to.");
+ABSL_FLAG(std::string, file, "/media/sda1/foo", "File to write to.");
 
-DEFINE_uint32(write_size, 4096, "Size of hunk to write");
-DEFINE_bool(cleanup, true, "If true, delete the created file");
-DEFINE_int32(nice, -20,
-             "Priority to nice to. Set to 0 to not change the priority.");
-DEFINE_bool(sync, false, "If true, sync the file after each written block.");
-DEFINE_bool(writev, false, "If true, use writev.");
-DEFINE_bool(direct, false, "If true, O_DIRECT.");
-DEFINE_uint32(chunks, 1, "Chunks to write using writev.");
-DEFINE_uint32(chunk_size, 512, "Chunk size to write using writev.");
-DEFINE_uint64(overall_size, 0,
-              "If nonzero, write this many bytes and then stop.  Must be a "
-              "multiple of --write_size");
-DEFINE_bool(rate_limit, false,
-            "If true, kick off writes every 100ms to mimic logger write "
-            "patterns more correctly.");
-DEFINE_double(write_bandwidth, 120.0,
-              "Write speed in MB/s to simulate. This is only used when "
-              "--rate_limit is specified.");
+ABSL_FLAG(uint32_t, write_size, 4096, "Size of hunk to write");
+ABSL_FLAG(bool, cleanup, true, "If true, delete the created file");
+ABSL_FLAG(int32_t, nice, -20,
+          "Priority to nice to. Set to 0 to not change the priority.");
+ABSL_FLAG(bool, sync, false,
+          "If true, sync the file after each written block.");
+ABSL_FLAG(bool, writev, false, "If true, use writev.");
+ABSL_FLAG(bool, direct, false, "If true, O_DIRECT.");
+ABSL_FLAG(uint32_t, chunks, 1, "Chunks to write using writev.");
+ABSL_FLAG(uint32_t, chunk_size, 512, "Chunk size to write using writev.");
+ABSL_FLAG(uint64_t, overall_size, 0,
+          "If nonzero, write this many bytes and then stop.  Must be a "
+          "multiple of --write_size");
+ABSL_FLAG(bool, rate_limit, false,
+          "If true, kick off writes every 100ms to mimic logger write "
+          "patterns more correctly.");
+ABSL_FLAG(double, write_bandwidth, 120.0,
+          "Write speed in MB/s to simulate. This is only used when "
+          "--rate_limit is specified.");
 
 void trap_sig(int signum) { exit(signum); }
 
 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::min_time;
 std::atomic<size_t> written_data = 0;
 
-void cleanup() {
+void Cleanup() {
   LOG(INFO) << "Overall average write speed: "
             << ((written_data) /
                 chrono::duration<double>(aos::monotonic_clock::now() -
@@ -56,19 +58,20 @@
             << "MB";
 
   // Delete FLAGS_file at shutdown
-  PCHECK(std::filesystem::remove(FLAGS_file) != 0) << "Failed to cleanup file";
+  PCHECK(std::filesystem::remove(absl::GetFlag(FLAGS_file)) != 0)
+      << "Failed to cleanup file";
 }
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   // c++ needs bash's trap <fcn> EXIT
   // instead we get this mess :(
-  if (FLAGS_cleanup) {
+  if (absl::GetFlag(FLAGS_cleanup)) {
     std::signal(SIGINT, trap_sig);
     std::signal(SIGTERM, trap_sig);
     std::signal(SIGKILL, trap_sig);
     std::signal(SIGHUP, trap_sig);
-    std::atexit(cleanup);
+    std::atexit(Cleanup);
   }
   aos::AllocatorResizeableBuffer<
       aos::AlignedReallocator<aos::logger::FileHandler::kSector>>
@@ -79,7 +82,7 @@
     // good sized block from /dev/random, and then reuse it.
     int random_fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
     PCHECK(random_fd != -1) << ": Failed to open /dev/random";
-    data.resize(FLAGS_write_size);
+    data.resize(absl::GetFlag(FLAGS_write_size));
     size_t written = 0;
     while (written < data.size()) {
       const size_t result =
@@ -92,23 +95,24 @@
   }
 
   std::vector<struct iovec> iovec;
-  if (FLAGS_writev) {
-    iovec.resize(FLAGS_chunks);
-    CHECK_LE(FLAGS_chunks * FLAGS_chunk_size, FLAGS_write_size);
+  if (absl::GetFlag(FLAGS_writev)) {
+    const size_t chunks = absl::GetFlag(FLAGS_chunks);
+    const size_t chunk_size = absl::GetFlag(FLAGS_chunk_size);
+    iovec.resize(chunks);
+    CHECK_LE(chunks * chunk_size, absl::GetFlag(FLAGS_write_size));
 
-    for (size_t i = 0; i < FLAGS_chunks; ++i) {
-      iovec[i].iov_base = &data.at(i * FLAGS_chunk_size);
-      iovec[i].iov_len = FLAGS_chunk_size;
+    for (size_t i = 0; i < chunks; ++i) {
+      iovec[i].iov_base = &data.at(i * chunk_size);
+      iovec[i].iov_len = chunk_size;
     }
-    iovec[FLAGS_chunks - 1].iov_base =
-        &data.at((FLAGS_chunks - 1) * FLAGS_chunk_size);
-    iovec[FLAGS_chunks - 1].iov_len =
-        data.size() - (FLAGS_chunks - 1) * FLAGS_chunk_size;
+    iovec[chunks - 1].iov_base = &data.at((chunks - 1) * chunk_size);
+    iovec[chunks - 1].iov_len = data.size() - (chunks - 1) * chunk_size;
   }
 
-  int fd =
-      open(FLAGS_file.c_str(),
-           O_RDWR | O_CLOEXEC | O_CREAT | (FLAGS_direct ? O_DIRECT : 0), 0774);
+  int fd = open(absl::GetFlag(FLAGS_file).c_str(),
+                O_RDWR | O_CLOEXEC | O_CREAT |
+                    (absl::GetFlag(FLAGS_direct) ? O_DIRECT : 0),
+                0774);
   PCHECK(fd != -1);
 
   start_time = aos::monotonic_clock::now();
@@ -121,23 +125,24 @@
   // want to write it in cycles of 100ms to simulate the logger.
   size_t cycle_written_data = 0;
   size_t data_per_cycle = std::numeric_limits<size_t>::max();
-  if (FLAGS_rate_limit) {
-    data_per_cycle =
-        static_cast<size_t>((FLAGS_write_bandwidth * 1024 * 1024) / 10);
+  if (absl::GetFlag(FLAGS_rate_limit)) {
+    data_per_cycle = static_cast<size_t>(
+        (absl::GetFlag(FLAGS_write_bandwidth) * 1024 * 1024) / 10);
   }
 
-  if (FLAGS_nice != 0) {
-    PCHECK(-1 != setpriority(PRIO_PROCESS, 0, FLAGS_nice))
-        << ": Renicing to " << FLAGS_nice << " failed";
+  if (absl::GetFlag(FLAGS_nice) != 0) {
+    PCHECK(-1 != setpriority(PRIO_PROCESS, 0, absl::GetFlag(FLAGS_nice)))
+        << ": Renicing to " << absl::GetFlag(FLAGS_nice) << " failed";
   }
 
   while (true) {
     // Bail if we have written our limit.
-    if (written_data >= FLAGS_overall_size && FLAGS_overall_size != 0) {
+    if (written_data >= absl::GetFlag(FLAGS_overall_size) &&
+        absl::GetFlag(FLAGS_overall_size) != 0) {
       break;
     }
 
-    if (FLAGS_writev) {
+    if (absl::GetFlag(FLAGS_writev)) {
       PCHECK(writev(fd, iovec.data(), iovec.size()) ==
              static_cast<ssize_t>(data.size()))
           << ": Failed after "
@@ -152,7 +157,7 @@
     }
 
     // Trigger a flush if asked.
-    if (FLAGS_sync) {
+    if (absl::GetFlag(FLAGS_sync)) {
       const aos::monotonic_clock::time_point monotonic_now =
           aos::monotonic_clock::now();
       sync_file_range(fd, written_data, data.size(), SYNC_FILE_RANGE_WRITE);
@@ -178,11 +183,12 @@
     // Simulate the logger by writing the specified amount of data in periods of
     // 100ms.
     bool reset_cycle = false;
-    if (cycle_written_data > data_per_cycle && FLAGS_rate_limit) {
+    if (cycle_written_data > data_per_cycle &&
+        absl::GetFlag(FLAGS_rate_limit)) {
       // Check how much data we should have already written based on
       // --write_bandwidth.
       const size_t current_target =
-          FLAGS_write_bandwidth * 1024 * 1024 *
+          absl::GetFlag(FLAGS_write_bandwidth) * 1024 * 1024 *
           chrono::duration<double>(aos::monotonic_clock::now() - start_time)
               .count();
       const bool caught_up = written_data > current_target;
diff --git a/aos/events/logging/timestamp_extractor.cc b/aos/events/logging/timestamp_extractor.cc
index 3cf96f6..00555d8 100644
--- a/aos/events/logging/timestamp_extractor.cc
+++ b/aos/events/logging/timestamp_extractor.cc
@@ -2,30 +2,32 @@
 #include <string>
 #include <vector>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 
 #include "aos/events/logging/logfile_sorting.h"
 #include "aos/events/logging/logfile_utils.h"
 #include "aos/events/logging/logfile_validator.h"
 #include "aos/init.h"
 
-DECLARE_bool(timestamps_to_csv);
-DEFINE_bool(skip_order_validation, false,
-            "If true, ignore any out of orderness in replay");
+ABSL_DECLARE_FLAG(bool, timestamps_to_csv);
+ABSL_FLAG(bool, skip_order_validation, false,
+          "If true, ignore any out of orderness in replay");
 
 namespace aos::logger {
 
 int Main(int argc, char **argv) {
   const LogFilesContainer log_files(SortParts(FindLogs(argc, argv)));
-  CHECK(MultiNodeLogIsReadable(log_files, FLAGS_skip_order_validation));
+  CHECK(MultiNodeLogIsReadable(log_files,
+                               absl::GetFlag(FLAGS_skip_order_validation)));
   return 0;
 }
 
 }  // namespace aos::logger
 
 int main(int argc, char **argv) {
-  FLAGS_timestamps_to_csv = true;
-  gflags::SetUsageMessage(
+  absl::SetFlag(&FLAGS_timestamps_to_csv, true);
+  absl::SetProgramUsageMessage(
       "Usage:\n"
       "  timestamp_extractor [args] logfile1 logfile2 ...\n\nThis program "
       "dumps out all the timestamps from a set of log files for plotting.  Use "
diff --git a/aos/events/logging/timestamp_plot.cc b/aos/events/logging/timestamp_plot.cc
index 5b5cdc2..82e8031 100644
--- a/aos/events/logging/timestamp_plot.cc
+++ b/aos/events/logging/timestamp_plot.cc
@@ -1,3 +1,4 @@
+#include "absl/flags/flag.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_split.h"
 
@@ -7,13 +8,13 @@
 
 using aos::analysis::Plotter;
 
-DEFINE_bool(all, false, "If true, plot *all* the nodes at once");
-DEFINE_bool(bounds, false, "If true, plot the noncausal bounds too.");
-DEFINE_bool(samples, true, "If true, plot the samples too.");
+ABSL_FLAG(bool, all, false, "If true, plot *all* the nodes at once");
+ABSL_FLAG(bool, bounds, false, "If true, plot the noncausal bounds too.");
+ABSL_FLAG(bool, samples, true, "If true, plot the samples too.");
 
-DEFINE_string(offsets, "",
-              "Offsets to add to the monotonic clock for each node.  Use the "
-              "format of node=offset,node=offest");
+ABSL_FLAG(std::string, offsets, "",
+          "Offsets to add to the monotonic clock for each node.  Use the "
+          "format of node=offset,node=offest");
 
 // Simple C++ application to read the CSV files and use the in process plotter
 // to plot them.  This smokes the pants off gnuplot in terms of interactivity.
@@ -112,8 +113,9 @@
  public:
   NodePlotter() : nodes_(Nodes()) {
     plotter_.AddFigure("Time");
-    if (!FLAGS_offsets.empty()) {
-      for (std::string_view nodeoffset : absl::StrSplit(FLAGS_offsets, ',')) {
+    if (!absl::GetFlag(FLAGS_offsets).empty()) {
+      for (std::string_view nodeoffset :
+           absl::StrSplit(absl::GetFlag(FLAGS_offsets), ',')) {
         std::vector<std::string_view> node_offset =
             absl::StrSplit(nodeoffset, '=');
         CHECK_EQ(node_offset.size(), 2u);
@@ -284,7 +286,7 @@
                        .color = "yellow",
                        .point_size = 2.0});
 
-  if (FLAGS_samples) {
+  if (absl::GetFlag(FLAGS_samples)) {
     plotter_.AddLine(samplefile12.first, samplefile12.second,
                      Plotter::LineOptions{
                          .label = absl::StrCat("sample ", node1, " ", node2),
@@ -299,7 +301,7 @@
                      });
   }
 
-  if (FLAGS_bounds) {
+  if (absl::GetFlag(FLAGS_bounds)) {
     plotter_.AddLine(
         noncausalfile12.first, noncausalfile12.second,
         Plotter::LineOptions{.label = absl::StrCat("nc ", node1, " ", node2),
@@ -316,7 +318,7 @@
 int Main(int argc, const char *const *argv) {
   NodePlotter plotter;
 
-  if (FLAGS_all) {
+  if (absl::GetFlag(FLAGS_all)) {
     const std::vector<std::pair<std::string, std::string>> connections =
         NodeConnections();
     for (std::pair<std::string, std::string> ab : connections) {
diff --git a/aos/events/ping.cc b/aos/events/ping.cc
index 975f2e4..5ed85c7 100644
--- a/aos/events/ping.cc
+++ b/aos/events/ping.cc
@@ -1,20 +1,18 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/ping_lib.h"
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
-#include "aos/json_to_flatbuffer.h"
 
-DEFINE_string(config, "pingpong_config.json", "Path to the config.");
+ABSL_FLAG(std::string, config, "pingpong_config.json", "Path to the config.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::EventLoop::SetDefaultVersionString("ping_version");
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
diff --git a/aos/events/ping_lib.cc b/aos/events/ping_lib.cc
index cd36378..8a65c84 100644
--- a/aos/events/ping_lib.cc
+++ b/aos/events/ping_lib.cc
@@ -1,13 +1,13 @@
 #include "aos/events/ping_lib.h"
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/log.h"
 
 #include "aos/events/ping_static.h"
 #include "aos/events/pong_static.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_int32(sleep_us, 10000, "Time to sleep between pings");
+ABSL_FLAG(int32_t, sleep_us, 10000, "Time to sleep between pings");
 
 namespace aos {
 
@@ -25,8 +25,9 @@
   }
 
   event_loop_->OnRun([this]() {
-    timer_handle_->Schedule(event_loop_->monotonic_now(),
-                            chrono::microseconds(FLAGS_sleep_us));
+    timer_handle_->Schedule(
+        event_loop_->monotonic_now(),
+        chrono::microseconds(absl::GetFlag(FLAGS_sleep_us)));
   });
 
   event_loop_->SetRuntimeRealtimePriority(5);
@@ -35,7 +36,7 @@
 void Ping::SendPing() {
   if (last_pong_value_ != count_ && (!quiet_ || VLOG_IS_ON(1))) {
     LOG(WARNING) << "Did not receive response to " << count_ << " within "
-                 << FLAGS_sleep_us << "us.";
+                 << absl::GetFlag(FLAGS_sleep_us) << "us.";
   }
   ++count_;
   aos::Sender<examples::PingStatic>::StaticBuilder builder =
diff --git a/aos/events/pingpong_test.cc b/aos/events/pingpong_test.cc
index c52e8eb..5905b73 100644
--- a/aos/events/pingpong_test.cc
+++ b/aos/events/pingpong_test.cc
@@ -1,4 +1,5 @@
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/ping_lib.h"
diff --git a/aos/events/pong.cc b/aos/events/pong.cc
index 9162567..ed09e70 100644
--- a/aos/events/pong.cc
+++ b/aos/events/pong.cc
@@ -1,4 +1,6 @@
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/ping_generated.h"
@@ -7,14 +9,14 @@
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 
-DEFINE_string(config, "pingpong_config.json", "Path to the config.");
+ABSL_FLAG(std::string, config, "pingpong_config.json", "Path to the config.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::EventLoop::SetDefaultVersionString("pong_version");
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   ::aos::ShmEventLoop event_loop(&config.message());
 
diff --git a/aos/events/pong_lib.cc b/aos/events/pong_lib.cc
index 8fc3f62..52bcd38 100644
--- a/aos/events/pong_lib.cc
+++ b/aos/events/pong_lib.cc
@@ -1,13 +1,15 @@
 #include "aos/events/pong_lib.h"
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "aos/events/ping_static.h"
 #include "aos/events/pong_static.h"
 
-DEFINE_bool(fetch, false, "Poll & fetch messages instead of using a watcher.");
-DEFINE_uint32(fetch_period_ms, 10, "Frequency at which to fetch.");
+ABSL_FLAG(bool, fetch, false,
+          "Poll & fetch messages instead of using a watcher.");
+ABSL_FLAG(uint32_t, fetch_period_ms, 10, "Frequency at which to fetch.");
 
 namespace aos {
 
@@ -15,7 +17,7 @@
     : event_loop_(event_loop),
       fetcher_(event_loop_->MakeFetcher<examples::Ping>("/test")),
       sender_(event_loop_->MakeSender<examples::PongStatic>("/test")) {
-  if (FLAGS_fetch) {
+  if (absl::GetFlag(FLAGS_fetch)) {
     event_loop_
         ->AddPhasedLoop(
             [this](int) {
@@ -23,7 +25,7 @@
                 HandlePing(*fetcher_.get());
               }
             },
-            std::chrono::milliseconds(FLAGS_fetch_period_ms))
+            std::chrono::milliseconds(absl::GetFlag(FLAGS_fetch_period_ms)))
         ->set_name("pong");
   } else {
     event_loop_->MakeWatcher(
diff --git a/aos/events/shm_event_loop.cc b/aos/events/shm_event_loop.cc
index 8035235..e038498 100644
--- a/aos/events/shm_event_loop.cc
+++ b/aos/events/shm_event_loop.cc
@@ -10,7 +10,9 @@
 #include <iterator>
 #include <stdexcept>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/aos_logging.h"
 #include "aos/events/epoll.h"
@@ -46,12 +48,12 @@
 // groups or others).
 // See https://man7.org/linux/man-pages/man2/umask.2.html for more details.
 // WITH THE DEFAULT UMASK YOU WONT ACTUALLY GET THESE PERMISSIONS :)
-DEFINE_uint32(permissions, 0770,
-              "Permissions to make shared memory files and folders, "
-              "affected by the process's umask. "
-              "See shm_event_loop.cc for more details.");
-DEFINE_string(application_name, Filename(program_invocation_name),
-              "The application name");
+ABSL_FLAG(uint32_t, permissions, 0770,
+          "Permissions to make shared memory files and folders, "
+          "affected by the process's umask. "
+          "See shm_event_loop.cc for more details.");
+ABSL_FLAG(std::string, application_name, Filename(program_invocation_name),
+          "The application name");
 
 namespace aos {
 
@@ -80,8 +82,8 @@
 ShmEventLoop::ShmEventLoop(const Configuration *configuration)
     : EventLoop(configuration),
       boot_uuid_(UUID::BootUUID()),
-      shm_base_(FLAGS_shm_base),
-      name_(FLAGS_application_name),
+      shm_base_(absl::GetFlag(FLAGS_shm_base)),
+      name_(absl::GetFlag(FLAGS_application_name)),
       node_(MaybeMyNode(configuration)) {
   // Ignore the wakeup signal by default. Otherwise, we have race conditions on
   // shutdown where a wakeup signal will uncleanly terminate the process.
@@ -103,7 +105,7 @@
                             const Channel *channel)
       : event_loop_(event_loop),
         channel_(channel),
-        lockless_queue_memory_(shm_base, FLAGS_permissions,
+        lockless_queue_memory_(shm_base, absl::GetFlag(FLAGS_permissions),
                                event_loop->configuration(), channel),
         reader_(lockless_queue_memory_.queue()) {
     context_.data = nullptr;
@@ -430,7 +432,7 @@
   explicit ShmSender(std::string_view shm_base, EventLoop *event_loop,
                      const Channel *channel)
       : RawSender(event_loop, channel),
-        lockless_queue_memory_(shm_base, FLAGS_permissions,
+        lockless_queue_memory_(shm_base, absl::GetFlag(FLAGS_permissions),
                                event_loop->configuration(), channel),
         lockless_queue_sender_(
             VerifySender(ipc_lib::LocklessQueueSender::Make(
diff --git a/aos/events/shm_event_loop.h b/aos/events/shm_event_loop.h
index 5da1632..5de4423 100644
--- a/aos/events/shm_event_loop.h
+++ b/aos/events/shm_event_loop.h
@@ -12,7 +12,7 @@
 #include "aos/ipc_lib/signalfd.h"
 #include "aos/stl_mutex/stl_mutex.h"
 
-DECLARE_string(application_name);
+ABSL_DECLARE_FLAG(std::string, application_name);
 
 namespace aos {
 namespace shm_event_loop_internal {
diff --git a/aos/events/shm_event_loop_test.cc b/aos/events/shm_event_loop_test.cc
index aae8f15..9665478 100644
--- a/aos/events/shm_event_loop_test.cc
+++ b/aos/events/shm_event_loop_test.cc
@@ -2,7 +2,9 @@
 
 #include <string_view>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/event_loop_param_test.h"
@@ -18,20 +20,26 @@
  public:
   ShmEventLoopTestFactory() {
     // Clean up anything left there before.
-    unlink((FLAGS_shm_base + "/test/aos.TestMessage.v7").c_str());
-    unlink((FLAGS_shm_base + "/test1/aos.TestMessage.v7").c_str());
-    unlink((FLAGS_shm_base + "/test2/aos.TestMessage.v7").c_str());
-    unlink((FLAGS_shm_base + "/test2/aos.TestMessage.v7").c_str());
-    unlink((FLAGS_shm_base + "/aos/aos.timing.Report.v7").c_str());
-    unlink((FLAGS_shm_base + "/aos/aos.logging.LogMessageFbs.v7").c_str());
+    unlink(
+        (absl::GetFlag(FLAGS_shm_base) + "/test/aos.TestMessage.v7").c_str());
+    unlink(
+        (absl::GetFlag(FLAGS_shm_base) + "/test1/aos.TestMessage.v7").c_str());
+    unlink(
+        (absl::GetFlag(FLAGS_shm_base) + "/test2/aos.TestMessage.v7").c_str());
+    unlink(
+        (absl::GetFlag(FLAGS_shm_base) + "/test2/aos.TestMessage.v7").c_str());
+    unlink(
+        (absl::GetFlag(FLAGS_shm_base) + "/aos/aos.timing.Report.v7").c_str());
+    unlink((absl::GetFlag(FLAGS_shm_base) + "/aos/aos.logging.LogMessageFbs.v7")
+               .c_str());
   }
 
-  ~ShmEventLoopTestFactory() { FLAGS_override_hostname = ""; }
+  ~ShmEventLoopTestFactory() { absl::SetFlag(&FLAGS_override_hostname, ""); }
 
   ::std::unique_ptr<EventLoop> Make(std::string_view name) override {
     if (configuration()->has_nodes()) {
-      FLAGS_override_hostname =
-          std::string(my_node()->hostname()->string_view());
+      absl::SetFlag(&FLAGS_override_hostname,
+                    std::string(my_node()->hostname()->string_view()));
     }
     ::std::unique_ptr<ShmEventLoop> loop(new ShmEventLoop(configuration()));
     loop->set_name(name);
@@ -40,8 +48,8 @@
 
   ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name) override {
     if (configuration()->has_nodes()) {
-      FLAGS_override_hostname =
-          std::string(my_node()->hostname()->string_view());
+      absl::SetFlag(&FLAGS_override_hostname,
+                    std::string(my_node()->hostname()->string_view()));
     }
     ::std::unique_ptr<ShmEventLoop> loop =
         ::std::unique_ptr<ShmEventLoop>(new ShmEventLoop(configuration()));
diff --git a/aos/events/simple_channel.cc b/aos/events/simple_channel.cc
index 51d9ef6..72621bc 100644
--- a/aos/events/simple_channel.cc
+++ b/aos/events/simple_channel.cc
@@ -1,7 +1,7 @@
 #include "aos/events/simple_channel.h"
 
+#include "absl/log/check.h"
 #include "absl/strings/str_cat.h"
-#include "glog/logging.h"
 
 namespace aos {
 
diff --git a/aos/events/simulated_event_loop.h b/aos/events/simulated_event_loop.h
index 3bcd639..449ab71 100644
--- a/aos/events/simulated_event_loop.h
+++ b/aos/events/simulated_event_loop.h
@@ -11,7 +11,8 @@
 #include <vector>
 
 #include "absl/container/btree_map.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "aos/events/event_scheduler.h"
diff --git a/aos/events/simulated_event_loop_test.cc b/aos/events/simulated_event_loop_test.cc
index 1588ede..9a1b9cc 100644
--- a/aos/events/simulated_event_loop_test.cc
+++ b/aos/events/simulated_event_loop_test.cc
@@ -4,6 +4,8 @@
 #include <functional>
 #include <string_view>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/event_loop_param_test.h"
@@ -479,10 +481,11 @@
 
 // Tests that watchers have latency in simulation.
 TEST(SimulatedEventLoopTest, WatcherTimingReport) {
+  absl::FlagSaver flag_saver;
   SimulatedEventLoopTestFactory factory;
   factory.set_send_delay(std::chrono::microseconds(50));
 
-  FLAGS_timing_report_ms = 1000;
+  absl::SetFlag(&FLAGS_timing_report_ms, 1000);
   auto loop1 = factory.MakePrimary("primary");
   loop1->MakeWatcher("/test", [](const TestMessage &) {});
 
diff --git a/aos/events/simulated_network_bridge.cc b/aos/events/simulated_network_bridge.cc
index fd2dead..af5c800 100644
--- a/aos/events/simulated_network_bridge.cc
+++ b/aos/events/simulated_network_bridge.cc
@@ -1,7 +1,8 @@
 #include "aos/events/simulated_network_bridge.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
diff --git a/aos/events/timing_report_dump.cc b/aos/events/timing_report_dump.cc
index bd80a04..b519f8d 100644
--- a/aos/events/timing_report_dump.cc
+++ b/aos/events/timing_report_dump.cc
@@ -1,5 +1,6 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -7,11 +8,11 @@
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_string(application, "",
-              "Application filter to use. Empty for no filter.");
-DEFINE_bool(stream, false, "Stream out all the timing reports in the log.");
-DEFINE_bool(accumulate, true,
-            "Display accumulation of all timing reports at end of log.");
+ABSL_FLAG(std::string, application, "",
+          "Application filter to use. Empty for no filter.");
+ABSL_FLAG(bool, stream, false, "Stream out all the timing reports in the log.");
+ABSL_FLAG(bool, accumulate, true,
+          "Display accumulation of all timing reports at end of log.");
 
 namespace aos {
 struct DumperState {
@@ -37,12 +38,14 @@
       std::unique_ptr<TimingReportDump> dumper =
           std::make_unique<TimingReportDump>(
               event_loop.get(),
-              FLAGS_accumulate ? TimingReportDump::AccumulateStatistics::kYes
-                               : TimingReportDump::AccumulateStatistics::kNo,
-              FLAGS_stream ? TimingReportDump::StreamResults::kYes
-                           : TimingReportDump::StreamResults::kNo);
-      if (!FLAGS_application.empty()) {
-        dumper->ApplicationFilter(FLAGS_application);
+              absl::GetFlag(FLAGS_accumulate)
+                  ? TimingReportDump::AccumulateStatistics::kYes
+                  : TimingReportDump::AccumulateStatistics::kNo,
+              absl::GetFlag(FLAGS_stream)
+                  ? TimingReportDump::StreamResults::kYes
+                  : TimingReportDump::StreamResults::kNo);
+      if (!absl::GetFlag(FLAGS_application).empty()) {
+        dumper->ApplicationFilter(absl::GetFlag(FLAGS_application));
       }
       dumpers.push_back({std::move(event_loop), std::move(dumper)});
     }
diff --git a/aos/events/timing_report_dump_lib.h b/aos/events/timing_report_dump_lib.h
index 02bfb54..0a2896c 100644
--- a/aos/events/timing_report_dump_lib.h
+++ b/aos/events/timing_report_dump_lib.h
@@ -3,8 +3,9 @@
 #include <map>
 #include <string>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
diff --git a/aos/events/timing_statistics.cc b/aos/events/timing_statistics.cc
index ea3f2d2..5aff823 100644
--- a/aos/events/timing_statistics.cc
+++ b/aos/events/timing_statistics.cc
@@ -1,6 +1,7 @@
 #include "aos/events/timing_statistics.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop_generated.h"
 
diff --git a/aos/fast_string_builder.h b/aos/fast_string_builder.h
index e9a4f27..b27ead1 100644
--- a/aos/fast_string_builder.h
+++ b/aos/fast_string_builder.h
@@ -5,9 +5,10 @@
 #include <string>
 #include <type_traits>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_format.h"
-#include "glog/logging.h"
 
 namespace aos {
 
diff --git a/aos/flatbuffer_utils.cc b/aos/flatbuffer_utils.cc
index afa1cb4..9021c78 100644
--- a/aos/flatbuffer_utils.cc
+++ b/aos/flatbuffer_utils.cc
@@ -1,8 +1,9 @@
 #include "aos/flatbuffer_utils.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/minireflect.h"
 #include "flatbuffers/reflection_generated.h"
-#include "glog/logging.h"
 
 namespace aos {
 
diff --git a/aos/flatbuffer_utils.h b/aos/flatbuffer_utils.h
index 003f141..90a4c86 100644
--- a/aos/flatbuffer_utils.h
+++ b/aos/flatbuffer_utils.h
@@ -6,7 +6,6 @@
 
 #include "flatbuffers/flatbuffers.h"
 #include "flatbuffers/reflection_generated.h"
-#include "glog/logging.h"
 
 namespace aos {
 
diff --git a/aos/flatbuffers.cc b/aos/flatbuffers.cc
index 4f6497e..9fead13 100644
--- a/aos/flatbuffers.cc
+++ b/aos/flatbuffers.cc
@@ -1,6 +1,7 @@
 #include "aos/flatbuffers.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos {
 
diff --git a/aos/flatbuffers.h b/aos/flatbuffers.h
index f1ed626..4549e19 100644
--- a/aos/flatbuffers.h
+++ b/aos/flatbuffers.h
@@ -4,9 +4,10 @@
 #include <array>
 #include <string_view>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
 #include "flatbuffers/flatbuffers.h"  // IWYU pragma: export
-#include "glog/logging.h"
 
 #include "aos/containers/resizeable_buffer.h"
 #include "aos/ipc_lib/data_alignment.h"
diff --git a/aos/flatbuffers/BUILD b/aos/flatbuffers/BUILD
index e4f7d1d..f7e4670 100644
--- a/aos/flatbuffers/BUILD
+++ b/aos/flatbuffers/BUILD
@@ -11,7 +11,8 @@
         ":static_vector",
         "//aos:json_to_flatbuffer",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/strings:str_format",
     ],
@@ -32,8 +33,9 @@
         "//aos/containers:resizeable_buffer",
         "//aos/ipc_lib:data_alignment",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -54,7 +56,8 @@
     deps = [
         ":base",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -67,7 +70,8 @@
         "//aos/containers:inlined_vector",
         "//aos/containers:sized_array",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/flatbuffers/base.cc b/aos/flatbuffers/base.cc
index f0e7a8b..77988da 100644
--- a/aos/flatbuffers/base.cc
+++ b/aos/flatbuffers/base.cc
@@ -4,6 +4,9 @@
 
 #include <iomanip>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
+
 namespace aos::fbs {
 
 namespace {
diff --git a/aos/flatbuffers/base.h b/aos/flatbuffers/base.h
index 6e93f93..a0d3810 100644
--- a/aos/flatbuffers/base.h
+++ b/aos/flatbuffers/base.h
@@ -12,9 +12,10 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
 #include "flatbuffers/base.h"
-#include "glog/logging.h"
 
 #include "aos/containers/resizeable_buffer.h"
 #include "aos/ipc_lib/data_alignment.h"
diff --git a/aos/flatbuffers/generate.cc b/aos/flatbuffers/generate.cc
index 9a2e5fd..4c76785 100644
--- a/aos/flatbuffers/generate.cc
+++ b/aos/flatbuffers/generate.cc
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 
+#include "absl/flags/flag.h"
 #include "flatbuffers/reflection_generated.h"
-#include "gflags/gflags.h"
 
 #include "aos/flatbuffers.h"
 #include "aos/flatbuffers/static_flatbuffers.h"
@@ -9,19 +9,22 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/util/file.h"
 
-DEFINE_string(reflection_bfbs, "", "Path to the .bfbs reflection file.");
-DEFINE_string(output_file, "", "Path to the output header to write.");
-DEFINE_string(base_file_name, "",
-              "Name of the base file to generate code for as used by the "
-              "reflection::Schema object.");
+ABSL_FLAG(std::string, reflection_bfbs, "",
+          "Path to the .bfbs reflection file.");
+ABSL_FLAG(std::string, output_file, "", "Path to the output header to write.");
+ABSL_FLAG(std::string, base_file_name, "",
+          "Name of the base file to generate code for as used by the "
+          "reflection::Schema object.");
 
 namespace aos::fbs {
 int Main() {
   aos::FlatbufferVector<reflection::Schema> schema =
-      aos::FileToFlatbuffer<reflection::Schema>(FLAGS_reflection_bfbs);
+      aos::FileToFlatbuffer<reflection::Schema>(
+          absl::GetFlag(FLAGS_reflection_bfbs));
   aos::util::WriteStringToFileOrDie(
-      FLAGS_output_file,
-      GenerateCodeForRootTableFile(&schema.message(), FLAGS_base_file_name));
+      absl::GetFlag(FLAGS_output_file),
+      GenerateCodeForRootTableFile(&schema.message(),
+                                   absl::GetFlag(FLAGS_base_file_name)));
   return EXIT_SUCCESS;
 }
 }  // namespace aos::fbs
diff --git a/aos/flatbuffers/static_flatbuffers.cc b/aos/flatbuffers/static_flatbuffers.cc
index 449bcbc..e3130bb 100644
--- a/aos/flatbuffers/static_flatbuffers.cc
+++ b/aos/flatbuffers/static_flatbuffers.cc
@@ -10,6 +10,8 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
@@ -19,7 +21,6 @@
 #include "flatbuffers/base.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 #include "aos/flatbuffers/base.h"
 #include "aos/json_to_flatbuffer.h"
diff --git a/aos/flatbuffers/static_flatbuffers_test.cc b/aos/flatbuffers/static_flatbuffers_test.cc
index 187c72a..aee8067 100644
--- a/aos/flatbuffers/static_flatbuffers_test.cc
+++ b/aos/flatbuffers/static_flatbuffers_test.cc
@@ -12,6 +12,8 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
 #include "absl/types/span.h"
@@ -23,7 +25,6 @@
 #include "flatbuffers/stl_emulation.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/flatbuffers.h"
diff --git a/aos/flatbuffers/static_table.h b/aos/flatbuffers/static_table.h
index a7f96d1..cd3ae5c 100644
--- a/aos/flatbuffers/static_table.h
+++ b/aos/flatbuffers/static_table.h
@@ -3,8 +3,9 @@
 #include <algorithm>
 #include <span>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/base.h"
-#include "glog/logging.h"
 
 #include "aos/flatbuffers/base.h"
 namespace aos::fbs {
diff --git a/aos/flatbuffers/static_vector.h b/aos/flatbuffers/static_vector.h
index f0c48cd..c835864 100644
--- a/aos/flatbuffers/static_vector.h
+++ b/aos/flatbuffers/static_vector.h
@@ -2,9 +2,10 @@
 #define AOS_FLATBUFFERS_STATIC_VECTOR_H_
 #include <span>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/base.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 #include "aos/containers/inlined_vector.h"
 #include "aos/containers/sized_array.h"
diff --git a/aos/ftrace.cc b/aos/ftrace.cc
index 37dc147..c731264 100644
--- a/aos/ftrace.cc
+++ b/aos/ftrace.cc
@@ -3,16 +3,18 @@
 #include <cstdarg>
 #include <cstdio>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
 #include "absl/strings/str_cat.h"
 
-DEFINE_bool(enable_ftrace, false,
-            "If false, disable logging to /sys/kernel/tracing/trace_marker");
+ABSL_FLAG(bool, enable_ftrace, false,
+          "If false, disable logging to /sys/kernel/tracing/trace_marker");
 
 namespace aos {
 
 namespace {
 int MaybeCheckOpen(const char *file) {
-  if (!FLAGS_enable_ftrace) return -1;
+  if (!absl::GetFlag(FLAGS_enable_ftrace)) return -1;
   int result =
       open(absl::StrCat("/sys/kernel/tracing/", file).c_str(), O_WRONLY);
   if (result == -1) {
@@ -42,6 +44,13 @@
   }
 }
 
+void Ftrace::TurnOffOrDie() {
+  CHECK(on_fd_ != -1)
+      << ": Failed to open tracing_on earlier, cannot turn off tracing";
+  char zero = '0';
+  CHECK_EQ(write(on_fd_, &zero, 1), 1) << ": Failed to turn tracing off";
+}
+
 void Ftrace::FormatMessage(const char *format, ...) {
   if (message_fd_ == -1) {
     return;
diff --git a/aos/ftrace.h b/aos/ftrace.h
index 3b5326f..e454838 100644
--- a/aos/ftrace.h
+++ b/aos/ftrace.h
@@ -8,8 +8,6 @@
 
 #include <string_view>
 
-#include "glog/logging.h"
-
 namespace aos {
 
 // Manages interacting with ftrace. Silently hides many errors, because they are
@@ -33,12 +31,7 @@
 
   // Turns tracing off, or CHECK-fails if tracing is inaccessible. Does nothing
   // if tracing is currently available but off.
-  void TurnOffOrDie() {
-    CHECK(on_fd_ != -1)
-        << ": Failed to open tracing_on earlier, cannot turn off tracing";
-    char zero = '0';
-    CHECK_EQ(write(on_fd_, &zero, 1), 1) << ": Failed to turn tracing off";
-  }
+  void TurnOffOrDie();
 
  private:
   int message_fd_, on_fd_;
diff --git a/aos/init.cc b/aos/init.cc
index 579ad33..b51dc1c 100644
--- a/aos/init.cc
+++ b/aos/init.cc
@@ -11,29 +11,61 @@
 #include <cstdlib>
 #include <cstring>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/debugging/failure_signal_handler.h"
+#include "absl/debugging/symbolize.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "absl/log/check.h"
+#include "absl/log/flags.h"
+#include "absl/log/globals.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 
 #include "aos/realtime.h"
 #include "aos/uuid.h"
 
-DEFINE_bool(coredump, false, "If true, write core dumps on failure.");
+ABSL_FLAG(bool, coredump, false, "If true, write core dumps on failure.");
+ABSL_FLAG(bool, backtrace, true, "If true, print backtraces out on crashes.");
 
 namespace aos {
 namespace {
-bool initialized = false;
+std::atomic<bool> initialized{false};
 }  // namespace
 
 bool IsInitialized() { return initialized; }
 
 void InitGoogle(int *argc, char ***argv) {
   CHECK(!IsInitialized()) << "Only initialize once.";
-  FLAGS_logtostderr = true;
-  google::InitGoogleLogging((*argv)[0]);
-  gflags::ParseCommandLineFlags(argc, argv, true);
-  google::InstallFailureSignalHandler();
+  absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
+  std::vector<char *> positional_arguments =
+      absl::ParseCommandLine(*argc, *argv);
 
-  if (FLAGS_coredump) {
+  {
+    const std::vector<absl::UnrecognizedFlag> unrecognized_flags;
+    absl::ReportUnrecognizedFlags(unrecognized_flags);
+    if (!unrecognized_flags.empty()) {
+      for (const absl::UnrecognizedFlag &flag : unrecognized_flags) {
+        LOG(ERROR) << "Unrecognized flag " << flag.flag_name;
+      }
+      LOG(FATAL) << "Found unrecognized flags, aborting";
+    }
+  }
+
+  CHECK_LE(positional_arguments.size(), static_cast<size_t>(*argc));
+  for (size_t i = 0; i < positional_arguments.size(); ++i) {
+    (*argv)[i] = positional_arguments[i];
+  }
+  *argc = positional_arguments.size();
+
+  absl::InitializeLog();
+
+  if (absl::GetFlag(FLAGS_backtrace)) {
+    absl::InitializeSymbolizer((*argv)[0]);
+    absl::FailureSignalHandlerOptions options;
+    absl::InstallFailureSignalHandler(options);
+  }
+
+  if (absl::GetFlag(FLAGS_coredump)) {
     WriteCoreDumps();
   }
 
diff --git a/aos/init.rs b/aos/init.rs
index 8fdb3d1..27b1046 100644
--- a/aos/init.rs
+++ b/aos/init.rs
@@ -262,14 +262,9 @@
     #[test]
     fn set_cxx_flag() {
         let _guard = MUTEX.lock();
-        let app = App::parse_with_cpp_flags_from(&[
-            "mytest",
-            "--alsologtostderr",
-            "true",
-            "--myarg",
-            "23",
-        ]);
+        let app =
+            App::parse_with_cpp_flags_from(&["mytest", "--stderrthreshold", "1", "--myarg", "23"]);
         assert_eq!(app.myarg, 23);
-        assert_eq!(CxxFlag::get_option("alsologtostderr"), "true");
+        assert_eq!(CxxFlag::get_option("stderrthreshold"), "1");
     }
 }
diff --git a/aos/init_for_rust.cc b/aos/init_for_rust.cc
index 9af4d83..1ede457 100644
--- a/aos/init_for_rust.cc
+++ b/aos/init_for_rust.cc
@@ -1,16 +1,19 @@
 #include "aos/init_for_rust.h"
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
+#include "absl/log/check.h"
+#include "absl/log/initialize.h"
+#include "absl/log/log.h"
 
 #include "aos/init.h"
 
 namespace aos {
 
-void InitFromRust(const char *argv0) {
-  CHECK(!IsInitialized()) << "Only initialize once.";
+void InitFromRust(const char * /*argv0*/) {
+  CHECK(!aos::IsInitialized()) << "Only initialize once.";
 
-  google::InitGoogleLogging(argv0);
+  absl::InitializeLog();
 
   // TODO(Brian): Where should Rust binaries be configured to write coredumps?
 
@@ -20,16 +23,50 @@
 }
 
 std::vector<FlagInfo> GetCppFlags() {
-  std::vector<gflags::CommandLineFlagInfo> info;
-  gflags::GetAllFlags(&info);
+  absl::flat_hash_map<absl::string_view, absl::CommandLineFlag *> info =
+      absl::GetAllFlags();
   std::vector<FlagInfo> out;
   for (const auto &flag : info) {
+    std::string type;
+    if (flag.second->IsOfType<float>()) {
+      type = "float";
+    } else if (flag.second->IsOfType<double>()) {
+      type = "double";
+    } else if (flag.second->IsOfType<bool>()) {
+      type = "bool";
+    } else if (flag.second->IsOfType<uint8_t>()) {
+      type = "uint8_t";
+    } else if (flag.second->IsOfType<int8_t>()) {
+      type = "int8_t";
+    } else if (flag.second->IsOfType<uint16_t>()) {
+      type = "uint16_t";
+    } else if (flag.second->IsOfType<int16_t>()) {
+      type = "int16_t";
+    } else if (flag.second->IsOfType<uint32_t>()) {
+      type = "uint32_t";
+    } else if (flag.second->IsOfType<int32_t>()) {
+      type = "int32_t";
+    } else if (flag.second->IsOfType<uint64_t>()) {
+      type = "uint64_t";
+    } else if (flag.second->IsOfType<int64_t>()) {
+      type = "int64_t";
+    } else if (flag.second->IsOfType<std::string>()) {
+      type = "string";
+    } else if (flag.second->IsOfType<std::vector<std::string>>()) {
+      type = "vector<string>";
+    } else {
+      LOG(FATAL) << "Unknown type for flag " << flag.second->Name()
+                 << " in file " << flag.second->Filename();
+    }
+
+    LOG(INFO) << "Reporting flag " << flag.second->Name() << " " << type << " "
+              << flag.second->DefaultValue();
     FlagInfo out_flag = {
-        .name_ = flag.name,
-        .type_ = flag.type,
-        .description_ = flag.description,
-        .default_value_ = flag.default_value,
-        .filename_ = flag.filename,
+        .name_ = std::string(flag.second->Name()),
+        .type_ = type,
+        .description_ = flag.second->Help(),
+        .default_value_ = flag.second->DefaultValue(),
+        .filename_ = flag.second->Filename(),
     };
     out.push_back(out_flag);
   }
@@ -37,13 +74,21 @@
 }
 
 bool SetCommandLineOption(const char *name, const char *value) {
-  return !gflags::SetCommandLineOption(name, value).empty();
+  absl::CommandLineFlag *flag = absl::FindCommandLineFlag(name);
+  if (flag == nullptr) {
+    return false;
+  }
+
+  std::string error;
+  bool result = flag->ParseFrom(value, &error);
+  return result;
 }
 
 std::string GetCommandLineOption(const char *name) {
-  std::string out;
-  CHECK(gflags::GetCommandLineOption(name, &out)) << "Unknown flag " << name;
-  return out;
+  absl::CommandLineFlag *flag = absl::FindCommandLineFlag(name);
+  CHECK(flag != nullptr) << "Unknown flag " << name;
+
+  return flag->CurrentValue();
 }
 
 }  // namespace aos
diff --git a/aos/ipc_lib/BUILD b/aos/ipc_lib/BUILD
index bae23b8..2ecd167 100644
--- a/aos/ipc_lib/BUILD
+++ b/aos/ipc_lib/BUILD
@@ -15,8 +15,9 @@
         ":shm_observers",
         "//aos:macros",
         "//aos/util:compiler_memory_barrier",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -53,7 +54,8 @@
         ":aos_sync",
         ":core_lib",
         ":shared_mem_types",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -105,7 +107,7 @@
         "//aos:init",
         "//aos/logging",
         "//aos/mutex",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -120,7 +122,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -134,7 +137,8 @@
         ":signalfd",
         "//aos/testing:googletest",
         "//aos/testing:test_logging",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -149,7 +153,8 @@
     visibility = ["//visibility:public"],
     deps = [
         ":shm_observers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -160,7 +165,8 @@
     deps = [
         ":index32",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -172,7 +178,8 @@
     visibility = ["//visibility:public"],
     deps = [
         ":shm_observers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -183,7 +190,8 @@
     deps = [
         ":index",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -213,7 +221,8 @@
         "//aos/time",
         "//aos/util:compiler_memory_barrier",
         "//aos/util:top",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/types:span",
     ],
@@ -266,6 +275,8 @@
     name = "lockless_queue_test",
     timeout = "eternal",
     srcs = ["lockless_queue_test.cc"],
+    # We don't want all the signal handlers registered, otherwise we can't fork.
+    args = ["--nobacktrace"],
     shard_count = 10,
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
@@ -283,6 +294,8 @@
 cc_test(
     name = "lockless_queue_death_test",
     srcs = ["lockless_queue_death_test.cc"],
+    # We don't want all the signal handlers registered, otherwise we can't fork.
+    args = ["--nobacktrace"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         ":event",
@@ -307,7 +320,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -320,7 +334,8 @@
         "//aos:realtime",
         "//aos/logging",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -334,7 +349,7 @@
         ":latency_lib",
         "//aos:init",
         "//aos/events:epoll",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -349,7 +364,7 @@
         "//aos:condition",
         "//aos:init",
         "//aos/mutex",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -363,7 +378,7 @@
         ":latency_lib",
         "//aos:init",
         "//aos/events:epoll",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -377,7 +392,7 @@
         ":latency_lib",
         "//aos:init",
         "//aos/events:epoll",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -407,7 +422,8 @@
         "//aos/ipc_lib:aos_sync",
         "//aos/time",
         "//aos/type_traits",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -442,7 +458,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
diff --git a/aos/ipc_lib/aos_sync.cc b/aos/ipc_lib/aos_sync.cc
index 78c6b2c..5642434 100644
--- a/aos/ipc_lib/aos_sync.cc
+++ b/aos/ipc_lib/aos_sync.cc
@@ -25,7 +25,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/macros.h"
 #include "aos/util/compiler_memory_barrier.h"
diff --git a/aos/ipc_lib/data_alignment.h b/aos/ipc_lib/data_alignment.h
index 3bf38ce..9cbfa23 100644
--- a/aos/ipc_lib/data_alignment.h
+++ b/aos/ipc_lib/data_alignment.h
@@ -1,7 +1,8 @@
 #ifndef AOS_IPC_LIB_DATA_ALIGNMENT_H_
 #define AOS_IPC_LIB_DATA_ALIGNMENT_H_
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos {
 
diff --git a/aos/ipc_lib/event.cc b/aos/ipc_lib/event.cc
index fd5bcaf..b62bdb2 100644
--- a/aos/ipc_lib/event.cc
+++ b/aos/ipc_lib/event.cc
@@ -6,7 +6,8 @@
 #include <ostream>
 #include <ratio>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/type_traits/type_traits.h"
 
diff --git a/aos/ipc_lib/eventfd_latency.cc b/aos/ipc_lib/eventfd_latency.cc
index 4a5616f..e35f8fc 100644
--- a/aos/ipc_lib/eventfd_latency.cc
+++ b/aos/ipc_lib/eventfd_latency.cc
@@ -10,10 +10,12 @@
 #include <ratio>
 #include <thread>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/epoll.h"
+#include "aos/init.h"
 #include "aos/ipc_lib/latency_lib.h"
 #include "aos/logging/implementations.h"
 #include "aos/realtime.h"
@@ -23,16 +25,16 @@
 // It measures both latency of a random timer thread, and latency of the
 // pipe.
 
-DEFINE_int32(seconds, 10, "Duration of the test to run");
-DEFINE_int32(
-    latency_threshold, 1000,
+ABSL_FLAG(int32_t, seconds, 10, "Duration of the test to run");
+ABSL_FLAG(
+    int32_t, latency_threshold, 1000,
     "Disable tracing when anything takes more than this many microseoncds");
-DEFINE_int32(core, 7, "Core to pin to");
-DEFINE_int32(sender_priority, 53, "RT priority to send at");
-DEFINE_int32(receiver_priority, 52, "RT priority to receive at");
-DEFINE_int32(timer_priority, 51, "RT priority to spin the timer at");
+ABSL_FLAG(int32_t, core, 7, "Core to pin to");
+ABSL_FLAG(int32_t, sender_priority, 53, "RT priority to send at");
+ABSL_FLAG(int32_t, receiver_priority, 52, "RT priority to receive at");
+ABSL_FLAG(int32_t, timer_priority, 51, "RT priority to spin the timer at");
 
-DEFINE_bool(log_latency, false, "If true, log the latency");
+ABSL_FLAG(bool, log_latency, false, "If true, log the latency");
 
 namespace chrono = ::std::chrono;
 
@@ -40,15 +42,15 @@
 
 void SenderThread(int fd) {
   const monotonic_clock::time_point end_time =
-      monotonic_clock::now() + chrono::seconds(FLAGS_seconds);
+      monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds));
   // Standard mersenne_twister_engine seeded with 0
   ::std::mt19937 generator(0);
 
   // Sleep between 1 and 15 ms.
   ::std::uniform_int_distribution<> distribution(1000, 15000);
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_sender_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_sender_priority));
   while (true) {
     const monotonic_clock::time_point wakeup_time =
         monotonic_clock::now() + chrono::microseconds(distribution(generator));
@@ -108,21 +110,22 @@
 
     max_wakeup_latency = ::std::max(wakeup_latency, max_wakeup_latency);
 
-    if (wakeup_latency > chrono::microseconds(FLAGS_latency_threshold)) {
+    if (wakeup_latency >
+        chrono::microseconds(absl::GetFlag(FLAGS_latency_threshold))) {
       t.Stop();
       AOS_LOG(INFO, "Stopped tracing, latency %" PRId64 "\n",
               static_cast<int64_t>(wakeup_latency.count()));
     }
 
-    if (FLAGS_log_latency) {
+    if (absl::GetFlag(FLAGS_log_latency)) {
       AOS_LOG(INFO, "dt: %8d.%03d\n",
               static_cast<int>(wakeup_latency.count() / 1000),
               static_cast<int>(wakeup_latency.count() % 1000));
     }
   });
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_receiver_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_receiver_priority));
   epoll.Run();
   UnsetCurrentThreadRealtimePriority();
   epoll.DeleteFd(fd);
@@ -141,8 +144,9 @@
 int Main(int /*argc*/, char ** /*argv*/) {
   AOS_LOG(INFO, "Main!\n");
   ::std::thread t([]() {
-    TimerThread(monotonic_clock::now() + chrono::seconds(FLAGS_seconds),
-                FLAGS_timer_priority);
+    TimerThread(
+        monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds)),
+        absl::GetFlag(FLAGS_timer_priority));
   });
 
   int fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
@@ -162,7 +166,7 @@
 }  // namespace aos
 
 int main(int argc, char **argv) {
-  ::gflags::ParseCommandLineFlags(&argc, &argv, true);
+  aos::InitGoogle(&argc, &argv);
 
   return ::aos::Main(argc, argv);
 }
diff --git a/aos/ipc_lib/futex_latency.cc b/aos/ipc_lib/futex_latency.cc
index eee015e..f6264aa 100644
--- a/aos/ipc_lib/futex_latency.cc
+++ b/aos/ipc_lib/futex_latency.cc
@@ -8,26 +8,28 @@
 #include <ratio>
 #include <thread>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/condition.h"
+#include "aos/init.h"
 #include "aos/ipc_lib/latency_lib.h"
 #include "aos/logging/implementations.h"
 #include "aos/mutex/mutex.h"
 #include "aos/realtime.h"
 #include "aos/time/time.h"
 
-DEFINE_int32(seconds, 10, "Duration of the test to run");
-DEFINE_int32(
-    latency_threshold, 1000,
+ABSL_FLAG(int32_t, seconds, 10, "Duration of the test to run");
+ABSL_FLAG(
+    int32_t, latency_threshold, 1000,
     "Disable tracing when anything takes more than this many microseoncds");
-DEFINE_int32(core, 7, "Core to pin to");
-DEFINE_int32(sender_priority, 53, "RT priority to send at");
-DEFINE_int32(receiver_priority, 52, "RT priority to receive at");
-DEFINE_int32(timer_priority, 51, "RT priority to spin the timer at");
+ABSL_FLAG(int32_t, core, 7, "Core to pin to");
+ABSL_FLAG(int32_t, sender_priority, 53, "RT priority to send at");
+ABSL_FLAG(int32_t, receiver_priority, 52, "RT priority to receive at");
+ABSL_FLAG(int32_t, timer_priority, 51, "RT priority to spin the timer at");
 
-DEFINE_bool(log_latency, false, "If true, log the latency");
+ABSL_FLAG(bool, log_latency, false, "If true, log the latency");
 
 const uint32_t kSignalNumber = SIGRTMIN + 1;
 const uint32_t kQuitSignalNumber = SIGRTMIN + 2;
@@ -49,15 +51,15 @@
 
 void SenderThread(WakeupData *data) {
   const monotonic_clock::time_point end_time =
-      monotonic_clock::now() + chrono::seconds(FLAGS_seconds);
+      monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds));
   // Standard mersenne_twister_engine seeded with 0
   ::std::mt19937 generator(0);
 
   // Sleep between 1 and 15 ms.
   ::std::uniform_int_distribution<> distribution(1000, 15000);
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_sender_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_sender_priority));
   while (true) {
     const monotonic_clock::time_point wakeup_time =
         monotonic_clock::now() + chrono::microseconds(distribution(generator));
@@ -93,8 +95,8 @@
   chrono::nanoseconds sum_latency = chrono::nanoseconds(0);
   int latency_count = 0;
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_receiver_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_receiver_priority));
   while (true) {
     chrono::nanoseconds wakeup_latency;
     {
@@ -118,13 +120,14 @@
 
     max_wakeup_latency = ::std::max(wakeup_latency, max_wakeup_latency);
 
-    if (wakeup_latency > chrono::microseconds(FLAGS_latency_threshold)) {
+    if (wakeup_latency >
+        chrono::microseconds(absl::GetFlag(FLAGS_latency_threshold))) {
       t.Stop();
       AOS_LOG(INFO, "Stopped tracing, latency %" PRId64 "\n",
               static_cast<int64_t>(wakeup_latency.count()));
     }
 
-    if (FLAGS_log_latency) {
+    if (absl::GetFlag(FLAGS_log_latency)) {
       AOS_LOG(INFO, "dt: %8d.%03d\n",
               static_cast<int>(wakeup_latency.count() / 1000),
               static_cast<int>(wakeup_latency.count() % 1000));
@@ -148,8 +151,9 @@
 
   AOS_LOG(INFO, "Main!\n");
   ::std::thread t([]() {
-    TimerThread(monotonic_clock::now() + chrono::seconds(FLAGS_seconds),
-                FLAGS_timer_priority);
+    TimerThread(
+        monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds)),
+        absl::GetFlag(FLAGS_timer_priority));
   });
 
   ::std::thread st([&data]() { SenderThread(&data); });
@@ -164,7 +168,7 @@
 }  // namespace aos
 
 int main(int argc, char **argv) {
-  ::gflags::ParseCommandLineFlags(&argc, &argv, true);
+  aos::InitGoogle(&argc, &argv);
 
   return ::aos::Main(argc, argv);
 }
diff --git a/aos/ipc_lib/index.h b/aos/ipc_lib/index.h
index c4cc64a..575d113 100644
--- a/aos/ipc_lib/index.h
+++ b/aos/ipc_lib/index.h
@@ -5,7 +5,8 @@
 
 #include <limits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/ipc_lib/shm_observers.h"
 
diff --git a/aos/ipc_lib/index_test.cc b/aos/ipc_lib/index_test.cc
index 334696e..a7f0c85 100644
--- a/aos/ipc_lib/index_test.cc
+++ b/aos/ipc_lib/index_test.cc
@@ -2,7 +2,8 @@
 
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 namespace aos::ipc_lib::testing {
diff --git a/aos/ipc_lib/ipc_comparison.cc b/aos/ipc_lib/ipc_comparison.cc
index 8bb78d7..e5905ac 100644
--- a/aos/ipc_lib/ipc_comparison.cc
+++ b/aos/ipc_lib/ipc_comparison.cc
@@ -26,7 +26,8 @@
 #include <thread>
 #include <utility>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 
 #include "aos/condition.h"
 #include "aos/init.h"
@@ -36,14 +37,15 @@
 #include "aos/realtime.h"
 #include "aos/time/time.h"
 
-DEFINE_string(method, "", "Which IPC method to use");
-DEFINE_int32(messages, 1000000, "How many messages to send back and forth");
-DEFINE_int32(client_cpu, 0, "CPU to pin client to");
-DEFINE_int32(server_cpu, 0, "CPU to pin server to");
-DEFINE_int32(client_priority, 1,
-             "Realtime priority for client. Negative for don't change");
-DEFINE_int32(server_priority, 1,
-             "Realtime priority for server. Negative for don't change");
+ABSL_FLAG(std::string, method, "", "Which IPC method to use");
+ABSL_FLAG(int32_t, messages, 1000000,
+          "How many messages to send back and forth");
+ABSL_FLAG(int32_t, client_cpu, 0, "CPU to pin client to");
+ABSL_FLAG(int32_t, server_cpu, 0, "CPU to pin server to");
+ABSL_FLAG(int32_t, client_priority, 1,
+          "Realtime priority for client. Negative for don't change");
+ABSL_FLAG(int32_t, server_priority, 1,
+          "Realtime priority for server. Negative for don't change");
 
 namespace aos {
 
@@ -761,63 +763,65 @@
   sem_t *ping_sem_, *pong_sem_;
 };
 
-int Main(int /*argc*/, char **argv) {
+int Main() {
   ::std::unique_ptr<PingPongerInterface> ping_ponger;
-  if (FLAGS_method == "pipe") {
+  if (absl::GetFlag(FLAGS_method) == "pipe") {
     ping_ponger.reset(new PipePingPonger());
-  } else if (FLAGS_method == "named_pipe") {
+  } else if (absl::GetFlag(FLAGS_method) == "named_pipe") {
     ping_ponger.reset(new NamedPipePingPonger());
-  } else if (FLAGS_method == "aos_mutex") {
+  } else if (absl::GetFlag(FLAGS_method) == "aos_mutex") {
     ping_ponger.reset(new AOSMutexPingPonger());
-  } else if (FLAGS_method == "aos_event") {
+  } else if (absl::GetFlag(FLAGS_method) == "aos_event") {
     ping_ponger.reset(new AOSEventPingPonger());
-  } else if (FLAGS_method == "pthread_mutex") {
+  } else if (absl::GetFlag(FLAGS_method) == "pthread_mutex") {
     ping_ponger.reset(new PthreadMutexPingPonger(false, false));
-  } else if (FLAGS_method == "pthread_mutex_pshared") {
+  } else if (absl::GetFlag(FLAGS_method) == "pthread_mutex_pshared") {
     ping_ponger.reset(new PthreadMutexPingPonger(true, false));
-  } else if (FLAGS_method == "pthread_mutex_pshared_pi") {
+  } else if (absl::GetFlag(FLAGS_method) == "pthread_mutex_pshared_pi") {
     ping_ponger.reset(new PthreadMutexPingPonger(true, true));
-  } else if (FLAGS_method == "pthread_mutex_pi") {
+  } else if (absl::GetFlag(FLAGS_method) == "pthread_mutex_pi") {
     ping_ponger.reset(new PthreadMutexPingPonger(false, true));
-  } else if (FLAGS_method == "eventfd") {
+  } else if (absl::GetFlag(FLAGS_method) == "eventfd") {
     ping_ponger.reset(new EventFDPingPonger());
-  } else if (FLAGS_method == "sysv_semaphore") {
+  } else if (absl::GetFlag(FLAGS_method) == "sysv_semaphore") {
     ping_ponger.reset(new SysvSemaphorePingPonger());
-  } else if (FLAGS_method == "sysv_queue") {
+  } else if (absl::GetFlag(FLAGS_method) == "sysv_queue") {
     ping_ponger.reset(new SysvQueuePingPonger());
-  } else if (FLAGS_method == "posix_semaphore_unnamed_shared") {
+  } else if (absl::GetFlag(FLAGS_method) == "posix_semaphore_unnamed_shared") {
     ping_ponger.reset(new PosixUnnamedSemaphorePingPonger(1));
-  } else if (FLAGS_method == "posix_semaphore_unnamed_unshared") {
+  } else if (absl::GetFlag(FLAGS_method) ==
+             "posix_semaphore_unnamed_unshared") {
     ping_ponger.reset(new PosixUnnamedSemaphorePingPonger(0));
-  } else if (FLAGS_method == "posix_semaphore_named") {
+  } else if (absl::GetFlag(FLAGS_method) == "posix_semaphore_named") {
     ping_ponger.reset(new PosixNamedSemaphorePingPonger());
-  } else if (FLAGS_method == "posix_queue") {
+  } else if (absl::GetFlag(FLAGS_method) == "posix_queue") {
     ping_ponger.reset(new PosixQueuePingPonger());
-  } else if (FLAGS_method == "unix_stream") {
+  } else if (absl::GetFlag(FLAGS_method) == "unix_stream") {
     ping_ponger.reset(new UnixPingPonger(SOCK_STREAM));
-  } else if (FLAGS_method == "unix_datagram") {
+  } else if (absl::GetFlag(FLAGS_method) == "unix_datagram") {
     ping_ponger.reset(new UnixPingPonger(SOCK_DGRAM));
-  } else if (FLAGS_method == "unix_seqpacket") {
+  } else if (absl::GetFlag(FLAGS_method) == "unix_seqpacket") {
     ping_ponger.reset(new UnixPingPonger(SOCK_SEQPACKET));
-  } else if (FLAGS_method == "tcp") {
+  } else if (absl::GetFlag(FLAGS_method) == "tcp") {
     ping_ponger.reset(new TCPPingPonger(false));
-  } else if (FLAGS_method == "tcp_nodelay") {
+  } else if (absl::GetFlag(FLAGS_method) == "tcp_nodelay") {
     ping_ponger.reset(new TCPPingPonger(true));
-  } else if (FLAGS_method == "udp") {
+  } else if (absl::GetFlag(FLAGS_method) == "udp") {
     ping_ponger.reset(new UDPPingPonger());
   } else {
-    fprintf(stderr, "Unknown IPC method to test '%s'\n", FLAGS_method.c_str());
-    ::gflags::ShowUsageWithFlags(argv[0]);
+    fprintf(stderr, "Unknown IPC method to test '%s'\n",
+            absl::GetFlag(FLAGS_method).c_str());
     return 1;
   }
 
   ::std::atomic<bool> done{false};
 
   ::std::thread server([&ping_ponger, &done]() {
-    if (FLAGS_server_priority > 0) {
-      SetCurrentThreadRealtimePriority(FLAGS_server_priority);
+    if (absl::GetFlag(FLAGS_server_priority) > 0) {
+      SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_server_priority));
     }
-    SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_server_cpu}));
+    SetCurrentThreadAffinity(
+        MakeCpusetFromCpus({absl::GetFlag(FLAGS_server_cpu)}));
 
     while (!done) {
       const PingPongerInterface::Data *data = ping_ponger->Wait();
@@ -829,10 +833,11 @@
     }
   });
 
-  if (FLAGS_client_priority > 0) {
-    SetCurrentThreadRealtimePriority(FLAGS_client_priority);
+  if (absl::GetFlag(FLAGS_client_priority) > 0) {
+    SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_client_priority));
   }
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_client_cpu}));
+  SetCurrentThreadAffinity(
+      MakeCpusetFromCpus({absl::GetFlag(FLAGS_client_cpu)}));
 
   // Warm everything up.
   for (int i = 0; i < 1000; ++i) {
@@ -843,7 +848,7 @@
 
   const monotonic_clock::time_point start = monotonic_clock::now();
 
-  for (int32_t i = 0; i < FLAGS_messages; ++i) {
+  for (int32_t i = 0; i < absl::GetFlag(FLAGS_messages); ++i) {
     PingPongerInterface::Data *to_send = ping_ponger->PingData();
     memset(*to_send, i % 123, sizeof(*to_send));
     const PingPongerInterface::Data *received = ping_ponger->Ping();
@@ -865,8 +870,10 @@
   server.join();
 
   AOS_LOG(INFO, "Took %f seconds to send %" PRId32 " messages\n",
-          ::aos::time::DurationInSeconds(end - start), FLAGS_messages);
-  const chrono::nanoseconds per_message = (end - start) / FLAGS_messages;
+          ::aos::time::DurationInSeconds(end - start),
+          absl::GetFlag(FLAGS_messages));
+  const chrono::nanoseconds per_message =
+      (end - start) / absl::GetFlag(FLAGS_messages);
   if (per_message >= chrono::seconds(1)) {
     AOS_LOG(INFO, "More than 1 second per message ?!?\n");
   } else {
@@ -880,7 +887,7 @@
 }  // namespace aos
 
 int main(int argc, char **argv) {
-  ::gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       ::std::string("Compares various forms of IPC. Usage:\n") + argv[0] +
       " --method=METHOD\n"
       "METHOD can be one of the following:\n"
@@ -905,7 +912,7 @@
       "\ttcp\n"
       "\ttcp_nodelay\n"
       "\tudp\n");
-  ::aos::InitGoogle(&argc, &argv);
+  aos::InitGoogle(&argc, &argv);
 
-  return ::aos::Main(argc, argv);
+  return ::aos::Main();
 }
diff --git a/aos/ipc_lib/latency_lib.h b/aos/ipc_lib/latency_lib.h
index 8206f3e..fe68941 100644
--- a/aos/ipc_lib/latency_lib.h
+++ b/aos/ipc_lib/latency_lib.h
@@ -5,7 +5,8 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 
diff --git a/aos/ipc_lib/lockless_queue.cc b/aos/ipc_lib/lockless_queue.cc
index ae3a493..986ca62 100644
--- a/aos/ipc_lib/lockless_queue.cc
+++ b/aos/ipc_lib/lockless_queue.cc
@@ -16,16 +16,17 @@
 #include <string>
 #include <string_view>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/escaping.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/ipc_lib/lockless_queue_memory.h"
 #include "aos/util/compiler_memory_barrier.h"
 
-DEFINE_bool(dump_lockless_queue_data, false,
-            "If true, print the data out when dumping the queue.");
-DECLARE_bool(skip_realtime_scheduler);
+ABSL_FLAG(bool, dump_lockless_queue_data, false,
+          "If true, print the data out when dumping the queue.");
+ABSL_DECLARE_FLAG(bool, skip_realtime_scheduler);
 
 namespace aos::ipc_lib {
 namespace {
@@ -821,7 +822,7 @@
       // Inline the setscheduler call rather than using aos/realtime.h.  This is
       // quite performance sensitive, and halves the time needed to send a
       // message when pi boosting is in effect.
-      if (!FLAGS_skip_realtime_scheduler) {
+      if (!absl::GetFlag(FLAGS_skip_realtime_scheduler)) {
         // TODO(austin): Do we need to boost the soft limit here too like we
         // were before?
         struct sched_param param;
@@ -859,7 +860,7 @@
 
     // Drop back down if we were boosted.
     if (max_priority > current_priority && current_priority > 0) {
-      if (!FLAGS_skip_realtime_scheduler) {
+      if (!absl::GetFlag(FLAGS_skip_realtime_scheduler)) {
         struct sched_param param;
         param.sched_priority = current_priority;
         PCHECK(sched_setscheduler(0, SCHED_FIFO, &param) == 0)
@@ -1643,7 +1644,7 @@
     }
     ::std::cout << "      data: {";
 
-    if (FLAGS_dump_lockless_queue_data) {
+    if (absl::GetFlag(FLAGS_dump_lockless_queue_data)) {
       const char *const m_data = m->data(memory->message_data_size());
       std::cout << absl::BytesToHexString(std::string_view(
           m_data, corrupt ? memory->message_data_size() : m->header.length));
diff --git a/aos/ipc_lib/lockless_queue.h b/aos/ipc_lib/lockless_queue.h
index ce067e6..1fdbb39 100644
--- a/aos/ipc_lib/lockless_queue.h
+++ b/aos/ipc_lib/lockless_queue.h
@@ -11,8 +11,9 @@
 #include <utility>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/events/context.h"
 #include "aos/ipc_lib/aos_sync.h"
diff --git a/aos/ipc_lib/lockless_queue_death_test.cc b/aos/ipc_lib/lockless_queue_death_test.cc
index c61c62c..fa2bdf6 100644
--- a/aos/ipc_lib/lockless_queue_death_test.cc
+++ b/aos/ipc_lib/lockless_queue_death_test.cc
@@ -8,7 +8,8 @@
 #include <optional>
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/context.h"
diff --git a/aos/ipc_lib/lockless_queue_stepping.cc b/aos/ipc_lib/lockless_queue_stepping.cc
index a7bd233..8608ad5 100644
--- a/aos/ipc_lib/lockless_queue_stepping.cc
+++ b/aos/ipc_lib/lockless_queue_stepping.cc
@@ -21,7 +21,8 @@
 #include <thread>
 #include <utility>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/ipc_lib/aos_sync.h"
diff --git a/aos/ipc_lib/lockless_queue_test.cc b/aos/ipc_lib/lockless_queue_test.cc
index 4169c93..bdb9755 100644
--- a/aos/ipc_lib/lockless_queue_test.cc
+++ b/aos/ipc_lib/lockless_queue_test.cc
@@ -17,7 +17,7 @@
 #include <thread>
 #include <type_traits>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/epoll.h"
@@ -29,20 +29,20 @@
 #include "aos/realtime.h"
 #include "aos/util/phased_loop.h"
 
-DEFINE_int32(min_iterations, 100,
-             "Minimum number of stress test iterations to run");
-DEFINE_int32(duration, 5, "Number of seconds to test for");
-DEFINE_int32(print_rate, 60, "Number of seconds between status prints");
+ABSL_FLAG(int32_t, min_iterations, 100,
+          "Minimum number of stress test iterations to run");
+ABSL_FLAG(int32_t, duration, 5, "Number of seconds to test for");
+ABSL_FLAG(int32_t, print_rate, 60, "Number of seconds between status prints");
 
 // The roboRIO can only handle 10 threads before exploding.  Set the default for
 // ARM to 10.
-DEFINE_int32(thread_count,
+ABSL_FLAG(int32_t, thread_count,
 #if defined(__ARM_EABI__)
-             10,
+          10,
 #else
-             100,
+          100,
 #endif
-             "Number of threads to race");
+          "Number of threads to race");
 
 namespace aos::ipc_lib::testing {
 
@@ -299,7 +299,7 @@
 
 // Races a bunch of sending threads to see if it all works.
 TEST_F(LocklessQueueTest, SendRace) {
-  const size_t kNumMessages = 10000 / FLAGS_thread_count;
+  const size_t kNumMessages = 10000 / absl::GetFlag(FLAGS_thread_count);
 
   ::std::mt19937 generator(0);
   ::std::uniform_int_distribution<> write_wrap_count_distribution(0, 10);
@@ -308,17 +308,19 @@
   ::std::bernoulli_distribution should_read_result_distribution;
   ::std::bernoulli_distribution wrap_writes_distribution;
 
-  const chrono::seconds print_frequency(FLAGS_print_rate);
+  const chrono::seconds print_frequency(absl::GetFlag(FLAGS_print_rate));
 
-  QueueRacer racer(queue(), FLAGS_thread_count, kNumMessages);
+  QueueRacer racer(queue(), absl::GetFlag(FLAGS_thread_count), kNumMessages);
   const monotonic_clock::time_point start_time = monotonic_clock::now();
   const monotonic_clock::time_point end_time =
-      start_time + chrono::seconds(FLAGS_duration);
+      start_time + chrono::seconds(absl::GetFlag(FLAGS_duration));
 
   monotonic_clock::time_point monotonic_now = start_time;
   monotonic_clock::time_point next_print_time = start_time + print_frequency;
   uint64_t messages = 0;
-  for (int i = 0; i < FLAGS_min_iterations || monotonic_now < end_time; ++i) {
+  for (int i = 0;
+       i < absl::GetFlag(FLAGS_min_iterations) || monotonic_now < end_time;
+       ++i) {
     const bool race_reads = race_reads_distribution(generator);
     const bool set_should_read = set_should_read_distribution(generator);
     const bool should_read_result = should_read_result_distribution(generator);
@@ -402,7 +404,7 @@
   PinForTest pin_cpu;
   uint64_t kNumMessages = 1000000;
   QueueRacer racer(queue(),
-                   {FLAGS_thread_count,
+                   {absl::GetFlag(FLAGS_thread_count),
                     kNumMessages,
                     {LocklessQueueSender::Result::GOOD,
                      LocklessQueueSender::Result::MESSAGES_SENT_TOO_FAST},
diff --git a/aos/ipc_lib/memory_mapped_queue.cc b/aos/ipc_lib/memory_mapped_queue.cc
index 8daf5a1..9ba21a9 100644
--- a/aos/ipc_lib/memory_mapped_queue.cc
+++ b/aos/ipc_lib/memory_mapped_queue.cc
@@ -11,9 +11,10 @@
 #include <ostream>
 #include <thread>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "flatbuffers/string.h"
-#include "glog/logging.h"
 
 #include "aos/ipc_lib/index.h"
 #include "aos/util/file.h"
diff --git a/aos/ipc_lib/named_pipe_latency.cc b/aos/ipc_lib/named_pipe_latency.cc
index 023853d..240bf78 100644
--- a/aos/ipc_lib/named_pipe_latency.cc
+++ b/aos/ipc_lib/named_pipe_latency.cc
@@ -11,10 +11,12 @@
 #include <ratio>
 #include <thread>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/epoll.h"
+#include "aos/init.h"
 #include "aos/ipc_lib/latency_lib.h"
 #include "aos/logging/implementations.h"
 #include "aos/realtime.h"
@@ -24,37 +26,37 @@
 // It measures both latency of a random timer thread, and latency of the
 // pipe.
 
-DEFINE_bool(sender, true, "If true, send signals to the other process.");
-DEFINE_string(fifo, "/dev/shm/aos/named_pipe_latency",
-              "FIFO to use for the test.");
-DEFINE_int32(seconds, 10, "Duration of the test to run");
-DEFINE_int32(
-    latency_threshold, 1000,
+ABSL_FLAG(bool, sender, true, "If true, send signals to the other process.");
+ABSL_FLAG(std::string, fifo, "/dev/shm/aos/named_pipe_latency",
+          "FIFO to use for the test.");
+ABSL_FLAG(int32_t, seconds, 10, "Duration of the test to run");
+ABSL_FLAG(
+    int32_t, latency_threshold, 1000,
     "Disable tracing when anything takes more than this many microseoncds");
-DEFINE_int32(core, 7, "Core to pin to");
-DEFINE_int32(sender_priority, 53, "RT priority to send at");
-DEFINE_int32(receiver_priority, 52, "RT priority to receive at");
-DEFINE_int32(timer_priority, 51, "RT priority to spin the timer at");
+ABSL_FLAG(int32_t, core, 7, "Core to pin to");
+ABSL_FLAG(int32_t, sender_priority, 53, "RT priority to send at");
+ABSL_FLAG(int32_t, receiver_priority, 52, "RT priority to receive at");
+ABSL_FLAG(int32_t, timer_priority, 51, "RT priority to spin the timer at");
 
-DEFINE_bool(log_latency, false, "If true, log the latency");
+ABSL_FLAG(bool, log_latency, false, "If true, log the latency");
 
 namespace chrono = ::std::chrono;
 
 namespace aos {
 
 void SenderThread() {
-  int pipefd =
-      open(FLAGS_fifo.c_str(), FD_CLOEXEC | O_NONBLOCK | O_WRONLY | O_NOATIME);
+  int pipefd = open(absl::GetFlag(FLAGS_fifo).c_str(),
+                    FD_CLOEXEC | O_NONBLOCK | O_WRONLY | O_NOATIME);
   const monotonic_clock::time_point end_time =
-      monotonic_clock::now() + chrono::seconds(FLAGS_seconds);
+      monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds));
   // Standard mersenne_twister_engine seeded with 0
   ::std::mt19937 generator(0);
 
   // Sleep between 1 and 15 ms.
   ::std::uniform_int_distribution<> distribution(1000, 15000);
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_sender_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_sender_priority));
   while (true) {
     const monotonic_clock::time_point wakeup_time =
         monotonic_clock::now() + chrono::microseconds(distribution(generator));
@@ -83,8 +85,8 @@
 }
 
 void ReceiverThread() {
-  int pipefd =
-      open(FLAGS_fifo.c_str(), O_CLOEXEC | O_NONBLOCK | O_RDONLY | O_NOATIME);
+  int pipefd = open(absl::GetFlag(FLAGS_fifo).c_str(),
+                    O_CLOEXEC | O_NONBLOCK | O_RDONLY | O_NOATIME);
   Tracing t;
   t.Start();
 
@@ -118,21 +120,22 @@
 
     max_wakeup_latency = ::std::max(wakeup_latency, max_wakeup_latency);
 
-    if (wakeup_latency > chrono::microseconds(FLAGS_latency_threshold)) {
+    if (wakeup_latency >
+        chrono::microseconds(absl::GetFlag(FLAGS_latency_threshold))) {
       t.Stop();
       AOS_LOG(INFO, "Stopped tracing, latency %" PRId64 "\n",
               static_cast<int64_t>(wakeup_latency.count()));
     }
 
-    if (FLAGS_log_latency) {
+    if (absl::GetFlag(FLAGS_log_latency)) {
       AOS_LOG(INFO, "dt: %8d.%03d\n",
               static_cast<int>(wakeup_latency.count() / 1000),
               static_cast<int>(wakeup_latency.count() % 1000));
     }
   });
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_receiver_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_receiver_priority));
   epoll.Run();
   UnsetCurrentThreadRealtimePriority();
   epoll.DeleteFd(pipefd);
@@ -152,12 +155,13 @@
 }
 
 int Main(int /*argc*/, char ** /*argv*/) {
-  mkfifo(FLAGS_fifo.c_str(), 0777);
+  mkfifo(absl::GetFlag(FLAGS_fifo).c_str(), 0777);
 
   AOS_LOG(INFO, "Main!\n");
   ::std::thread t([]() {
-    TimerThread(monotonic_clock::now() + chrono::seconds(FLAGS_seconds),
-                FLAGS_timer_priority);
+    TimerThread(
+        monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds)),
+        absl::GetFlag(FLAGS_timer_priority));
   });
 
   ::std::thread st([]() { SenderThread(); });
@@ -172,7 +176,7 @@
 }  // namespace aos
 
 int main(int argc, char **argv) {
-  ::gflags::ParseCommandLineFlags(&argc, &argv, true);
+  aos::InitGoogle(&argc, &argv);
 
   return ::aos::Main(argc, argv);
 }
diff --git a/aos/ipc_lib/print_lockless_queue_memory.cc b/aos/ipc_lib/print_lockless_queue_memory.cc
index 4bad81c..8c6e18d 100644
--- a/aos/ipc_lib/print_lockless_queue_memory.cc
+++ b/aos/ipc_lib/print_lockless_queue_memory.cc
@@ -5,7 +5,8 @@
 
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/ipc_lib/lockless_queue.h"
 
diff --git a/aos/ipc_lib/queue_racer.cc b/aos/ipc_lib/queue_racer.cc
index 67ed6c5..a25d10a 100644
--- a/aos/ipc_lib/queue_racer.cc
+++ b/aos/ipc_lib/queue_racer.cc
@@ -10,8 +10,9 @@
 #include <ostream>
 #include <thread>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/context.h"
diff --git a/aos/ipc_lib/robust_ownership_tracker.h b/aos/ipc_lib/robust_ownership_tracker.h
index 34c8b7a..bc2db17 100644
--- a/aos/ipc_lib/robust_ownership_tracker.h
+++ b/aos/ipc_lib/robust_ownership_tracker.h
@@ -13,7 +13,8 @@
 #include <ostream>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/ipc_lib/aos_sync.h"
 #include "aos/util/top.h"
diff --git a/aos/ipc_lib/shared_mem.cc b/aos/ipc_lib/shared_mem.cc
index 30dd173..861f02e 100644
--- a/aos/ipc_lib/shared_mem.cc
+++ b/aos/ipc_lib/shared_mem.cc
@@ -12,7 +12,8 @@
 #include <cstring>
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/ipc_lib/aos_sync.h"
 
diff --git a/aos/ipc_lib/shm_base.cc b/aos/ipc_lib/shm_base.cc
index 5db25d3..eebed6f 100644
--- a/aos/ipc_lib/shm_base.cc
+++ b/aos/ipc_lib/shm_base.cc
@@ -2,10 +2,15 @@
 
 #include <string>
 
-DEFINE_string(shm_base, "/dev/shm/aos",
-              "Directory to place queue backing mmaped files in.");
+#include "absl/flags/flag.h"
+
+ABSL_FLAG(std::string, shm_base, "/dev/shm/aos",
+          "Directory to place queue backing mmaped files in.");
+
 namespace aos::testing {
+
 void SetShmBase(const std::string_view base) {
-  FLAGS_shm_base = std::string(base) + "/aos";
+  absl::SetFlag(&FLAGS_shm_base, std::string(base) + "/aos");
 }
+
 }  // namespace aos::testing
diff --git a/aos/ipc_lib/shm_base.h b/aos/ipc_lib/shm_base.h
index 1d06a69..9a56d29 100644
--- a/aos/ipc_lib/shm_base.h
+++ b/aos/ipc_lib/shm_base.h
@@ -3,11 +3,12 @@
 
 #include <string_view>
 
-#include "gflags/gflags.h"
+#include "absl/flags/declare.h"
 
-DECLARE_string(shm_base);
+ABSL_DECLARE_FLAG(std::string, shm_base);
 
 namespace aos::testing {
 void SetShmBase(const std::string_view base);
 }
+
 #endif  // AOS_IPC_LIB_SHM_BASE_H_
diff --git a/aos/ipc_lib/signal_stress.cc b/aos/ipc_lib/signal_stress.cc
index b2749af..d5d1323 100644
--- a/aos/ipc_lib/signal_stress.cc
+++ b/aos/ipc_lib/signal_stress.cc
@@ -10,10 +10,12 @@
 #include <ratio>
 #include <thread>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/epoll.h"
+#include "aos/init.h"
 #include "aos/ipc_lib/latency_lib.h"
 #include "aos/logging/implementations.h"
 #include "aos/realtime.h"
@@ -26,18 +28,18 @@
 // To enable function graph:
 //   echo "function_graph" > current_tracer
 
-DEFINE_bool(sender, true, "If true, send signals to the other process.");
-DEFINE_int32(other_pid, -1, "PID of other process to ping");
-DEFINE_int32(seconds, 10, "Duration of the test to run");
-DEFINE_int32(
-    latency_threshold, 1000,
+ABSL_FLAG(bool, sender, true, "If true, send signals to the other process.");
+ABSL_FLAG(int32_t, other_pid, -1, "PID of other process to ping");
+ABSL_FLAG(int32_t, seconds, 10, "Duration of the test to run");
+ABSL_FLAG(
+    int32_t, latency_threshold, 1000,
     "Disable tracing when anything takes more than this many microseoncds");
-DEFINE_int32(core, 7, "Core to pin to");
-DEFINE_int32(sender_priority, 53, "RT priority to send at");
-DEFINE_int32(receiver_priority, 52, "RT priority to receive at");
-DEFINE_int32(timer_priority, 51, "RT priority to spin the timer at");
+ABSL_FLAG(int32_t, core, 7, "Core to pin to");
+ABSL_FLAG(int32_t, sender_priority, 53, "RT priority to send at");
+ABSL_FLAG(int32_t, receiver_priority, 52, "RT priority to receive at");
+ABSL_FLAG(int32_t, timer_priority, 51, "RT priority to spin the timer at");
 
-DEFINE_bool(log_latency, false, "If true, log the latency");
+ABSL_FLAG(bool, log_latency, false, "If true, log the latency");
 
 const uint32_t kSignalNumber = SIGRTMIN + 1;
 const uint32_t kQuitSignalNumber = SIGRTMIN + 2;
@@ -48,7 +50,7 @@
 
 void SenderThread() {
   const monotonic_clock::time_point end_time =
-      monotonic_clock::now() + chrono::seconds(FLAGS_seconds);
+      monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds));
   // Standard mersenne_twister_engine seeded with 0
   ::std::mt19937 generator(0);
 
@@ -56,13 +58,13 @@
   ::std::uniform_int_distribution<> distribution(1000, 15000);
 
   int pid = getpid();
-  if (FLAGS_other_pid != -1) {
-    pid = FLAGS_other_pid;
+  if (absl::GetFlag(FLAGS_other_pid) != -1) {
+    pid = absl::GetFlag(FLAGS_other_pid);
   }
   AOS_LOG(INFO, "Current PID: %d\n", pid);
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_sender_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_sender_priority));
   while (true) {
     const monotonic_clock::time_point wakeup_time =
         monotonic_clock::now() + chrono::microseconds(distribution(generator));
@@ -137,21 +139,22 @@
 
     max_wakeup_latency = ::std::max(wakeup_latency, max_wakeup_latency);
 
-    if (wakeup_latency > chrono::microseconds(FLAGS_latency_threshold)) {
+    if (wakeup_latency >
+        chrono::microseconds(absl::GetFlag(FLAGS_latency_threshold))) {
       t.Stop();
       AOS_LOG(INFO, "Stopped tracing, latency %" PRId64 "\n",
               static_cast<int64_t>(wakeup_latency.count()));
     }
 
-    if (FLAGS_log_latency) {
+    if (absl::GetFlag(FLAGS_log_latency)) {
       AOS_LOG(INFO, "signo: %d, sending pid: %d, dt: %8d.%03d\n", si.ssi_signo,
               si.ssi_pid, static_cast<int>(wakeup_latency_int64 / 1000),
               static_cast<int>(wakeup_latency_int64 % 1000));
     }
   });
 
-  SetCurrentThreadAffinity(MakeCpusetFromCpus({FLAGS_core}));
-  SetCurrentThreadRealtimePriority(FLAGS_receiver_priority);
+  SetCurrentThreadAffinity(MakeCpusetFromCpus({absl::GetFlag(FLAGS_core)}));
+  SetCurrentThreadRealtimePriority(absl::GetFlag(FLAGS_receiver_priority));
   epoll.Run();
   UnsetCurrentThreadRealtimePriority();
   epoll.DeleteFd(signalfd_fd);
@@ -178,8 +181,9 @@
 
   AOS_LOG(INFO, "Main!\n");
   ::std::thread t([]() {
-    TimerThread(monotonic_clock::now() + chrono::seconds(FLAGS_seconds),
-                FLAGS_timer_priority);
+    TimerThread(
+        monotonic_clock::now() + chrono::seconds(absl::GetFlag(FLAGS_seconds)),
+        absl::GetFlag(FLAGS_timer_priority));
   });
 
   ::std::thread st([]() { SenderThread(); });
@@ -194,7 +198,7 @@
 }  // namespace aos
 
 int main(int argc, char **argv) {
-  ::gflags::ParseCommandLineFlags(&argc, &argv, true);
+  aos::InitGoogle(&argc, &argv);
 
   return ::aos::Main(argc, argv);
 }
diff --git a/aos/ipc_lib/signalfd.cc b/aos/ipc_lib/signalfd.cc
index c9634a5..9f3c972 100644
--- a/aos/ipc_lib/signalfd.cc
+++ b/aos/ipc_lib/signalfd.cc
@@ -12,7 +12,8 @@
 
 #include <initializer_list>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos::ipc_lib {
 namespace {
diff --git a/aos/ipc_lib/signalfd_test.cc b/aos/ipc_lib/signalfd_test.cc
index 025d66b..bc6f460 100644
--- a/aos/ipc_lib/signalfd_test.cc
+++ b/aos/ipc_lib/signalfd_test.cc
@@ -3,7 +3,8 @@
 #include <memory>
 #include <thread>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/testing/test_logging.h"
diff --git a/aos/json_to_flatbuffer.cc b/aos/json_to_flatbuffer.cc
index 3f049d7..2a19557 100644
--- a/aos/json_to_flatbuffer.cc
+++ b/aos/json_to_flatbuffer.cc
@@ -4,9 +4,10 @@
 #include <cstdio>
 #include <string_view>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
 #include "flatbuffers/minireflect.h"
-#include "glog/logging.h"
 
 #include "aos/flatbuffer_utils.h"
 #include "aos/json_tokenizer.h"
diff --git a/aos/libc/BUILD b/aos/libc/BUILD
index 9bfd365..8385ebb 100644
--- a/aos/libc/BUILD
+++ b/aos/libc/BUILD
@@ -10,7 +10,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/libc/aos_strsignal.cc b/aos/libc/aos_strsignal.cc
index 6a91973..d8dd914 100644
--- a/aos/libc/aos_strsignal.cc
+++ b/aos/libc/aos_strsignal.cc
@@ -6,7 +6,8 @@
 
 #include <csignal>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 const char *aos_strsignal(int signal) {
   thread_local char buffer[512];
diff --git a/aos/logging/BUILD b/aos/logging/BUILD
index b08f465..0ba90a9 100644
--- a/aos/logging/BUILD
+++ b/aos/logging/BUILD
@@ -23,7 +23,8 @@
         "//aos:macros",
         "//aos/libc:aos_strerror",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -36,7 +37,8 @@
     deps = [
         "//aos:configuration",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -49,7 +51,8 @@
     deps = [
         ":logging",
         "//aos/testing:googletest",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -83,7 +86,8 @@
     deps = [
         ":dynamic_log_command_fbs",
         "//aos/events:shm_event_loop",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/logging/context.cc b/aos/logging/context.cc
index 00b7f3c..66ece05 100644
--- a/aos/logging/context.cc
+++ b/aos/logging/context.cc
@@ -21,7 +21,8 @@
 extern char *program_invocation_name;
 extern char *program_invocation_short_name;
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos::logging::internal {
 namespace {
diff --git a/aos/logging/dynamic_logging.cc b/aos/logging/dynamic_logging.cc
index 48c9dcb..4ed4ea3 100644
--- a/aos/logging/dynamic_logging.cc
+++ b/aos/logging/dynamic_logging.cc
@@ -3,8 +3,10 @@
 #include <ostream>
 #include <string_view>
 
+#include "absl/log/check.h"
+#include "absl/log/globals.h"
+#include "absl/log/log.h"
 #include "flatbuffers/string.h"
-#include "glog/logging.h"
 
 namespace aos::logging {
 
@@ -31,7 +33,7 @@
   if (command.vlog_level() < 0) {
     return;
   }
-  FLAGS_v = command.vlog_level();
+  absl::SetGlobalVLogLevel(command.vlog_level());
 }
 
 }  // namespace aos::logging
diff --git a/aos/logging/dynamic_logging_test.cc b/aos/logging/dynamic_logging_test.cc
index 21e0c36..449d7ac 100644
--- a/aos/logging/dynamic_logging_test.cc
+++ b/aos/logging/dynamic_logging_test.cc
@@ -4,9 +4,10 @@
 #include <memory>
 #include <ostream>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/flatbuffer_builder.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
diff --git a/aos/logging/implementations_test.cc b/aos/logging/implementations_test.cc
index 08fdc7b..62d5f1e 100644
--- a/aos/logging/implementations_test.cc
+++ b/aos/logging/implementations_test.cc
@@ -7,7 +7,8 @@
 #include <cinttypes>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/logging/printf_formats.h"
diff --git a/aos/logging/interface.cc b/aos/logging/interface.cc
index 326f28e..a630285 100644
--- a/aos/logging/interface.cc
+++ b/aos/logging/interface.cc
@@ -9,7 +9,8 @@
 #include <string>
 #include <type_traits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/die.h"
 #include "aos/logging/context.h"
diff --git a/aos/logging/log_namer.cc b/aos/logging/log_namer.cc
index d5005bb..0e68e7b 100644
--- a/aos/logging/log_namer.cc
+++ b/aos/logging/log_namer.cc
@@ -11,8 +11,9 @@
 #include <ostream>
 #include <string>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/time/time.h"
@@ -23,14 +24,14 @@
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
 #endif
 
-DEFINE_string(logging_folder,
+ABSL_FLAG(std::string, logging_folder,
 #ifdef AOS_ARCHITECTURE_arm_frc
-              "",
+          "",
 #else
-              "./logs",
+          "./logs",
 #endif
-              "The folder to log to.  If empty, search for the /media/sd*1/ "
-              "folder and place logs there.");
+          "The folder to log to.  If empty, search for the /media/sd*1/ "
+          "folder and place logs there.");
 
 namespace aos::logging {
 namespace {
@@ -126,7 +127,7 @@
 }  // namespace
 
 std::optional<std::string> MaybeGetLogName(const char *basename) {
-  if (FLAGS_logging_folder.empty()) {
+  if (absl::GetFlag(FLAGS_logging_folder).empty()) {
     char folder[128];
     {
       char dev_name[8];
@@ -147,23 +148,23 @@
                  << "' does not exist. please create it.";
     }
 
-    FLAGS_logging_folder = folder;
+    absl::SetFlag(&FLAGS_logging_folder, folder);
   }
-  const char *folder = FLAGS_logging_folder.c_str();
-  if (access(folder, R_OK | W_OK) == -1) {
+  const std::string folder = absl::GetFlag(FLAGS_logging_folder);
+  if (access(folder.c_str(), R_OK | W_OK) == -1) {
     LOG(FATAL) << "folder '" << folder << "' does not exist. please create it.";
   }
   LOG(INFO) << "logging to folder '" << folder << "'";
 
   char *tmp;
-  AllocateLogName(&tmp, folder, basename);
+  AllocateLogName(&tmp, folder.c_str(), basename);
 
   std::string log_base_name = tmp;
   std::string log_roborio_name = log_base_name + "/";
   free(tmp);
 
   char *tmp2;
-  if (asprintf(&tmp2, "%s/%s-current", folder, basename) == -1) {
+  if (asprintf(&tmp2, "%s/%s-current", folder.c_str(), basename) == -1) {
     PLOG(WARNING) << "couldn't create current symlink name";
   } else {
     if (unlink(tmp2) == -1 && (errno != EROFS && errno != ENOENT)) {
diff --git a/aos/mutex/BUILD b/aos/mutex/BUILD
index d079a02..d3fea1f 100644
--- a/aos/mutex/BUILD
+++ b/aos/mutex/BUILD
@@ -12,7 +12,8 @@
     deps = [
         "//aos/ipc_lib:aos_sync",
         "//aos/type_traits",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -29,6 +30,7 @@
         "//aos/testing:test_shm",
         "//aos/time",
         "//aos/util:death_test_log_implementation",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/aos/mutex/mutex.cc b/aos/mutex/mutex.cc
index 30a9534..4a3fb25 100644
--- a/aos/mutex/mutex.cc
+++ b/aos/mutex/mutex.cc
@@ -1,6 +1,7 @@
 #include "aos/mutex/mutex.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos {
 
diff --git a/aos/mutex/mutex.h b/aos/mutex/mutex.h
index dfc212a..c40917a 100644
--- a/aos/mutex/mutex.h
+++ b/aos/mutex/mutex.h
@@ -3,7 +3,8 @@
 
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/ipc_lib/aos_sync.h"
 #include "aos/macros.h"
diff --git a/aos/network/BUILD b/aos/network/BUILD
index 96f8b50..57dba97 100644
--- a/aos/network/BUILD
+++ b/aos/network/BUILD
@@ -173,7 +173,9 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -203,7 +205,9 @@
     deps = [
         "//aos:unique_malloc_ptr",
         "//aos/util:file",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -290,8 +294,9 @@
         ":remote_message_fbs",
         "//aos:configuration",
         "//aos/events:event_loop",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/container:btree",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -353,6 +358,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         ":sctp_lib",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -713,8 +719,9 @@
         "//aos/mutex",
         "//aos/seasocks:seasocks_logger",
         "//third_party/seasocks",
-        "@com_github_google_glog//:glog",
         "@com_github_rawrtc_rawrtc//:rawrtc",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -926,5 +933,7 @@
         ":sctp_server",
         "//aos:init",
         "//aos/events:shm_event_loop",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/flags:usage",
     ],
 )
diff --git a/aos/network/log_web_proxy_main.cc b/aos/network/log_web_proxy_main.cc
index 12276c3..dc55ff1 100644
--- a/aos/network/log_web_proxy_main.cc
+++ b/aos/network/log_web_proxy_main.cc
@@ -4,7 +4,8 @@
 // /path/to/logfile And then opening the plotting webpage at
 // http://localhost:8080/graph.html
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -13,13 +14,14 @@
 #include "aos/init.h"
 #include "aos/network/web_proxy.h"
 
-DEFINE_string(data_dir, "www", "Directory to serve data files from");
-DEFINE_string(node, "", "Directory to serve data files from");
-DEFINE_int32(buffer_size, -1, "-1 if infinite, in # of messages / channel.");
-DEFINE_double(monotonic_start_time, -1.0, "Start time (sec)");
-DEFINE_double(monotonic_end_time, -1.0, "End time (sec)");
-DEFINE_double(
-    replay_rate, -1,
+ABSL_FLAG(std::string, data_dir, "www", "Directory to serve data files from");
+ABSL_FLAG(std::string, node, "", "Directory to serve data files from");
+ABSL_FLAG(int32_t, buffer_size, -1,
+          "-1 if infinite, in # of messages / channel.");
+ABSL_FLAG(double, monotonic_start_time, -1.0, "Start time (sec)");
+ABSL_FLAG(double, monotonic_end_time, -1.0, "End time (sec)");
+ABSL_FLAG(
+    double, replay_rate, -1,
     "-1 to replay as fast as possible; 1.0 = realtime, 0.5 = half speed.");
 
 int main(int argc, char **argv) {
@@ -34,44 +36,46 @@
 
   // If going for "as fast as possible" don't actually use infinity, because we
   // don't want the log reading blocking our use of the epoll handlers.
-  reader.SetRealtimeReplayRate(FLAGS_replay_rate == -1.0
+  reader.SetRealtimeReplayRate(absl::GetFlag(FLAGS_replay_rate) == -1.0
                                    ? std::numeric_limits<double>::max()
-                                   : FLAGS_replay_rate);
+                                   : absl::GetFlag(FLAGS_replay_rate));
 
   std::unique_ptr<aos::EventLoop> event_loop;
 
-  if (FLAGS_node.empty()) {
+  if (absl::GetFlag(FLAGS_node).empty()) {
     CHECK(!aos::configuration::MultiNode(reader.configuration()))
         << "If using a multi-node logfile, please specify --node.";
     event_loop = reader.event_loop_factory()->MakeEventLoop("web_proxy");
   } else {
     event_loop = reader.event_loop_factory()->MakeEventLoop(
-        "web_proxy",
-        aos::configuration::GetNode(reader.configuration(), FLAGS_node));
+        "web_proxy", aos::configuration::GetNode(reader.configuration(),
+                                                 absl::GetFlag(FLAGS_node)));
   }
 
   event_loop->SkipTimingReport();
 
-  if (FLAGS_monotonic_start_time > 0) {
+  if (absl::GetFlag(FLAGS_monotonic_start_time) > 0) {
     event_loop->AddTimer([&reader]() { reader.event_loop_factory()->Exit(); })
         ->Schedule(aos::monotonic_clock::time_point(
             std::chrono::duration_cast<std::chrono::nanoseconds>(
-                std::chrono::duration<double>(FLAGS_monotonic_start_time))));
+                std::chrono::duration<double>(
+                    absl::GetFlag(FLAGS_monotonic_start_time)))));
 
     reader.event_loop_factory()->Run();
   }
 
   aos::web_proxy::WebProxy web_proxy(
       event_loop.get(), reader.event_loop_factory()->scheduler_epoll(),
-      aos::web_proxy::StoreHistory::kYes, FLAGS_buffer_size);
+      aos::web_proxy::StoreHistory::kYes, absl::GetFlag(FLAGS_buffer_size));
 
-  web_proxy.SetDataPath(FLAGS_data_dir.c_str());
+  web_proxy.SetDataPath(absl::GetFlag(FLAGS_data_dir).c_str());
 
-  if (FLAGS_monotonic_end_time > 0) {
+  if (absl::GetFlag(FLAGS_monotonic_end_time) > 0) {
     event_loop->AddTimer([&web_proxy]() { web_proxy.StopRecording(); })
         ->Schedule(aos::monotonic_clock::time_point(
             std::chrono::duration_cast<std::chrono::nanoseconds>(
-                std::chrono::duration<double>(FLAGS_monotonic_end_time))));
+                std::chrono::duration<double>(
+                    absl::GetFlag(FLAGS_monotonic_end_time)))));
   }
 
   reader.event_loop_factory()->Run();
diff --git a/aos/network/message_bridge_auth_client_lib.cc b/aos/network/message_bridge_auth_client_lib.cc
index c277b4f..2b520ba 100644
--- a/aos/network/message_bridge_auth_client_lib.cc
+++ b/aos/network/message_bridge_auth_client_lib.cc
@@ -2,7 +2,8 @@
 
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "aos/network/message_bridge_auth.grpc.pb.h"
diff --git a/aos/network/message_bridge_auth_server_lib.cc b/aos/network/message_bridge_auth_server_lib.cc
index 6a9dc7e..f2a03c8 100644
--- a/aos/network/message_bridge_auth_server_lib.cc
+++ b/aos/network/message_bridge_auth_server_lib.cc
@@ -3,7 +3,8 @@
 #include <cstdio>
 #include <fstream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "grpc/grpc.h"
 #include "grpcpp/server_context.h"
diff --git a/aos/network/message_bridge_client.cc b/aos/network/message_bridge_client.cc
index 4a1992a..e6b71ea 100644
--- a/aos/network/message_bridge_client.cc
+++ b/aos/network/message_bridge_client.cc
@@ -1,3 +1,5 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/logging/dynamic_logging.h"
@@ -6,11 +8,10 @@
 #include "aos/sha256.h"
 #include "aos/util/file.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config.");
-DEFINE_int32(rt_priority, -1, "If > 0, run as this RT priority");
-DEFINE_bool(
-    wants_sctp_authentication, false,
-    "When set, try to use SCTP authentication if provided by the kernel");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the config.");
+ABSL_FLAG(int32_t, rt_priority, -1, "If > 0, run as this RT priority");
+ABSL_FLAG(bool, wants_sctp_authentication, false,
+          "When set, try to use SCTP authentication if provided by the kernel");
 
 namespace aos::message_bridge {
 
@@ -18,15 +19,15 @@
 
 int Main() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
-  if (FLAGS_rt_priority > 0) {
-    event_loop.SetRuntimeRealtimePriority(FLAGS_rt_priority);
+  if (absl::GetFlag(FLAGS_rt_priority) > 0) {
+    event_loop.SetRuntimeRealtimePriority(absl::GetFlag(FLAGS_rt_priority));
   }
 
   MessageBridgeClient app(&event_loop, Sha256(config.span()),
-                          FLAGS_wants_sctp_authentication
+                          absl::GetFlag(FLAGS_wants_sctp_authentication)
                               ? SctpAuthMethod::kAuth
                               : SctpAuthMethod::kNoAuth);
 
diff --git a/aos/network/message_bridge_client_lib.cc b/aos/network/message_bridge_client_lib.cc
index cf52a69..d9fa91d 100644
--- a/aos/network/message_bridge_client_lib.cc
+++ b/aos/network/message_bridge_client_lib.cc
@@ -3,8 +3,9 @@
 #include <chrono>
 #include <string_view>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/shm_event_loop.h"
@@ -24,7 +25,7 @@
 #pragma clang diagnostic ignored "-Wcast-align"
 #endif
 
-DECLARE_bool(use_sctp_authentication);
+ABSL_DECLARE_FLAG(bool, use_sctp_authentication);
 
 // This application receives messages from another node and re-publishes them on
 // this node.
diff --git a/aos/network/message_bridge_retry_test.cc b/aos/network/message_bridge_retry_test.cc
index e90bcb0..52ed3c9 100644
--- a/aos/network/message_bridge_retry_test.cc
+++ b/aos/network/message_bridge_retry_test.cc
@@ -1,6 +1,7 @@
 #include <chrono>
 #include <thread>
 
+#include "absl/flags/declare.h"
 #include "absl/strings/str_cat.h"
 #include "gtest/gtest.h"
 
@@ -16,7 +17,7 @@
 #include "aos/testing/path.h"
 #include "aos/util/file.h"
 
-DECLARE_int32(force_wmem_max);
+ABSL_DECLARE_FLAG(int32_t, force_wmem_max);
 
 namespace aos::message_bridge::testing {
 
@@ -37,10 +38,10 @@
 // message_bridge_test, so we kept it separate.
 TEST_P(MessageBridgeParameterizedTest, ReliableRetries) {
   // Set an absurdly small wmem max. This will help to trigger retries.
-  FLAGS_force_wmem_max = 1024;
+  absl::SetFlag(&FLAGS_force_wmem_max, 1024);
   pi1_.OnPi();
 
-  FLAGS_application_name = "sender";
+  absl::SetFlag(&FLAGS_application_name, "sender");
   aos::ShmEventLoop send_event_loop(&config_.message());
   aos::Sender<examples::Ping> ping_sender =
       send_event_loop.MakeSender<examples::Ping>("/test");
diff --git a/aos/network/message_bridge_server.cc b/aos/network/message_bridge_server.cc
index 64c57f5..2df5704 100644
--- a/aos/network/message_bridge_server.cc
+++ b/aos/network/message_bridge_server.cc
@@ -1,5 +1,6 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
@@ -8,11 +9,10 @@
 #include "aos/network/sctp_lib.h"
 #include "aos/sha256.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config.");
-DEFINE_int32(rt_priority, -1, "If > 0, run as this RT priority");
-DEFINE_bool(
-    wants_sctp_authentication, false,
-    "When set, try to use SCTP authentication if provided by the kernel");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the config.");
+ABSL_FLAG(int32_t, rt_priority, -1, "If > 0, run as this RT priority");
+ABSL_FLAG(bool, wants_sctp_authentication, false,
+          "When set, try to use SCTP authentication if provided by the kernel");
 
 namespace aos::message_bridge {
 
@@ -20,15 +20,15 @@
 
 int Main() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
-  if (FLAGS_rt_priority > 0) {
-    event_loop.SetRuntimeRealtimePriority(FLAGS_rt_priority);
+  if (absl::GetFlag(FLAGS_rt_priority) > 0) {
+    event_loop.SetRuntimeRealtimePriority(absl::GetFlag(FLAGS_rt_priority));
   }
 
   MessageBridgeServer app(&event_loop, Sha256(config.span()),
-                          FLAGS_wants_sctp_authentication
+                          absl::GetFlag(FLAGS_wants_sctp_authentication)
                               ? SctpAuthMethod::kAuth
                               : SctpAuthMethod::kNoAuth);
 
diff --git a/aos/network/message_bridge_server_lib.cc b/aos/network/message_bridge_server_lib.cc
index a3f429a..7f6ad53 100644
--- a/aos/network/message_bridge_server_lib.cc
+++ b/aos/network/message_bridge_server_lib.cc
@@ -1,9 +1,10 @@
 #include "aos/network/message_bridge_server_lib.h"
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
-#include "glog/raw_logging.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/logger_generated.h"
@@ -31,31 +32,31 @@
 // that hopefully it is a relatively minor blip for anything that isn't
 // timing-critical (and timing-critical things that hit the retry logic are
 // probably in trouble).
-DEFINE_uint32(min_retry_period_ms, 10,
-              "Maximum retry timer period--the exponential backoff will not "
-              "exceed this period, in milliseconds.");
+ABSL_FLAG(uint32_t, min_retry_period_ms, 10,
+          "Maximum retry timer period--the exponential backoff will not "
+          "exceed this period, in milliseconds.");
 // Amount of backoff to add every time a retry fails. Chosen semi-arbitrarily;
 // 100ms is large enough that the backoff actually does increase at a reasonable
 // rate, while preventing the period from growing so fast that it can readily
 // take multiple seconds for a retry to occur.
-DEFINE_uint32(retry_period_additive_backoff_ms, 100,
-              "Amount of time to add to the retry period every time a retry "
-              "fails, in milliseconds.");
+ABSL_FLAG(uint32_t, retry_period_additive_backoff_ms, 100,
+          "Amount of time to add to the retry period every time a retry "
+          "fails, in milliseconds.");
 // Max out retry period at 10 seconds---this is generally a much longer
 // timescale than anything normally happening on our systems, while still being
 // short enough that the retries will regularly happen (basically, the maximum
 // should be short enough that a human trying to debug issues with the system
 // will still see the retries regularly happening as they debug, rather than
 // having to wait minutes or hours for a retry to occur).
-DEFINE_uint32(max_retry_period_ms, 10000,
-              "Maximum retry timer period--the additive backoff will not "
-              "exceed this period, in milliseconds.");
+ABSL_FLAG(uint32_t, max_retry_period_ms, 10000,
+          "Maximum retry timer period--the additive backoff will not "
+          "exceed this period, in milliseconds.");
 
-DEFINE_int32(force_wmem_max, -1,
-             "If set to a nonnegative numbers, the wmem buffer size to use, in "
-             "bytes. Intended solely for testing purposes.");
+ABSL_FLAG(int32_t, force_wmem_max, -1,
+          "If set to a nonnegative numbers, the wmem buffer size to use, in "
+          "bytes. Intended solely for testing purposes.");
 
-DECLARE_bool(use_sctp_authentication);
+ABSL_DECLARE_FLAG(bool, use_sctp_authentication);
 
 namespace aos::message_bridge {
 namespace chrono = std::chrono;
@@ -115,7 +116,8 @@
       allocator_(allocator),
       last_message_fetcher_(event_loop->MakeRawFetcher(channel)),
       retry_timer_(event_loop->AddTimer([this]() { SendData(); })),
-      retry_period_(std::chrono::milliseconds(FLAGS_min_retry_period_ms)) {
+      retry_period_(
+          std::chrono::milliseconds(absl::GetFlag(FLAGS_min_retry_period_ms))) {
   retry_timer_->set_name(absl::StrFormat("retry%d", channel_index));
 }
 
@@ -164,7 +166,8 @@
   // either (a) we run out of messages to send or (b) sends start to fail.
   do {
     if (ReadyToFetchNext()) {
-      retry_period_ = std::chrono::milliseconds(FLAGS_min_retry_period_ms);
+      retry_period_ =
+          std::chrono::milliseconds(absl::GetFlag(FLAGS_min_retry_period_ms));
       if (!last_message_fetcher_->FetchNext()) {
         return;
       }
@@ -231,9 +234,9 @@
   if (retry_required) {
     retry_timer_->Schedule(event_loop_->monotonic_now() + retry_period_);
     retry_period_ = std::min(
-        retry_period_ +
-            std::chrono::milliseconds(FLAGS_retry_period_additive_backoff_ms),
-        std::chrono::milliseconds(FLAGS_max_retry_period_ms));
+        retry_period_ + std::chrono::milliseconds(absl::GetFlag(
+                            FLAGS_retry_period_additive_backoff_ms)),
+        std::chrono::milliseconds(absl::GetFlag(FLAGS_max_retry_period_ms)));
   }
 
   if (logged_remotely) {
@@ -369,13 +372,13 @@
         reconnected->push_back(peer.sac_assoc_id);
         if (peer.sac_assoc_id == assoc_id) {
           if (VLOG_IS_ON(1)) {
-            LOG_EVERY_T(WARNING, 0.025)
+            LOG_EVERY_N_SEC(WARNING, 0.025)
                 << "Node " << node->name()->string_view() << " reconnecting on "
                 << assoc_id << " with the same ID, something got lost";
           }
         } else {
           if (VLOG_IS_ON(1)) {
-            LOG_EVERY_T(WARNING, 0.025)
+            LOG_EVERY_N_SEC(WARNING, 0.025)
                 << "Node " << node->name()->string_view() << " "
                 << " already connected on " << peer.sac_assoc_id
                 << " aborting old connection and switching to " << assoc_id;
@@ -395,7 +398,8 @@
       if (!AnyNodeConnected()) {
         // If no one else is connected yet, reset the Fetcher.
         last_message_fetcher_->Fetch();
-        retry_period_ = std::chrono::milliseconds(FLAGS_min_retry_period_ms);
+        retry_period_ =
+            std::chrono::milliseconds(absl::GetFlag(FLAGS_min_retry_period_ms));
       }
       // Unreliable channels aren't supposed to send out the latest fetched
       // message.
@@ -581,8 +585,8 @@
   LOG(INFO) << "Reliable buffer size for all clients is "
             << reliable_buffer_size;
   server_.SetMaxReadSize(max_size);
-  if (FLAGS_force_wmem_max >= 0) {
-    server_.SetMaxWriteSize(FLAGS_force_wmem_max);
+  if (absl::GetFlag(FLAGS_force_wmem_max) >= 0) {
+    server_.SetMaxWriteSize(absl::GetFlag(FLAGS_force_wmem_max));
   } else {
     server_.SetMaxWriteSize(
         std::max(max_channel_buffer_size, reliable_buffer_size));
@@ -696,7 +700,7 @@
       flatbuffers::Verifier verifier(message->data(), message->size);
       if (!connect->Verify(verifier)) {
         if (VLOG_IS_ON(1)) {
-          LOG_EVERY_T(WARNING, 1.0)
+          LOG_EVERY_N_SEC(WARNING, 1.0)
               << "Failed to verify message, disconnecting client";
         }
         server_.Abort(message->header.rcvinfo.rcv_assoc_id);
diff --git a/aos/network/message_bridge_server_lib.h b/aos/network/message_bridge_server_lib.h
index 1c3903f..1b20743 100644
--- a/aos/network/message_bridge_server_lib.h
+++ b/aos/network/message_bridge_server_lib.h
@@ -3,8 +3,9 @@
 
 #include <deque>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/logger_generated.h"
diff --git a/aos/network/message_bridge_test.cc b/aos/network/message_bridge_test.cc
index 350cf26..a923f81 100644
--- a/aos/network/message_bridge_test.cc
+++ b/aos/network/message_bridge_test.cc
@@ -1,6 +1,9 @@
 #include <chrono>
 #include <thread>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "gtest/gtest.h"
 
@@ -54,7 +57,7 @@
   const std::string long_data = std::string(10000, 'a');
 
   // And build the app which sends the pings.
-  FLAGS_application_name = "ping";
+  absl::SetFlag(&FLAGS_application_name, "ping");
   aos::ShmEventLoop ping_event_loop(&config_.message());
   aos::Sender<examples::Ping> ping_sender =
       ping_event_loop.MakeSender<examples::Ping>("/test");
@@ -78,11 +81,11 @@
   pi2_.MakeServer();
 
   // And build the app which sends the pongs.
-  FLAGS_application_name = "pong";
+  absl::SetFlag(&FLAGS_application_name, "pong");
   aos::ShmEventLoop pong_event_loop(&config_.message());
 
   // And build the app for testing.
-  FLAGS_application_name = "test";
+  absl::SetFlag(&FLAGS_application_name, "test");
   aos::ShmEventLoop test_event_loop(&config_.message());
 
   aos::Fetcher<ClientStatistics> client_statistics_fetcher =
@@ -112,7 +115,7 @@
     VLOG(1) << "Got ping back " << FlatbufferToJson(&ping);
   });
 
-  FLAGS_override_hostname = "";
+  absl::SetFlag(&FLAGS_override_hostname, "");
 
   // Wait until we are connected, then send.
   int ping_count = 0;
@@ -805,7 +808,7 @@
 TEST_P(MessageBridgeParameterizedTest, ReliableSentBeforeClientStartup) {
   pi1_.OnPi();
 
-  FLAGS_application_name = "sender";
+  absl::SetFlag(&FLAGS_application_name, "sender");
   aos::ShmEventLoop send_event_loop(&config_.message());
   aos::Sender<examples::Ping> ping_sender =
       send_event_loop.MakeSender<examples::Ping>("/test");
@@ -817,7 +820,7 @@
   pi1_.MakeServer();
   pi1_.MakeClient();
 
-  FLAGS_application_name = "pi1_timestamp";
+  absl::SetFlag(&FLAGS_application_name, "pi1_timestamp");
   aos::ShmEventLoop pi1_remote_timestamp_event_loop(&config_.message());
 
   // Now do it for "raspberrypi2", the client.
@@ -953,7 +956,7 @@
   // Force ourselves to be "raspberrypi" and allocate everything.
   pi1_.OnPi();
 
-  FLAGS_application_name = "sender";
+  absl::SetFlag(&FLAGS_application_name, "sender");
   aos::ShmEventLoop send_event_loop(&config_.message());
   aos::Sender<examples::Ping> ping_sender =
       send_event_loop.MakeSender<examples::Ping>("/test");
@@ -967,7 +970,7 @@
 
   pi1_.MakeClient();
 
-  FLAGS_application_name = "pi1_timestamp";
+  absl::SetFlag(&FLAGS_application_name, "pi1_timestamp");
   aos::ShmEventLoop pi1_remote_timestamp_event_loop(&config_.message());
 
   const size_t ping_channel_index = configuration::ChannelIndex(
@@ -1077,7 +1080,7 @@
 TEST_P(MessageBridgeParameterizedTest, ReliableSentDuringClientReboot) {
   pi1_.OnPi();
 
-  FLAGS_application_name = "sender";
+  absl::SetFlag(&FLAGS_application_name, "sender");
   aos::ShmEventLoop send_event_loop(&config_.message());
   aos::Sender<examples::Ping> ping_sender =
       send_event_loop.MakeSender<examples::Ping>("/test");
@@ -1087,7 +1090,7 @@
   pi1_.MakeServer();
   pi1_.MakeClient();
 
-  FLAGS_application_name = "pi1_timestamp";
+  absl::SetFlag(&FLAGS_application_name, "pi1_timestamp");
   aos::ShmEventLoop pi1_remote_timestamp_event_loop(&config_.message());
 
   // Now do it for "raspberrypi2", the client.
@@ -1363,7 +1366,7 @@
     // Now, spin up a SctpClient and send a massive hunk of data.  This should
     // trigger a disconnect, but no crash.
     pi2_.OnPi();
-    FLAGS_application_name = "pi2_message_bridge_client";
+    absl::SetFlag(&FLAGS_application_name, "pi2_message_bridge_client");
     pi2_.client_event_loop_ =
         std::make_unique<aos::ShmEventLoop>(&config_.message());
     pi2_.client_event_loop_->SetRuntimeRealtimePriority(1);
diff --git a/aos/network/message_bridge_test_lib.cc b/aos/network/message_bridge_test_lib.cc
index 6b8b49e..eed1698 100644
--- a/aos/network/message_bridge_test_lib.cc
+++ b/aos/network/message_bridge_test_lib.cc
@@ -1,6 +1,9 @@
 #include "aos/network/message_bridge_test_lib.h"
 
-DECLARE_string(boot_uuid);
+#include "absl/flags/flag.h"
+#include "absl/log/log.h"
+
+ABSL_DECLARE_FLAG(std::string, boot_uuid);
 
 namespace aos::message_bridge::testing {
 
@@ -69,14 +72,14 @@
 
 void PiNode::OnPi() {
   DoSetShmBase(node_name_);
-  FLAGS_override_hostname = host_name_;
-  FLAGS_boot_uuid = boot_uuid_.ToString();
+  absl::SetFlag(&FLAGS_override_hostname, host_name_);
+  absl::SetFlag(&FLAGS_boot_uuid, boot_uuid_.ToString());
 }
 
 void PiNode::MakeServer(const std::string server_config_sha256) {
   OnPi();
   LOG(INFO) << "Making " << node_name_ << " server";
-  FLAGS_application_name = app_name_;
+  absl::SetFlag(&FLAGS_application_name, app_name_);
   server_event_loop_ = std::make_unique<aos::ShmEventLoop>(&config_.message());
   server_event_loop_->SetRuntimeRealtimePriority(1);
   message_bridge_server_ = std::make_unique<MessageBridgeServer>(
@@ -114,7 +117,7 @@
 void PiNode::MakeClient() {
   OnPi();
   LOG(INFO) << "Making " << node_name_ << " client";
-  FLAGS_application_name = app_name_;
+  absl::SetFlag(&FLAGS_application_name, app_name_);
   client_event_loop_ = std::make_unique<aos::ShmEventLoop>(&config_.message());
   client_event_loop_->SetRuntimeRealtimePriority(1);
   message_bridge_client_ = std::make_unique<MessageBridgeClient>(
@@ -138,7 +141,7 @@
                       const PiNode *other_node) {
   OnPi();
   LOG(INFO) << "Making " << node_name_ << " test";
-  FLAGS_application_name = test_app_name;
+  absl::SetFlag(&FLAGS_application_name, test_app_name);
   test_event_loop_ = std::make_unique<aos::ShmEventLoop>(&config_.message());
 
   std::string channel_name = "/" + node_name_ + "/aos";
diff --git a/aos/network/message_bridge_test_lib.h b/aos/network/message_bridge_test_lib.h
index f8c0a3a..613f792 100644
--- a/aos/network/message_bridge_test_lib.h
+++ b/aos/network/message_bridge_test_lib.h
@@ -3,6 +3,7 @@
 #include <chrono>
 #include <thread>
 
+#include "absl/flags/reflection.h"
 #include "absl/strings/str_cat.h"
 #include "gtest/gtest.h"
 
@@ -92,7 +93,7 @@
 
   bool shared() const;
 
-  gflags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
 
   PiNode pi1_;
   PiNode pi2_;
diff --git a/aos/network/multinode_timestamp_filter.cc b/aos/network/multinode_timestamp_filter.cc
index 42e4299..263d52b 100644
--- a/aos/network/multinode_timestamp_filter.cc
+++ b/aos/network/multinode_timestamp_filter.cc
@@ -4,8 +4,10 @@
 #include <functional>
 #include <map>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_join.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/boot_timestamp.h"
@@ -13,53 +15,54 @@
 #include "aos/network/timestamp_filter.h"
 #include "aos/time/time.h"
 
-DEFINE_bool(timestamps_to_csv, false,
-            "If true, write all the time synchronization information to a set "
-            "of CSV files in /tmp/.  This should only be needed when debugging "
-            "time synchronization.");
+ABSL_FLAG(bool, timestamps_to_csv, false,
+          "If true, write all the time synchronization information to a set "
+          "of CSV files in /tmp/.  This should only be needed when debugging "
+          "time synchronization.");
 
-DEFINE_string(timestamp_csv_folder, "/tmp", "Folder to drop CSVs in");
+ABSL_FLAG(std::string, timestamp_csv_folder, "/tmp", "Folder to drop CSVs in");
 
-DEFINE_int32(max_invalid_distance_ns, 0,
-             "The max amount of time we will let the solver go backwards.");
+ABSL_FLAG(int32_t, max_invalid_distance_ns, 0,
+          "The max amount of time we will let the solver go backwards.");
 
-DEFINE_int32(debug_solve_number, -1,
-             "If nonzero, print out all the state for the provided solve "
-             "number.  This is typically used by solving once, taking note of "
-             "which solution failed to converge, and then re-running with "
-             "debug turned on for just that problem.");
+ABSL_FLAG(int32_t, debug_solve_number, -1,
+          "If nonzero, print out all the state for the provided solve "
+          "number.  This is typically used by solving once, taking note of "
+          "which solution failed to converge, and then re-running with "
+          "debug turned on for just that problem.");
 
-DEFINE_bool(bounds_offset_error, false,
-            "If true, use the offset to the bounds for solving instead of to "
-            "the interpolation lines.  This seems to make startup a bit "
-            "better, but won't track the middle as well.");
+ABSL_FLAG(bool, bounds_offset_error, false,
+          "If true, use the offset to the bounds for solving instead of to "
+          "the interpolation lines.  This seems to make startup a bit "
+          "better, but won't track the middle as well.");
 
-DEFINE_bool(
-    crash_on_solve_failure, true,
+ABSL_FLAG(
+    bool, crash_on_solve_failure, true,
     "If true, crash when the solver fails to converge.  If false, keep going.  "
     "This should only be set to false when trying to see if future problems "
     "would be solvable.  This won't process a valid log");
 
-DEFINE_bool(attempt_simultaneous_constrained_solve, true,
-            "If true, try the simultaneous, constrained solver.  If false, "
-            "only solve constrained problems sequentially.");
+ABSL_FLAG(bool, attempt_simultaneous_constrained_solve, true,
+          "If true, try the simultaneous, constrained solver.  If false, "
+          "only solve constrained problems sequentially.");
 
-DEFINE_bool(
-    remove_unlikely_constraints, true,
+ABSL_FLAG(
+    bool, remove_unlikely_constraints, true,
     "If true, when solving, try with our best guess at which constraints will "
     "be relevant and resolve if that proves wrong with an updated set.  For "
     "expensive problems, this reduces solve time significantly.");
 
-DEFINE_int32(solve_verbosity, 1, "Verbosity to use when debugging the solver.");
+ABSL_FLAG(int32_t, solve_verbosity, 1,
+          "Verbosity to use when debugging the solver.");
 
-DEFINE_bool(constrained_solve, true,
-            "If true, use the constrained solver.  If false, only solve "
-            "unconstrained.");
+ABSL_FLAG(bool, constrained_solve, true,
+          "If true, use the constrained solver.  If false, only solve "
+          "unconstrained.");
 
-#define SOLVE_VLOG_IS_ON(solve_number, v)                             \
-  (VLOG_IS_ON(v) ||                                                   \
-   (static_cast<int32_t>(solve_number) == FLAGS_debug_solve_number && \
-    v <= FLAGS_solve_verbosity))
+#define SOLVE_VLOG_IS_ON(solve_number, v)                           \
+  (VLOG_IS_ON(v) || (static_cast<int32_t>(solve_number) ==          \
+                         absl::GetFlag(FLAGS_debug_solve_number) && \
+                     v <= absl::GetFlag(FLAGS_solve_verbosity)))
 
 #define SOLVE_VLOG(solve_number, v) \
   LOG_IF(INFO, SOLVE_VLOG_IS_ON(solve_number, v))
@@ -77,7 +80,7 @@
 
 template <class... Args>
 std::string CsvPath(Args &&...args) {
-  return absl::StrCat(FLAGS_timestamp_csv_folder, "/",
+  return absl::StrCat(absl::GetFlag(FLAGS_timestamp_csv_folder), "/",
                       std::forward<Args>(args)...);
 }
 }  // namespace
@@ -329,7 +332,7 @@
       std::pair<NoncausalTimestampFilter::Pointer,
                 std::tuple<chrono::nanoseconds, double, double>>
           offset_error =
-              FLAGS_bounds_offset_error
+              absl::GetFlag(FLAGS_bounds_offset_error)
                   ? filter.filter->BoundsOffsetError(
                         filter.b_filter, std::move(filter.pointer),
                         base_clock_[i], time_offsets(a_solution_index),
@@ -1049,7 +1052,8 @@
             << " Considering constraint " << i << " from before";
         active_constraints.emplace_back(i);
         ++original_constraint_index;
-      } else if (derivatives.f(i) > 0.0 || !FLAGS_remove_unlikely_constraints) {
+      } else if (derivatives.f(i) > 0.0 ||
+                 !absl::GetFlag(FLAGS_remove_unlikely_constraints)) {
         SOLVE_VLOG(my_solve_number_, 1) << " Considering constraint " << i;
         active_constraints.emplace_back(i);
       }
@@ -1306,7 +1310,8 @@
     }
   }
 
-  if (iteration > max_iterations && FLAGS_crash_on_solve_failure) {
+  if (iteration > max_iterations &&
+      absl::GetFlag(FLAGS_crash_on_solve_failure)) {
     LOG(ERROR) << "Failed to converge on solve " << my_solve_number_;
     return std::nullopt;
   }
@@ -1417,7 +1422,7 @@
         // hitting this anymore.  I'm also likely the one who will be debugging
         // it next and would rather spend the time debugging it when I get a bug
         // report.
-        if (FLAGS_bounds_offset_error) {
+        if (absl::GetFlag(FLAGS_bounds_offset_error)) {
           gradients[i].emplace_back(
               std::string("- ") +
               filter.filter->DebugOffsetError(
@@ -1789,7 +1794,7 @@
   CHECK_EQ(boots_->boots.size(), NodesCount());
   filters_per_node_.resize(NodesCount());
   last_monotonics_.resize(NodesCount(), BootTimestamp::epoch());
-  if (FLAGS_timestamps_to_csv && multi_node) {
+  if (absl::GetFlag(FLAGS_timestamps_to_csv) && multi_node) {
     fp_ = fopen(CsvPath("timestamp_noncausal_offsets.csv").c_str(), "w");
     fprintf(fp_, "# distributed");
     for (const Node *node : configuration::GetNodes(logged_configuration)) {
@@ -1925,7 +1930,7 @@
 
 void MultiNodeNoncausalOffsetEstimator::Start(
     std::vector<monotonic_clock::time_point> times) {
-  if (FLAGS_timestamps_to_csv) {
+  if (absl::GetFlag(FLAGS_timestamps_to_csv)) {
     std::fstream s(CsvPath("timestamp_noncausal_starttime.csv").c_str(),
                    s.trunc | s.out);
     CHECK(s.is_open());
@@ -2636,7 +2641,8 @@
                                  SOLVE_VLOG_IS_ON(solver.my_solve_number(), 2),
                              solution_y);
 
-    if (iterations > kMaxIterations && FLAGS_crash_on_solve_failure) {
+    if (iterations > kMaxIterations &&
+        absl::GetFlag(FLAGS_crash_on_solve_failure)) {
       UpdateSolution(std::move(solution));
       if (!FlushAndClose(false)) {
         return std::nullopt;
@@ -2646,7 +2652,7 @@
     }
 
     if (!problem->ValidateSolution(solution, true)) {
-      if (!FLAGS_constrained_solve) {
+      if (!absl::GetFlag(FLAGS_constrained_solve)) {
         problem->ValidateSolution(solution, false);
         LOG(WARNING) << "Invalid solution, constraints not met for problem "
                      << solver.my_solve_number();
@@ -2671,7 +2677,7 @@
           problem->set_base_clock(node_index, solution[node_index]);
         }
 
-        if (!FLAGS_attempt_simultaneous_constrained_solve) {
+        if (!absl::GetFlag(FLAGS_attempt_simultaneous_constrained_solve)) {
           VLOG(1) << "Falling back to sequential constrained Newton.";
           return SequentialSolution(problem, candidate_times, base_times);
         }
@@ -2687,7 +2693,8 @@
         std::tie(std::ignore, std::ignore, solution_index, iterations) =
             *solver_result;
 
-        if (iterations > kMaxIterations && FLAGS_crash_on_solve_failure) {
+        if (iterations > kMaxIterations &&
+            absl::GetFlag(FLAGS_crash_on_solve_failure)) {
           UpdateSolution(std::move(solution));
           if (!FlushAndClose(false)) {
             return std::nullopt;
@@ -2729,7 +2736,8 @@
   // If times are close enough, drop the invalid time.
   const chrono::nanoseconds invalid_distance =
       InvalidDistance(result_times, solution);
-  if (invalid_distance <= chrono::nanoseconds(FLAGS_max_invalid_distance_ns)) {
+  if (invalid_distance <=
+      chrono::nanoseconds(absl::GetFlag(FLAGS_max_invalid_distance_ns))) {
     VLOG(1) << "Times can't be compared by " << invalid_distance.count()
             << "ns";
     for (size_t i = 0; i < result_times.size(); ++i) {
@@ -2867,7 +2875,8 @@
                                  SOLVE_VLOG_IS_ON(solver.my_solve_number(), 2),
                              solution_y);
 
-    if (iterations > kMaxIterations && FLAGS_crash_on_solve_failure) {
+    if (iterations > kMaxIterations &&
+        absl::GetFlag(FLAGS_crash_on_solve_failure)) {
       UpdateSolution(std::move(solution));
       if (!FlushAndClose(false)) {
         return std::nullopt;
@@ -2881,7 +2890,7 @@
     // CSV file so we can view the problem and figure out what to do.  The
     // results won't make sense.
     if (!problem->ValidateSolution(solution, true)) {
-      if (!FLAGS_constrained_solve) {
+      if (!absl::GetFlag(FLAGS_constrained_solve)) {
         // Do it non-quiet now.
         problem->ValidateSolution(solution, false);
 
@@ -2918,7 +2927,8 @@
         std::tie(std::ignore, std::ignore, solution_index, iterations) =
             *solver_result;
 
-        if (iterations > kMaxIterations && FLAGS_crash_on_solve_failure) {
+        if (iterations > kMaxIterations &&
+            absl::GetFlag(FLAGS_crash_on_solve_failure)) {
           UpdateSolution(std::move(solution));
           if (!FlushAndClose(false)) {
             return std::nullopt;
@@ -3238,7 +3248,7 @@
         const chrono::nanoseconds invalid_distance =
             InvalidDistance(last_monotonics_, result_times);
         if (invalid_distance <=
-            chrono::nanoseconds(FLAGS_max_invalid_distance_ns)) {
+            chrono::nanoseconds(absl::GetFlag(FLAGS_max_invalid_distance_ns))) {
           WriteFilter(next_filter, sample);
           return NextTimestamp();
         }
diff --git a/aos/network/multinode_timestamp_filter.h b/aos/network/multinode_timestamp_filter.h
index 66dcbff..8d560b6 100644
--- a/aos/network/multinode_timestamp_filter.h
+++ b/aos/network/multinode_timestamp_filter.h
@@ -8,7 +8,8 @@
 
 #include "Eigen/Dense"
 #include "absl/container/btree_set.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/boot_timestamp.h"
diff --git a/aos/network/ping.cc b/aos/network/ping.cc
index f105133..6aceaee 100644
--- a/aos/network/ping.cc
+++ b/aos/network/ping.cc
@@ -1,17 +1,17 @@
 #include <chrono>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/network/sctp_server.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config.");
-DEFINE_uint32(port, 1323, "Port to pingpong on");
-DEFINE_uint32(size, 1000000, "Size of data to send in bytes");
-DEFINE_uint32(duration, 1000, "Period to send at in milliseconds");
-DEFINE_uint32(ttl, 0, "TTL in milliseconds");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the config.");
+ABSL_FLAG(uint32_t, port, 1323, "Port to pingpong on");
+ABSL_FLAG(uint32_t, size, 1000000, "Size of data to send in bytes");
+ABSL_FLAG(uint32_t, duration, 1000, "Period to send at in milliseconds");
+ABSL_FLAG(uint32_t, ttl, 0, "TTL in milliseconds");
 
 namespace aos {
 namespace message_bridge {
@@ -21,17 +21,17 @@
 class PingServer {
  public:
   PingServer(aos::ShmEventLoop *event_loop)
-      : event_loop_(event_loop), server_(2, "::", FLAGS_port) {
+      : event_loop_(event_loop), server_(2, "::", absl::GetFlag(FLAGS_port)) {
     event_loop_->epoll()->OnReadable(server_.fd(),
                                      [this]() { MessageReceived(); });
-    server_.SetMaxReadSize(FLAGS_size + 100);
-    server_.SetMaxWriteSize(FLAGS_size + 100);
+    server_.SetMaxReadSize(absl::GetFlag(FLAGS_size) + 100);
+    server_.SetMaxWriteSize(absl::GetFlag(FLAGS_size) + 100);
 
     timer_ = event_loop_->AddTimer([this]() { Timer(); });
 
     event_loop_->OnRun([this]() {
       timer_->Schedule(event_loop_->monotonic_now(),
-                       chrono::milliseconds(FLAGS_duration));
+                       chrono::milliseconds(absl::GetFlag(FLAGS_duration)));
     });
 
     event_loop_->SetRuntimeRealtimePriority(5);
@@ -48,9 +48,9 @@
       return;
     }
 
-    std::string data(FLAGS_size, 'a');
+    std::string data(absl::GetFlag(FLAGS_size), 'a');
 
-    if (server_.Send(data, sac_assoc_id_, 0, FLAGS_ttl)) {
+    if (server_.Send(data, sac_assoc_id_, 0, absl::GetFlag(FLAGS_ttl))) {
       LOG(INFO) << "Sent " << data.size();
     } else {
       PLOG(ERROR) << "Failed to send";
@@ -117,7 +117,7 @@
 
 int Main() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   PingServer server(&event_loop);
diff --git a/aos/network/pong.cc b/aos/network/pong.cc
index 8f08836..29253ec 100644
--- a/aos/network/pong.cc
+++ b/aos/network/pong.cc
@@ -1,19 +1,19 @@
 #include <chrono>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/network/sctp_client.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config.");
-DEFINE_uint32(port, 1323, "Port to pingpong on");
-DEFINE_string(target, "vpu0-0a", "Host to connect to");
-DEFINE_uint32(rx_size, 1000000,
-              "RX buffer size to set the max size to be in bytes.");
-DEFINE_uint32(size, 1000, "Size of data to send in bytes");
-DEFINE_uint32(ttl, 0, "TTL in milliseconds");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the config.");
+ABSL_FLAG(uint32_t, port, 1323, "Port to pingpong on");
+ABSL_FLAG(std::string, target, "vpu0-0a", "Host to connect to");
+ABSL_FLAG(uint32_t, rx_size, 1000000,
+          "RX buffer size to set the max size to be in bytes.");
+ABSL_FLAG(uint32_t, size, 1000, "Size of data to send in bytes");
+ABSL_FLAG(uint32_t, ttl, 0, "TTL in milliseconds");
 
 namespace aos {
 namespace message_bridge {
@@ -23,9 +23,15 @@
 class PingClient {
  public:
   PingClient(aos::ShmEventLoop *event_loop)
-      : event_loop_(event_loop), client_(FLAGS_target, FLAGS_port, 2, "::", 0) {
-    client_.SetMaxReadSize(std::max(FLAGS_rx_size, FLAGS_size) + 100);
-    client_.SetMaxWriteSize(std::max(FLAGS_rx_size, FLAGS_size) + 100);
+      : event_loop_(event_loop),
+        client_(absl::GetFlag(FLAGS_target), absl::GetFlag(FLAGS_port), 2,
+                "::", 0) {
+    client_.SetMaxReadSize(
+        std::max(absl::GetFlag(FLAGS_rx_size), absl::GetFlag(FLAGS_size)) +
+        100);
+    client_.SetMaxWriteSize(
+        std::max(absl::GetFlag(FLAGS_rx_size), absl::GetFlag(FLAGS_size)) +
+        100);
 
     timer_ = event_loop_->AddTimer([this]() { Timer(); });
 
@@ -45,9 +51,9 @@
   sctp_assoc_t sac_assoc_id_ = 0;
 
   void Timer() {
-    std::string data(FLAGS_size, 'a');
+    std::string data(absl::GetFlag(FLAGS_size), 'a');
 
-    if (client_.Send(0, data, FLAGS_ttl)) {
+    if (client_.Send(0, data, absl::GetFlag(FLAGS_ttl))) {
       LOG(INFO) << "Sent " << data.size();
     } else {
       PLOG(ERROR) << "Failed to send";
@@ -119,7 +125,7 @@
 
 int Main() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   PingClient server(&event_loop);
diff --git a/aos/network/rawrtc.cc b/aos/network/rawrtc.cc
index 6d9bc3d..eddf696 100644
--- a/aos/network/rawrtc.cc
+++ b/aos/network/rawrtc.cc
@@ -9,13 +9,15 @@
 #include <functional>
 #include <string>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 
-DEFINE_int32(min_ice_port, -1,
-             "Minimum port number to use for ICE candidates.");
-DEFINE_int32(max_ice_port, -1,
-             "Maximum port number to use for ICE candidates.");
+ABSL_FLAG(int32_t, min_ice_port, -1,
+          "Minimum port number to use for ICE candidates.");
+ABSL_FLAG(int32_t, max_ice_port, -1,
+          "Maximum port number to use for ICE candidates.");
 
 namespace aos::web_proxy {
 namespace {
@@ -198,11 +200,14 @@
   CHECK_RAWRTC(rawrtc_peer_connection_configuration_set_sctp_buffer_length(
       configuration, TRANSPORT_BUFFER_LENGTH, TRANSPORT_BUFFER_LENGTH));
 
-  if (FLAGS_min_ice_port >= 0 && FLAGS_max_ice_port >= 0) {
-    CHECK_LT(FLAGS_min_ice_port, FLAGS_max_ice_port);
+  if (absl::GetFlag(FLAGS_min_ice_port) >= 0 &&
+      absl::GetFlag(FLAGS_max_ice_port) >= 0) {
+    CHECK_LT(absl::GetFlag(FLAGS_min_ice_port),
+             absl::GetFlag(FLAGS_max_ice_port));
     // Set the port range to use for ICE candidates.
     CHECK_RAWRTC(rawrtc_peer_connection_configuration_set_ice_udp_port_range(
-        configuration, FLAGS_min_ice_port, FLAGS_max_ice_port));
+        configuration, absl::GetFlag(FLAGS_min_ice_port),
+        absl::GetFlag(FLAGS_max_ice_port)));
   }
 
   // Create peer connection
diff --git a/aos/network/rawrtc.h b/aos/network/rawrtc.h
index 57153f0..7b919bf 100644
--- a/aos/network/rawrtc.h
+++ b/aos/network/rawrtc.h
@@ -10,8 +10,9 @@
 #include "rawrtcc/utils.h"
 }
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 
 namespace aos::web_proxy {
 
diff --git a/aos/network/sctp_client.cc b/aos/network/sctp_client.cc
index 32347fd..b387e07 100644
--- a/aos/network/sctp_client.cc
+++ b/aos/network/sctp_client.cc
@@ -9,14 +9,16 @@
 #include <cstring>
 #include <string_view>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/sctp_lib.h"
 #include "aos/unique_malloc_ptr.h"
 
-DEFINE_int32(sinit_max_init_timeout, 0,
-             "Timeout in milliseconds for retrying the INIT packet when "
-             "connecting to the message bridge server");
+ABSL_FLAG(int32_t, sinit_max_init_timeout, 0,
+          "Timeout in milliseconds for retrying the INIT packet when "
+          "connecting to the message bridge server");
 
 namespace aos::message_bridge {
 
@@ -35,7 +37,7 @@
     initmsg.sinit_num_ostreams = streams;
     initmsg.sinit_max_instreams = streams;
     // Max timeout in milliseconds for the INIT packet.
-    initmsg.sinit_max_init_timeo = FLAGS_sinit_max_init_timeout;
+    initmsg.sinit_max_init_timeo = absl::GetFlag(FLAGS_sinit_max_init_timeout);
     PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
                       sizeof(struct sctp_initmsg)) == 0);
   }
diff --git a/aos/network/sctp_client.h b/aos/network/sctp_client.h
index 952d0e9..61e4e9e 100644
--- a/aos/network/sctp_client.h
+++ b/aos/network/sctp_client.h
@@ -5,8 +5,9 @@
 #include <cstdlib>
 #include <string_view>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/network/sctp_lib.h"
 #include "aos/unique_malloc_ptr.h"
diff --git a/aos/network/sctp_lib.cc b/aos/network/sctp_lib.cc
index cf50ad6..1c55293 100644
--- a/aos/network/sctp_lib.cc
+++ b/aos/network/sctp_lib.cc
@@ -16,6 +16,10 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
+
 #include "aos/util/file.h"
 
 // The casts required to read datastructures from sockets trip - Wcast - align.
@@ -23,9 +27,9 @@
 #pragma clang diagnostic ignored "-Wcast-align"
 #endif
 
-DEFINE_string(interface, "", "network interface");
-DEFINE_bool(disable_ipv6, false, "disable ipv6");
-DEFINE_int32(rmem, 0, "If nonzero, set rmem to this size.");
+ABSL_FLAG(std::string, interface, "", "network interface");
+ABSL_FLAG(bool, disable_ipv6, false, "disable ipv6");
+ABSL_FLAG(int32_t, rmem, 0, "If nonzero, set rmem to this size.");
 
 // The Type of Service.
 // https://www.tucny.com/Home/dscp-tos
@@ -39,8 +43,8 @@
 // to zero. Those two bits are the "Explicit Congestion Notification" bits. They
 // are controlled by the IP stack itself (and used by the router). We don't
 // control that via the TOS value we set here.
-DEFINE_int32(
-    sctp_tos, 176,
+ABSL_FLAG(
+    int32_t, sctp_tos, 176,
     "The Type-Of-Service value to use. Defaults to a critical priority. "
     "Always set values here whose two least significant bits are set to zero. "
     "When using tcpdump, the `tos` field may show the least significant two "
@@ -88,7 +92,7 @@
 }  // namespace
 
 bool Ipv6Enabled() {
-  if (FLAGS_disable_ipv6) {
+  if (absl::GetFlag(FLAGS_disable_ipv6)) {
     return false;
   }
   int fd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
@@ -151,8 +155,9 @@
       t_addr6->sin6_family = addrinfo_result->ai_family;
       t_addr6->sin6_port = htons(port);
 
-      if (FLAGS_interface.size() > 0) {
-        t_addr6->sin6_scope_id = if_nametoindex(FLAGS_interface.c_str());
+      if (absl::GetFlag(FLAGS_interface).size() > 0) {
+        t_addr6->sin6_scope_id =
+            if_nametoindex(absl::GetFlag(FLAGS_interface).c_str());
       }
 
       break;
@@ -295,7 +300,7 @@
     // Set up Type-Of-Service.
     //
     // See comments for the --sctp_tos flag for more information.
-    int tos = IPTOS_DSCP(FLAGS_sctp_tos);
+    int tos = IPTOS_DSCP(absl::GetFlag(FLAGS_sctp_tos));
     PCHECK(setsockopt(fd_, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == 0);
   }
   {
@@ -683,8 +688,8 @@
   // The SO_RCVBUF option (also controlled by net.core.rmem_default) needs to be
   // decently large but the actual size can be measured by tuning.  The defaults
   // should be fine.  If it isn't big enough, transmission will fail.
-  if (FLAGS_rmem > 0) {
-    size_t rmem = FLAGS_rmem;
+  if (absl::GetFlag(FLAGS_rmem) > 0) {
+    size_t rmem = absl::GetFlag(FLAGS_rmem);
     PCHECK(setsockopt(fd(), SOL_SOCKET, SO_RCVBUF, &rmem, sizeof(rmem)) == 0);
   }
 }
diff --git a/aos/network/sctp_lib.h b/aos/network/sctp_lib.h
index 3430be8..97d9d20 100644
--- a/aos/network/sctp_lib.h
+++ b/aos/network/sctp_lib.h
@@ -11,9 +11,9 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/unique_malloc_ptr.h"
 
diff --git a/aos/network/sctp_lib_test.cc b/aos/network/sctp_lib_test.cc
index f297a82..a822257 100644
--- a/aos/network/sctp_lib_test.cc
+++ b/aos/network/sctp_lib_test.cc
@@ -1,16 +1,17 @@
 #include "aos/network/sctp_lib.h"
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/init.h"
 
-DEFINE_string(host, "", "host to resolve");
-DEFINE_int32(port, 2977, "port to use");
+ABSL_FLAG(std::string, host, "", "host to resolve");
+ABSL_FLAG(int32_t, port, 2977, "port to use");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   struct sockaddr_storage sockaddr = aos::message_bridge::ResolveSocket(
-      FLAGS_host, FLAGS_port, aos::message_bridge::Ipv6Enabled());
+      absl::GetFlag(FLAGS_host), absl::GetFlag(FLAGS_port),
+      aos::message_bridge::Ipv6Enabled());
   LOG(INFO) << "Family " << aos::message_bridge::Family(sockaddr);
   LOG(INFO) << "Address " << aos::message_bridge::Address(sockaddr);
   return 0;
diff --git a/aos/network/sctp_perf.cc b/aos/network/sctp_perf.cc
index db762de..dae8667 100644
--- a/aos/network/sctp_perf.cc
+++ b/aos/network/sctp_perf.cc
@@ -1,7 +1,9 @@
 #include <chrono>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
@@ -14,24 +16,24 @@
 #pragma clang diagnostic ignored "-Wcast-align"
 #endif
 
-DEFINE_string(config, "aos_config.json", "Path to the config.");
-DEFINE_uint32(port, 1323, "Port to run the sctp test on");
-DEFINE_uint32(payload_size, 1000, "Size of data to send in bytes");
-DEFINE_uint32(ttl, 0, "TTL in milliseconds");
-DEFINE_uint32(rx_size, 1000000,
-              "RX buffer size to set the max size to be in bytes.");
-DEFINE_string(host, "", "Server host (acts as server if unspecified)");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the config.");
+ABSL_FLAG(uint32_t, port, 1323, "Port to run the sctp test on");
+ABSL_FLAG(uint32_t, payload_size, 1000, "Size of data to send in bytes");
+ABSL_FLAG(uint32_t, ttl, 0, "TTL in milliseconds");
+ABSL_FLAG(uint32_t, rx_size, 1000000,
+          "RX buffer size to set the max size to be in bytes.");
+ABSL_FLAG(std::string, host, "", "Server host (acts as server if unspecified)");
 
-DEFINE_bool(client, false,
-            "If true, then act as a client, otherwise act as a server");
-DEFINE_uint32(skip_first_n, 10,
-              "Skip the first 'n' messages when computing statistics.");
+ABSL_FLAG(bool, client, false,
+          "If true, then act as a client, otherwise act as a server");
+ABSL_FLAG(uint32_t, skip_first_n, 10,
+          "Skip the first 'n' messages when computing statistics.");
 
-DEFINE_string(sctp_auth_key_file, "",
-              "When set, use the provided key for SCTP authentication as "
-              "defined in RFC 4895");
+ABSL_FLAG(std::string, sctp_auth_key_file, "",
+          "When set, use the provided key for SCTP authentication as "
+          "defined in RFC 4895");
 
-DECLARE_bool(die_on_malloc);
+ABSL_DECLARE_FLAG(bool, die_on_malloc);
 
 namespace aos::message_bridge::perf {
 
@@ -40,15 +42,16 @@
 using util::ReadFileToVecOrDie;
 
 SctpAuthMethod SctpAuthMethod() {
-  return FLAGS_sctp_auth_key_file.empty() ? SctpAuthMethod::kNoAuth
-                                          : SctpAuthMethod::kAuth;
+  return absl::GetFlag(FLAGS_sctp_auth_key_file).empty()
+             ? SctpAuthMethod::kNoAuth
+             : SctpAuthMethod::kAuth;
 }
 
 std::vector<uint8_t> GetSctpAuthKey() {
   if (SctpAuthMethod() == SctpAuthMethod::kNoAuth) {
     return {};
   }
-  return ReadFileToVecOrDie(FLAGS_sctp_auth_key_file);
+  return ReadFileToVecOrDie(absl::GetFlag(FLAGS_sctp_auth_key_file));
 }
 
 }  // namespace
@@ -59,12 +62,12 @@
  public:
   Server(aos::ShmEventLoop *event_loop)
       : event_loop_(event_loop),
-        server_(2, "0.0.0.0", FLAGS_port, SctpAuthMethod()) {
+        server_(2, "0.0.0.0", absl::GetFlag(FLAGS_port), SctpAuthMethod()) {
     server_.SetAuthKey(GetSctpAuthKey());
     event_loop_->epoll()->OnReadable(server_.fd(),
                                      [this]() { MessageReceived(); });
-    server_.SetMaxReadSize(FLAGS_rx_size + 100);
-    server_.SetMaxWriteSize(FLAGS_rx_size + 100);
+    server_.SetMaxReadSize(absl::GetFlag(FLAGS_rx_size) + 100);
+    server_.SetMaxWriteSize(absl::GetFlag(FLAGS_rx_size) + 100);
 
     event_loop_->SetRuntimeRealtimePriority(5);
   }
@@ -76,7 +79,7 @@
       LOG(INFO) << "Lost connection to client. Not sending";
       return;
     }
-    if (server_.Send(message, sac_assoc_id_, 0, FLAGS_ttl)) {
+    if (server_.Send(message, sac_assoc_id_, 0, absl::GetFlag(FLAGS_ttl))) {
       LOG(INFO) << "Server reply with " << message.size() << "B";
     } else {
       PLOG(FATAL) << "Failed to send";
@@ -140,11 +143,11 @@
  public:
   Client(aos::ShmEventLoop *event_loop)
       : event_loop_(event_loop),
-        client_(FLAGS_host, FLAGS_port, 2, "0.0.0.0", FLAGS_port,
-                SctpAuthMethod()) {
+        client_(absl::GetFlag(FLAGS_host), absl::GetFlag(FLAGS_port), 2,
+                "0.0.0.0", absl::GetFlag(FLAGS_port), SctpAuthMethod()) {
     client_.SetAuthKey(GetSctpAuthKey());
-    client_.SetMaxReadSize(FLAGS_rx_size + 100);
-    client_.SetMaxWriteSize(FLAGS_rx_size + 100);
+    client_.SetMaxReadSize(absl::GetFlag(FLAGS_rx_size) + 100);
+    client_.SetMaxWriteSize(absl::GetFlag(FLAGS_rx_size) + 100);
 
     timer_ = event_loop_->AddTimer([this]() { Ping(); });
 
@@ -161,9 +164,9 @@
   ~Client() { event_loop_->epoll()->DeleteFd(client_.fd()); }
 
   void Ping() {
-    std::string payload(FLAGS_payload_size, 'a');
+    std::string payload(absl::GetFlag(FLAGS_payload_size), 'a');
     sent_time_ = aos::monotonic_clock::now();
-    if (client_.Send(0, payload, FLAGS_ttl)) {
+    if (client_.Send(0, payload, absl::GetFlag(FLAGS_ttl))) {
       LOG(INFO) << "Sending " << payload.size() << "B";
     } else {
       PLOG(ERROR) << "Failed to send";
@@ -226,8 +229,9 @@
             .count();
     avg_latency_ = (avg_latency_ * (count_ - 1) + elapsed_secs) / count_;
     // average one-way throughput
-    double throughput = FLAGS_payload_size * 2.0 / elapsed_secs;
-    double avg_throughput = FLAGS_payload_size * 2.0 / avg_latency_;
+    double throughput = absl::GetFlag(FLAGS_payload_size) * 2.0 / elapsed_secs;
+    double avg_throughput =
+        absl::GetFlag(FLAGS_payload_size) * 2.0 / avg_latency_;
     printf(
         "Round trip: %.2fms | %.2f KB/s | Avg RTL: %.2fms | %.2f KB/s | "
         "Count: %d\n",
@@ -240,25 +244,27 @@
   SctpClient client_;
   aos::TimerHandler *timer_;
   double avg_latency_ = 0.0;
-  int count_ = -FLAGS_skip_first_n;
+  int count_ = -absl::GetFlag(FLAGS_skip_first_n);
 
   aos::monotonic_clock::time_point sent_time_;
 };
 
 int Main() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
-  if (FLAGS_client) {
-    CHECK(!FLAGS_host.empty()) << "Client Usage: `sctp_perf --client --host "
-                                  "abc.com --payload_size [bytes] "
-                                  "[--port PORT] [--config PATH]`";
+  if (absl::GetFlag(FLAGS_client)) {
+    CHECK(!absl::GetFlag(FLAGS_host).empty())
+        << "Client Usage: `sctp_perf --client --host "
+           "abc.com --payload_size [bytes] "
+           "[--port PORT] [--config PATH]`";
 
     Client client(&event_loop);
     event_loop.Run();
   } else {
-    CHECK(FLAGS_host.empty()) << "Server Usage: `sctp_perf [--config PATH]`";
+    CHECK(absl::GetFlag(FLAGS_host).empty())
+        << "Server Usage: `sctp_perf [--config PATH]`";
     Server server(&event_loop);
     event_loop.Run();
   }
@@ -269,12 +275,12 @@
 }  // namespace aos::message_bridge::perf
 
 int main(int argc, char **argv) {
-  gflags::SetUsageMessage(absl::StrCat(
+  absl::SetProgramUsageMessage(absl::StrCat(
       "Measure SCTP performance\n", "  Server Usage: `sctp_perf`\n",
       "  Client Usage: `sctp_perf --client --host abc.com`\n"));
   aos::InitGoogle(&argc, &argv);
 
   // Client and server need to malloc.
-  FLAGS_die_on_malloc = false;
+  absl::SetFlag(&FLAGS_die_on_malloc, false);
   return aos::message_bridge::perf::Main();
 }
diff --git a/aos/network/sctp_server.cc b/aos/network/sctp_server.cc
index 7f7a0ae..c495180 100644
--- a/aos/network/sctp_server.cc
+++ b/aos/network/sctp_server.cc
@@ -13,7 +13,8 @@
 #include <memory>
 #include <thread>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/sctp_lib.h"
 #include "aos/unique_malloc_ptr.h"
diff --git a/aos/network/sctp_server.h b/aos/network/sctp_server.h
index 996645e..4dd295d 100644
--- a/aos/network/sctp_server.h
+++ b/aos/network/sctp_server.h
@@ -13,8 +13,9 @@
 #include <cstring>
 #include <memory>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/network/sctp_lib.h"
 #include "aos/unique_malloc_ptr.h"
diff --git a/aos/network/sctp_test.cc b/aos/network/sctp_test.cc
index bce5c19..d202e5d 100644
--- a/aos/network/sctp_test.cc
+++ b/aos/network/sctp_test.cc
@@ -3,7 +3,8 @@
 #include <chrono>
 #include <functional>
 
-#include "gflags/gflags.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 #include "gmock/gmock-matchers.h"
 #include "gtest/gtest.h"
 
@@ -13,7 +14,7 @@
 #include "aos/network/sctp_server.h"
 #include "sctp_lib.h"
 
-DECLARE_bool(disable_ipv6);
+ABSL_DECLARE_FLAG(bool, disable_ipv6);
 
 namespace aos::message_bridge::testing {
 
@@ -128,7 +129,7 @@
   static void SetUpTestSuite() {
     EnableSctpAuthIfAvailable();
     // Buildkite seems to have issues with ipv6 sctp sockets...
-    FLAGS_disable_ipv6 = true;
+    absl::SetFlag(&FLAGS_disable_ipv6, true);
   }
 
   void SetUp() override { Run(); }
diff --git a/aos/network/team_number.cc b/aos/network/team_number.cc
index cc81e26..175c3a9 100644
--- a/aos/network/team_number.cc
+++ b/aos/network/team_number.cc
@@ -6,12 +6,14 @@
 #include <cinttypes>
 #include <cstdlib>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/numbers.h"
 
-DEFINE_string(
-    override_hostname, "",
-    "If set, this forces the hostname of this node to be the provided "
-    "hostname.");
+ABSL_FLAG(std::string, override_hostname, "",
+          "If set, this forces the hostname of this node to be the provided "
+          "hostname.");
 
 namespace aos::network {
 namespace team_number_internal {
@@ -106,13 +108,13 @@
 }  // namespace
 
 ::std::string GetHostname() {
-  if (FLAGS_override_hostname.empty()) {
+  if (absl::GetFlag(FLAGS_override_hostname).empty()) {
     char buf[256];
     buf[sizeof(buf) - 1] = '\0';
     PCHECK(gethostname(buf, sizeof(buf) - 1) == 0);
     return buf;
   } else {
-    return FLAGS_override_hostname;
+    return absl::GetFlag(FLAGS_override_hostname);
   }
 }
 
diff --git a/aos/network/team_number.h b/aos/network/team_number.h
index 7b9acbb..10f8921 100644
--- a/aos/network/team_number.h
+++ b/aos/network/team_number.h
@@ -5,9 +5,9 @@
 #include <optional>
 #include <string_view>
 
-#include "glog/logging.h"
+#include "absl/flags/declare.h"
 
-DECLARE_string(override_hostname);
+ABSL_DECLARE_FLAG(std::string, override_hostname);
 
 namespace aos {
 namespace network {
diff --git a/aos/network/timestamp_channel.cc b/aos/network/timestamp_channel.cc
index 778c2e7..1a821c5 100644
--- a/aos/network/timestamp_channel.cc
+++ b/aos/network/timestamp_channel.cc
@@ -1,14 +1,15 @@
 #include "aos/network/timestamp_channel.h"
 
+#include "absl/flags/flag.h"
 #include "absl/strings/str_cat.h"
 
-DEFINE_bool(combined_timestamp_channel_fallback, true,
-            "If true, fall back to using the combined timestamp channel if the "
-            "single timestamp channel doesn't exist for a timestamp.");
-DEFINE_bool(check_timestamp_channel_frequencies, true,
-            "If true, include a debug CHECK to ensure that remote timestamp "
-            "channels are configured to have at least as great a frequency as "
-            "the corresponding data channel.");
+ABSL_FLAG(bool, combined_timestamp_channel_fallback, true,
+          "If true, fall back to using the combined timestamp channel if the "
+          "single timestamp channel doesn't exist for a timestamp.");
+ABSL_FLAG(bool, check_timestamp_channel_frequencies, true,
+          "If true, include a debug CHECK to ensure that remote timestamp "
+          "channels are configured to have at least as great a frequency as "
+          "the corresponding data channel.");
 
 namespace aos::message_bridge {
 
@@ -55,7 +56,7 @@
     return split_timestamp_channel;
   }
 
-  if (!FLAGS_combined_timestamp_channel_fallback) {
+  if (!absl::GetFlag(FLAGS_combined_timestamp_channel_fallback)) {
     LOG(FATAL) << "Failed to find new timestamp channel {\"name\": \""
                << split_timestamp_channel_name << "\", \"type\": \""
                << RemoteMessage::GetFullyQualifiedName() << "\"} for "
@@ -112,7 +113,7 @@
 
   const Channel *timestamp_channel = finder.ForChannel(channel, connection);
 
-  if (FLAGS_check_timestamp_channel_frequencies) {
+  if (absl::GetFlag(FLAGS_check_timestamp_channel_frequencies)) {
     // Sanity-check that the timestamp channel can actually support full-rate
     // messages coming through on the source channel.
     CHECK_GE(timestamp_channel->frequency(), channel->frequency())
diff --git a/aos/network/timestamp_channel.h b/aos/network/timestamp_channel.h
index 7e48a00..0d57c82 100644
--- a/aos/network/timestamp_channel.h
+++ b/aos/network/timestamp_channel.h
@@ -5,7 +5,8 @@
 #include <vector>
 
 #include "absl/container/btree_map.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
diff --git a/aos/network/timestamp_channel_test.cc b/aos/network/timestamp_channel_test.cc
index a217a74..9c0f57c 100644
--- a/aos/network/timestamp_channel_test.cc
+++ b/aos/network/timestamp_channel_test.cc
@@ -1,5 +1,7 @@
 #include "aos/network/timestamp_channel.h"
 
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
@@ -9,16 +11,16 @@
 #include "aos/testing/path.h"
 #include "aos/testing/tmpdir.h"
 
-DECLARE_string(override_hostname);
+ABSL_DECLARE_FLAG(std::string, override_hostname);
 
 namespace aos::message_bridge::testing {
+
 class TimestampChannelTest : public ::testing::Test {
  protected:
   TimestampChannelTest()
       : config_(aos::configuration::ReadConfig(aos::testing::ArtifactPath(
             "aos/network/timestamp_channel_test_config.json"))) {
-    FLAGS_shm_base = aos::testing::TestTmpDir();
-    FLAGS_override_hostname = "pi1";
+    absl::SetFlag(&FLAGS_override_hostname, "pi1");
   }
   aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
 };
diff --git a/aos/network/timestamp_filter.h b/aos/network/timestamp_filter.h
index 04ee605..5b24cd1 100644
--- a/aos/network/timestamp_filter.h
+++ b/aos/network/timestamp_filter.h
@@ -7,8 +7,9 @@
 #include <cstdio>
 #include <deque>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/numeric/int128.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/boot_timestamp.h"
diff --git a/aos/network/web_proxy.cc b/aos/network/web_proxy.cc
index 6b71433..05bb7fa 100644
--- a/aos/network/web_proxy.cc
+++ b/aos/network/web_proxy.cc
@@ -1,6 +1,8 @@
 #include "aos/network/web_proxy.h"
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/flatbuffer_merge.h"
 #include "aos/network/connect_generated.h"
@@ -18,21 +20,21 @@
 struct list *tmrl_get(void);
 }
 
-DEFINE_int32(proxy_port, 1180, "Port to use for the web proxy server.");
-DEFINE_int32(pre_send_messages, 10000,
-             "Number of messages / queue to send to a client before waiting on "
-             "confirmation that the initial message was received. If set to "
-             "-1, will not throttle messages at all. This prevents a situation "
-             "where, when run on localhost, the large number of WebRTC packets "
-             "can overwhelm the browser and crash the webpage.");
+ABSL_FLAG(int32_t, proxy_port, 1180, "Port to use for the web proxy server.");
+ABSL_FLAG(int32_t, pre_send_messages, 10000,
+          "Number of messages / queue to send to a client before waiting on "
+          "confirmation that the initial message was received. If set to "
+          "-1, will not throttle messages at all. This prevents a situation "
+          "where, when run on localhost, the large number of WebRTC packets "
+          "can overwhelm the browser and crash the webpage.");
 // Note: sometimes it appears that WebRTC buffer up and stop sending message
 // ack's back from the client page. It is not clear *why* WebRTC is doing this,
 // but since the only reason we use those ack's is to stop ourselves from
 // overloading the client webpage, this setting lets us fall back to just a
 // time-based rate-limit when we stop receiving acks.
-DEFINE_double(max_buffer_pause_sec, 0.1,
-              "If we have not received any ack's in this amount of time, we "
-              "start to continue sending messages.");
+ABSL_FLAG(double, max_buffer_pause_sec, 0.1,
+          "If we have not received any ack's in this amount of time, we "
+          "start to continue sending messages.");
 
 namespace aos::web_proxy {
 WebsocketHandler::WebsocketHandler(::seasocks::Server *server,
@@ -176,7 +178,7 @@
   });
 
   server_.addWebSocketHandler("/ws", websocket_handler_);
-  CHECK(server_.startListening(FLAGS_proxy_port));
+  CHECK(server_.startListening(absl::GetFlag(FLAGS_proxy_port)));
 
   epoll->OnReadable(server_.fd(), [this]() {
     CHECK(::seasocks::Server::PollResult::Continue == server_.poll(0));
@@ -351,17 +353,19 @@
     // We are still waiting on the next message to appear; return.
     return nullptr;
   }
-  if (FLAGS_pre_send_messages > 0) {
+  if (absl::GetFlag(FLAGS_pre_send_messages) > 0) {
     // Note: Uses actual clock to handle simulation time.
     const aos::monotonic_clock::time_point now = aos::monotonic_clock::now();
     if (channel->last_report.has_value() &&
         channel->last_report.value() +
                 std::chrono::duration_cast<std::chrono::nanoseconds>(
-                    std::chrono::duration<double>(FLAGS_max_buffer_pause_sec)) <
+                    std::chrono::duration<double>(
+                        absl::GetFlag(FLAGS_max_buffer_pause_sec))) <
             now) {
       // Increment the number of messages that we will send over to the client
       // webpage.
-      channel->reported_queue_index += FLAGS_pre_send_messages / 10;
+      channel->reported_queue_index +=
+          absl::GetFlag(FLAGS_pre_send_messages) / 10;
       channel->reported_packet_index = 0;
       channel->last_report = now;
     }
@@ -371,7 +375,7 @@
     // browser, not to be ultra precise about anything. It's also not clear that
     // message *size* is necessarily even the determining factor in causing
     // issues.
-    if (channel->reported_queue_index + FLAGS_pre_send_messages <
+    if (channel->reported_queue_index + absl::GetFlag(FLAGS_pre_send_messages) <
         channel->current_queue_index) {
       return nullptr;
     }
diff --git a/aos/network/web_proxy_main.cc b/aos/network/web_proxy_main.cc
index 7684b06..3b1977a 100644
--- a/aos/network/web_proxy_main.cc
+++ b/aos/network/web_proxy_main.cc
@@ -1,27 +1,29 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/flatbuffer_merge.h"
 #include "aos/init.h"
 #include "aos/network/web_proxy.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
-DEFINE_string(data_dir, "www", "Directory to serve data files from");
-DEFINE_int32(buffer_size, 1000000,
-             "-1 if infinite, in bytes / channel. If there are no active "
-             "connections, will not store anything.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
+ABSL_FLAG(std::string, data_dir, "www", "Directory to serve data files from");
+ABSL_FLAG(int32_t, buffer_size, 1000000,
+          "-1 if infinite, in bytes / channel. If there are no active "
+          "connections, will not store anything.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
-  aos::web_proxy::WebProxy web_proxy(
-      &event_loop, aos::web_proxy::StoreHistory::kNo, FLAGS_buffer_size);
-  web_proxy.SetDataPath(FLAGS_data_dir.c_str());
+  aos::web_proxy::WebProxy web_proxy(&event_loop,
+                                     aos::web_proxy::StoreHistory::kNo,
+                                     absl::GetFlag(FLAGS_buffer_size));
+  web_proxy.SetDataPath(absl::GetFlag(FLAGS_data_dir).c_str());
 
   event_loop.Run();
 }
diff --git a/aos/realtime.cc b/aos/realtime.cc
index 1e10457..43f0bb5 100644
--- a/aos/realtime.cc
+++ b/aos/realtime.cc
@@ -15,19 +15,21 @@
 #include <cstdlib>
 #include <cstring>
 
-#include "glog/logging.h"
-#include "glog/raw_logging.h"
+#include "absl/base/internal/raw_logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/uuid.h"
 
-DEFINE_bool(
-    die_on_malloc, true,
+ABSL_FLAG(
+    bool, die_on_malloc, true,
     "If true, die when the application allocates memory in a RT section.");
-DEFINE_bool(skip_realtime_scheduler, false,
-            "If true, skip changing the scheduler.  Pretend that we changed "
-            "the scheduler instead.");
-DEFINE_bool(skip_locking_memory, false,
-            "If true, skip locking memory.  Pretend that we did it instead.");
+ABSL_FLAG(bool, skip_realtime_scheduler, false,
+          "If true, skip changing the scheduler.  Pretend that we changed "
+          "the scheduler instead.");
+ABSL_FLAG(bool, skip_locking_memory, false,
+          "If true, skip locking memory.  Pretend that we did it instead.");
 
 extern "C" {
 typedef void (*MallocHook_NewHook)(const void *ptr, size_t size);
@@ -44,6 +46,8 @@
 
 void *__libc_malloc(size_t size);
 void __libc_free(void *ptr);
+void *__libc_realloc(void *ptr, size_t size);
+void *__libc_calloc(size_t n, size_t elem_size);
 }  // extern "C"
 
 namespace FLAG__namespace_do_not_use_directly_use_DECLARE_double_instead {
@@ -109,6 +113,7 @@
   CHECK_EQ(1, mallopt(M_MMAP_MAX, 0));
 #endif
 
+  // TODO(austin): new tcmalloc does this differently...
   if (&FLAGS_tcmalloc_release_rate) {
     // Tell tcmalloc not to return memory.
     FLAGS_tcmalloc_release_rate = 0.0;
@@ -129,7 +134,7 @@
 }
 
 void InitRT() {
-  if (FLAGS_skip_locking_memory) {
+  if (absl::GetFlag(FLAGS_skip_locking_memory)) {
     LOG(WARNING) << "Ignoring request to lock all memory due to "
                     "--skip_locking_memory.";
     return;
@@ -138,7 +143,7 @@
   CheckNotRealtime();
   LockAllMemory();
 
-  if (FLAGS_skip_realtime_scheduler) {
+  if (absl::GetFlag(FLAGS_skip_realtime_scheduler)) {
     return;
   }
   // Only let rt processes run for 3 seconds straight.
@@ -161,22 +166,6 @@
   MarkRealtime(false);
 }
 
-std::ostream &operator<<(std::ostream &stream, const cpu_set_t &cpuset) {
-  stream << "{CPUs ";
-  bool first_found = false;
-  for (int i = 0; i < CPU_SETSIZE; ++i) {
-    if (CPU_ISSET(i, &cpuset)) {
-      if (first_found) {
-        stream << ", ";
-      }
-      stream << i;
-      first_found = true;
-    }
-  }
-  stream << "}";
-  return stream;
-}
-
 void SetCurrentThreadAffinity(const cpu_set_t &cpuset) {
   PCHECK(sched_setaffinity(0, sizeof(cpuset), &cpuset) == 0) << cpuset;
 }
@@ -203,7 +192,7 @@
   // scheduler is running.
   UUID::Random();
 
-  if (FLAGS_skip_realtime_scheduler) {
+  if (absl::GetFlag(FLAGS_skip_realtime_scheduler)) {
     LOG(WARNING) << "Ignoring request to switch to the RT scheduler due to "
                     "--skip_realtime_scheduler.";
     return;
@@ -271,7 +260,7 @@
 void NewHook(const void *ptr, size_t size) {
   if (is_realtime) {
     is_realtime = false;
-    RAW_LOG(FATAL, "Malloced %p -> %zu bytes", ptr, size);
+    ABSL_RAW_LOG(FATAL, "Malloced %p -> %zu bytes", ptr, size);
   }
 }
 
@@ -281,7 +270,7 @@
   // calls.
   if (is_realtime && ptr != nullptr) {
     is_realtime = false;
-    RAW_LOG(FATAL, "Delete Hook %p", ptr);
+    ABSL_RAW_LOG(FATAL, "Delete Hook %p", ptr);
   }
 }
 
@@ -290,9 +279,9 @@
 // malloc hooks for libc. Tcmalloc will replace everything it finds (malloc,
 // __libc_malloc, etc.), so we need its specific hook above as well.
 void *aos_malloc_hook(size_t size) {
-  if (FLAGS_die_on_malloc && aos::is_realtime) {
+  if (absl::GetFlag(FLAGS_die_on_malloc) && aos::is_realtime) {
     aos::is_realtime = false;
-    RAW_LOG(FATAL, "Malloced %zu bytes", size);
+    ABSL_RAW_LOG(FATAL, "Malloced %zu bytes", size);
     return nullptr;
   } else {
     return __libc_malloc(size);
@@ -300,16 +289,41 @@
 }
 
 void aos_free_hook(void *ptr) {
-  if (FLAGS_die_on_malloc && aos::is_realtime && ptr != nullptr) {
+  if (absl::GetFlag(FLAGS_die_on_malloc) && aos::is_realtime &&
+      ptr != nullptr) {
     aos::is_realtime = false;
-    RAW_LOG(FATAL, "Deleted %p", ptr);
+    ABSL_RAW_LOG(FATAL, "Deleted %p", ptr);
   } else {
     __libc_free(ptr);
   }
 }
 
+void *aos_realloc_hook(void *ptr, size_t size) {
+  if (absl::GetFlag(FLAGS_die_on_malloc) && aos::is_realtime) {
+    aos::is_realtime = false;
+    ABSL_RAW_LOG(FATAL, "Malloced %p -> %zu bytes", ptr, size);
+    return nullptr;
+  } else {
+    return __libc_realloc(ptr, size);
+  }
+}
+
+void *aos_calloc_hook(size_t n, size_t elem_size) {
+  if (absl::GetFlag(FLAGS_die_on_malloc) && aos::is_realtime) {
+    aos::is_realtime = false;
+    ABSL_RAW_LOG(FATAL, "Malloced %zu * %zu bytes", n, elem_size);
+    return nullptr;
+  } else {
+    return __libc_calloc(n, elem_size);
+  }
+}
+
 void *malloc(size_t size) __attribute__((weak, alias("aos_malloc_hook")));
 void free(void *ptr) __attribute__((weak, alias("aos_free_hook")));
+void *realloc(void *ptr, size_t size)
+    __attribute__((weak, alias("aos_realloc_hook")));
+void *calloc(size_t n, size_t elem_size)
+    __attribute__((weak, alias("aos_calloc_hook")));
 }
 
 void FatalUnsetRealtimePriority() {
@@ -342,11 +356,11 @@
 }
 
 void RegisterMallocHook() {
-  if (FLAGS_die_on_malloc) {
+  if (absl::GetFlag(FLAGS_die_on_malloc)) {
     // tcmalloc redefines __libc_malloc, so use this as a feature test.
     if (&__libc_malloc == &tc_malloc) {
       if (VLOG_IS_ON(1)) {
-        RAW_LOG(INFO, "Hooking tcmalloc for die_on_malloc");
+        ABSL_RAW_LOG(INFO, "Hooking tcmalloc for die_on_malloc");
       }
       if (&MallocHook_AddNewHook != nullptr) {
         CHECK(MallocHook_AddNewHook(&NewHook));
@@ -360,7 +374,7 @@
       }
     } else {
       if (VLOG_IS_ON(1)) {
-        RAW_LOG(INFO, "Replacing glibc malloc");
+        ABSL_RAW_LOG(INFO, "Replacing glibc malloc");
       }
       if (&malloc != &aos_malloc_hook) {
         has_malloc_hook = false;
diff --git a/aos/realtime.h b/aos/realtime.h
index 261eb26..e9c76b9 100644
--- a/aos/realtime.h
+++ b/aos/realtime.h
@@ -6,7 +6,26 @@
 #include <ostream>
 #include <string_view>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
+#include "absl/strings/str_format.h"
+
+// Stringifies the cpu_set_t for LOG().
+template <typename Sink>
+void AbslStringify(Sink &sink, const cpu_set_t &cpuset) {
+  sink.Append("{CPUs ");
+  bool first_found = false;
+  for (int i = 0; i < CPU_SETSIZE; ++i) {
+    if (CPU_ISSET(i, &cpuset)) {
+      if (first_found) {
+        sink.Append(", ");
+      }
+      absl::Format(&sink, "%d", i);
+      first_found = true;
+    }
+  }
+  sink.Append("}");
+}
 
 namespace aos {
 
@@ -29,9 +48,6 @@
 // name can have a maximum of 16 characters.
 void SetCurrentThreadName(const std::string_view name);
 
-// Stringifies the cpu_set_t for streams.
-std::ostream &operator<<(std::ostream &stream, const cpu_set_t &cpuset);
-
 // Creates a cpu_set_t from a list of CPUs.
 inline cpu_set_t MakeCpusetFromCpus(std::initializer_list<int> cpus) {
   cpu_set_t result;
diff --git a/aos/realtime_test.cc b/aos/realtime_test.cc
index 1f6e460..feb26b3 100644
--- a/aos/realtime_test.cc
+++ b/aos/realtime_test.cc
@@ -1,12 +1,15 @@
 #include "aos/realtime.h"
 
-#include "glog/logging.h"
-#include "glog/raw_logging.h"
+#include "absl/base/internal/raw_logging.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/init.h"
 
-DECLARE_bool(die_on_malloc);
+ABSL_DECLARE_FLAG(bool, die_on_malloc);
 
 namespace aos::testing {
 
@@ -129,7 +132,7 @@
         *b = 5;
         EXPECT_EQ(*b, 5);
       },
-      "RAW: Delete");  // realloc free first, then allocates
+      "RAW: Malloced");
 }
 
 TEST(RealtimeDeathTest, Calloc) {
@@ -175,15 +178,15 @@
         int x = reinterpret_cast<const volatile int *>(0)[0];
         LOG(INFO) << x;
       },
-      "\\*\\*\\* Aborted at .*");
+      "\\*\\*\\* SIGSEGV received at .*");
 }
 
-// Tests that RAW_LOG(FATAL) explodes properly.
+// Tests that ABSL_RAW_LOG(FATAL) explodes properly.
 TEST(RealtimeDeathTest, RawFatal) {
   EXPECT_DEATH(
       {
         ScopedRealtime rt;
-        RAW_LOG(FATAL, "Cute message here\n");
+        ABSL_RAW_LOG(FATAL, "Cute message here\n");
       },
       "Cute message here");
 }
@@ -210,10 +213,9 @@
 // we can't test CHECK statements before turning die_on_malloc on globally.
 GTEST_API_ int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
-  FLAGS_logtostderr = true;
 
 #if !__has_feature(address_sanitizer) && !__has_feature(memory_sanitizer)
-  FLAGS_die_on_malloc = true;
+  absl::SetFlag(&FLAGS_die_on_malloc, true);
 #endif
 
   aos::InitGoogle(&argc, &argv);
diff --git a/aos/scoped/BUILD b/aos/scoped/BUILD
index fb867c6..8c59967 100644
--- a/aos/scoped/BUILD
+++ b/aos/scoped/BUILD
@@ -11,6 +11,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "//aos:macros",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/aos/scoped/scoped_fd.cc b/aos/scoped/scoped_fd.cc
index f2375ab..4e9054d 100644
--- a/aos/scoped/scoped_fd.cc
+++ b/aos/scoped/scoped_fd.cc
@@ -4,7 +4,8 @@
 
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos {
 
diff --git a/aos/seasocks/BUILD b/aos/seasocks/BUILD
index 7f5d25a..12d505e 100644
--- a/aos/seasocks/BUILD
+++ b/aos/seasocks/BUILD
@@ -15,6 +15,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//third_party/seasocks",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/aos/seasocks/seasocks_logger.cc b/aos/seasocks/seasocks_logger.cc
index a9d83bc..bba0482 100644
--- a/aos/seasocks/seasocks_logger.cc
+++ b/aos/seasocks/seasocks_logger.cc
@@ -1,6 +1,6 @@
 #include "aos/seasocks/seasocks_logger.h"
 
-#include "glog/logging.h"
+#include "absl/log/log.h"
 
 #include "seasocks/PrintfLogger.h"
 
@@ -8,17 +8,17 @@
 
 void SeasocksLogger::log(::seasocks::Logger::Level level, const char *message) {
   // Convert Seasocks error codes to glog.
-  int glog_level;
+  absl::LogSeverity log_level;
   switch (level) {
     case ::seasocks::Logger::Level::Info:
-      glog_level = google::INFO;
+      log_level = absl::LogSeverity::kInfo;
       break;
     case ::seasocks::Logger::Level::Warning:
-      glog_level = google::WARNING;
+      log_level = absl::LogSeverity::kWarning;
       break;
     case ::seasocks::Logger::Level::Error:
     case ::seasocks::Logger::Level::Severe:
-      glog_level = google::ERROR;
+      log_level = absl::LogSeverity::kError;
       break;
     case ::seasocks::Logger::Level::Debug:
     case ::seasocks::Logger::Level::Access:
@@ -26,10 +26,10 @@
       if (!VLOG_IS_ON(1)) {
         return;
       }
-      glog_level = google::INFO;
+      log_level = absl::LogSeverity::kInfo;
       break;
   }
-  LOG_AT_LEVEL(glog_level) << "Seasocks: " << message;
+  LOG(LEVEL(log_level)) << "Seasocks: " << message;
 }
 
 }  // namespace aos::seasocks
diff --git a/aos/starter/BUILD b/aos/starter/BUILD
index 9d359d4..13751e0 100644
--- a/aos/starter/BUILD
+++ b/aos/starter/BUILD
@@ -37,7 +37,8 @@
         "//aos/events:shm_event_loop",
         "//aos/util:scoped_pipe",
         "//aos/util:top",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -53,7 +54,8 @@
         "//aos:configuration",
         "//aos:macros",
         "//aos/events:shm_event_loop",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -179,7 +181,8 @@
     deps = [
         ":starter_rpc_lib",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings:str_format",
     ],
 )
@@ -245,7 +248,8 @@
     hdrs = ["irq_affinity_lib.h"],
     deps = [
         "//aos/scoped:scoped_fd",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
diff --git a/aos/starter/irq_affinity.cc b/aos/starter/irq_affinity.cc
index 94c9c71..0dad287 100644
--- a/aos/starter/irq_affinity.cc
+++ b/aos/starter/irq_affinity.cc
@@ -15,12 +15,13 @@
 #include <utility>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
@@ -33,12 +34,13 @@
 #include "aos/util/file.h"
 #include "aos/util/top.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
 
-DEFINE_string(user, "",
-              "Starter runs as though this user ran a SUID binary if set.");
-DEFINE_string(irq_config, "rockpi_config.json",
-              "File path of rockpi configuration");
+ABSL_FLAG(std::string, user, "",
+          "Starter runs as though this user ran a SUID binary if set.");
+ABSL_FLAG(std::string, irq_config, "rockpi_config.json",
+          "File path of rockpi configuration");
 
 namespace aos {
 
@@ -281,7 +283,7 @@
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  if (!FLAGS_user.empty()) {
+  if (!absl::GetFlag(FLAGS_user).empty()) {
     // Maintain root permissions as we switch to become the user so we can
     // actually manipulate priorities.
     PCHECK(prctl(PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP | SECBIT_NOROOT) ==
@@ -290,12 +292,12 @@
     uid_t uid;
     uid_t gid;
     {
-      struct passwd *user_data = getpwnam(FLAGS_user.c_str());
+      struct passwd *user_data = getpwnam(absl::GetFlag(FLAGS_user).c_str());
       if (user_data != nullptr) {
         uid = user_data->pw_uid;
         gid = user_data->pw_gid;
       } else {
-        LOG(FATAL) << "Could not find user " << FLAGS_user;
+        LOG(FATAL) << "Could not find user " << absl::GetFlag(FLAGS_user);
         return 1;
       }
     }
@@ -306,22 +308,22 @@
     constexpr int kUnchanged = -1;
     if (setresgid(/* ruid */ gid, /* euid */ gid,
                   /* suid */ kUnchanged) != 0) {
-      PLOG(FATAL) << "Failed to change GID to " << FLAGS_user;
+      PLOG(FATAL) << "Failed to change GID to " << absl::GetFlag(FLAGS_user);
     }
 
     if (setresuid(/* ruid */ uid, /* euid */ uid,
                   /* suid */ kUnchanged) != 0) {
-      PLOG(FATAL) << "Failed to change UID to " << FLAGS_user;
+      PLOG(FATAL) << "Failed to change UID to " << absl::GetFlag(FLAGS_user);
     }
   }
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::FlatbufferDetachedBuffer<aos::starter::IrqAffinityConfig>
       irq_affinity_config =
           aos::JsonFileToFlatbuffer<aos::starter::IrqAffinityConfig>(
-              FLAGS_irq_config);
+              absl::GetFlag(FLAGS_irq_config));
 
   aos::ShmEventLoop shm_event_loop(&config.message());
 
diff --git a/aos/starter/irq_affinity_lib.cc b/aos/starter/irq_affinity_lib.cc
index 7075e31..de58be6 100644
--- a/aos/starter/irq_affinity_lib.cc
+++ b/aos/starter/irq_affinity_lib.cc
@@ -7,12 +7,13 @@
 #include <ostream>
 #include <utility>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/ascii.h"
 #include "absl/strings/match.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_split.h"
 #include "absl/strings/string_view.h"
-#include "glog/logging.h"
 
 #include "aos/scoped/scoped_fd.h"
 
diff --git a/aos/starter/mock_starter.cc b/aos/starter/mock_starter.cc
index d52db95..d729833 100644
--- a/aos/starter/mock_starter.cc
+++ b/aos/starter/mock_starter.cc
@@ -5,11 +5,12 @@
 #include <string_view>
 #include <utility>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/flatbuffer_builder.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/starter/starter_rpc_generated.h"
diff --git a/aos/starter/starter_cmd.cc b/aos/starter/starter_cmd.cc
index b79485a..c4d324d 100644
--- a/aos/starter/starter_cmd.cc
+++ b/aos/starter/starter_cmd.cc
@@ -16,12 +16,13 @@
 #include <utility>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/flatbuffers.h"
@@ -31,21 +32,21 @@
 #include "aos/starter/starter_rpc_lib.h"
 #include "aos/time/time.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
 // TODO(james): Bash autocompletion for node names.
-DEFINE_string(
-    node, "",
-    "Node to interact with. If empty, just interact with local node.");
-DEFINE_bool(all_nodes, false, "Interact with all nodes.");
+ABSL_FLAG(std::string, node, "",
+          "Node to interact with. If empty, just interact with local node.");
+ABSL_FLAG(bool, all_nodes, false, "Interact with all nodes.");
 
-DEFINE_bool(_bash_autocomplete, false,
-            "Internal use: Outputs commands or applications for use with "
-            "autocomplete script.");
-DEFINE_string(_bash_autocomplete_word, "",
-              "Internal use: Current word being autocompleted");
-DEFINE_string(sort, "name",
-              "The name of the column to sort processes by.  "
-              "Can be \"name\", \"state\", \"pid\", or \"uptime\".");
+ABSL_FLAG(bool, _bash_autocomplete, false,
+          "Internal use: Outputs commands or applications for use with "
+          "autocomplete script.");
+ABSL_FLAG(std::string, _bash_autocomplete_word, "",
+          "Internal use: Current word being autocompleted");
+ABSL_FLAG(std::string, sort, "name",
+          "The name of the column to sort processes by.  "
+          "Can be \"name\", \"state\", \"pid\", or \"uptime\".");
 
 namespace {
 
@@ -62,12 +63,14 @@
     return {nullptr};
   }
 
-  if (!FLAGS_node.empty()) {
-    CHECK(!FLAGS_all_nodes) << "Can't specify both --node and --all_nodes.";
-    return {aos::configuration::GetNode(configuration, FLAGS_node)};
+  if (!absl::GetFlag(FLAGS_node).empty()) {
+    CHECK(!absl::GetFlag(FLAGS_all_nodes))
+        << "Can't specify both --node and --all_nodes.";
+    return {
+        aos::configuration::GetNode(configuration, absl::GetFlag(FLAGS_node))};
   }
 
-  if (FLAGS_all_nodes) {
+  if (absl::GetFlag(FLAGS_all_nodes)) {
     return aos::configuration::GetNodes(configuration);
   }
 
@@ -114,25 +117,26 @@
     sorted_statuses.push_back(app_status);
   }
   // If --sort flag not set, then return this unsorted vector as is.
-  if (FLAGS_sort.empty()) {
+  if (absl::GetFlag(FLAGS_sort).empty()) {
     return sorted_statuses;
   }
 
   // Convert --sort flag to lowercase for testing below.
-  std::transform(FLAGS_sort.begin(), FLAGS_sort.end(), FLAGS_sort.begin(),
-                 tolower);
+  std::transform(absl::GetFlag(FLAGS_sort).begin(),
+                 absl::GetFlag(FLAGS_sort).end(),
+                 absl::GetFlag(FLAGS_sort).begin(), tolower);
 
   // This function is called once for each node being reported upon, so there is
   // no need to sort on node, it happens implicitly.
 
-  if (FLAGS_sort == "name") {
+  if (absl::GetFlag(FLAGS_sort) == "name") {
     // Sort on name using std::string_view::operator< for lexicographic order.
     std::sort(sorted_statuses.begin(), sorted_statuses.end(),
               [](const aos::starter::ApplicationStatus *lhs,
                  const aos::starter::ApplicationStatus *rhs) {
                 return lhs->name()->string_view() < rhs->name()->string_view();
               });
-  } else if (FLAGS_sort == "state") {
+  } else if (absl::GetFlag(FLAGS_sort) == "state") {
     // Sort on state first, and then name for apps in same state.
     // ApplicationStatus::state is an enum, so need to call EnumNameState()
     // convenience wrapper to convert enum to char*, and then wrap in
@@ -148,7 +152,7 @@
                            : (lhs->name()->string_view() <
                               rhs->name()->string_view());
               });
-  } else if (FLAGS_sort == "pid") {
+  } else if (absl::GetFlag(FLAGS_sort) == "pid") {
     // Sort on pid first, and then name for when both apps are not running.
     // If the app state is STOPPED, then it will not have a pid, so need to test
     // that first. If only one app is STOPPED, then return Boolean state to put
@@ -171,7 +175,7 @@
                   }
                 }
               });
-  } else if (FLAGS_sort == "uptime") {
+  } else if (absl::GetFlag(FLAGS_sort) == "uptime") {
     // Sort on last_start_time first, and then name for when both apps are not
     // running, or have exact same start time. Only use last_start_time when app
     // is not STOPPED. If only one app is STOPPED, then return Boolean state to
@@ -198,7 +202,8 @@
           }
         });
   } else {
-    std::cerr << "Unknown sort criteria \"" << FLAGS_sort << "\"" << std::endl;
+    std::cerr << "Unknown sort criteria \"" << absl::GetFlag(FLAGS_sort) << "\""
+              << std::endl;
     exit(1);
   }
 
@@ -486,7 +491,7 @@
   const std::string_view app_name = (argc >= 3 ? argv[2] : "");
 
   std::cout << "COMPREPLY=(";
-  if (FLAGS__bash_autocomplete_word == command) {
+  if (absl::GetFlag(FLAGS__bash_autocomplete_word) == command) {
     // Autocomplete the starter command
     for (const auto &entry : kCommands) {
       if (std::get<0>(entry).find(command) == 0) {
@@ -515,9 +520,9 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
-  if (FLAGS__bash_autocomplete) {
+  if (absl::GetFlag(FLAGS__bash_autocomplete)) {
     Autocomplete(argc, argv, &config.message());
     return 0;
   }
diff --git a/aos/starter/starter_rpc_lib.cc b/aos/starter/starter_rpc_lib.cc
index b497792..4a54f71 100644
--- a/aos/starter/starter_rpc_lib.cc
+++ b/aos/starter/starter_rpc_lib.cc
@@ -3,11 +3,12 @@
 #include <algorithm>
 #include <ostream>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/flatbuffer_builder.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 #include "aos/events/context.h"
 #include "aos/events/shm_event_loop.h"
diff --git a/aos/starter/starter_test.cc b/aos/starter/starter_test.cc
index 0a074e0..65d43aa 100644
--- a/aos/starter/starter_test.cc
+++ b/aos/starter/starter_test.cc
@@ -8,10 +8,12 @@
 #include <string>
 #include <thread>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
 #include "flatbuffers/string.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
@@ -56,7 +58,7 @@
  public:
   StarterdTest() {
     // Nuke the shm dir:
-    aos::util::UnlinkRecursive(FLAGS_shm_base);
+    aos::util::UnlinkRecursive(absl::GetFlag(FLAGS_shm_base));
   }
 
  protected:
@@ -71,7 +73,7 @@
                    std::chrono::milliseconds(100));
   }
 
-  gflags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
   // Used to track when the test completes so that we can clean up the starter
   // in its thread.
   std::atomic<bool> test_done_{false};
@@ -87,8 +89,8 @@
       public ::testing::WithParamInterface<TestParams> {};
 
 TEST_P(StarterdConfigParamTest, MultiNodeStartStopTest) {
-  gflags::FlagSaver flag_saver;
-  FLAGS_override_hostname = GetParam().hostname;
+  absl::FlagSaver flag_saver;
+  absl::SetFlag(&FLAGS_override_hostname, GetParam().hostname);
   const std::string config_file = ArtifactPath(GetParam().config);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
@@ -111,9 +113,9 @@
                                     "args": ["--shm_base", "%s", "--config", "%s", "--override_hostname", "%s"]
                                   }
                                 ]})",
-          ArtifactPath("aos/events/ping"), FLAGS_shm_base, config_file,
-          GetParam().hostname, ArtifactPath("aos/events/pong"), FLAGS_shm_base,
-          config_file, GetParam().hostname));
+          ArtifactPath("aos/events/ping"), absl::GetFlag(FLAGS_shm_base),
+          config_file, GetParam().hostname, ArtifactPath("aos/events/pong"),
+          absl::GetFlag(FLAGS_shm_base), config_file, GetParam().hostname));
 
   const aos::Configuration *config_msg = &new_config.message();
 
@@ -220,8 +222,9 @@
       aos::configuration::ReadConfig(config_file);
 
   auto new_config = aos::configuration::MergeWithConfig(
-      &config.message(), absl::StrFormat(
-                             R"({"applications": [
+      &config.message(),
+      absl::StrFormat(
+          R"({"applications": [
                                   {
                                     "name": "ping",
                                     "executable_name": "%s",
@@ -233,8 +236,8 @@
                                     "args": ["--shm_base", "%s"]
                                   }
                                 ]})",
-                             ArtifactPath("aos/events/ping"), FLAGS_shm_base,
-                             ArtifactPath("aos/events/pong"), FLAGS_shm_base));
+          ArtifactPath("aos/events/ping"), absl::GetFlag(FLAGS_shm_base),
+          ArtifactPath("aos/events/pong"), absl::GetFlag(FLAGS_shm_base)));
 
   const aos::Configuration *config_msg = &new_config.message();
 
@@ -307,8 +310,9 @@
       aos::configuration::ReadConfig(config_file);
 
   auto new_config = aos::configuration::MergeWithConfig(
-      &config.message(), absl::StrFormat(
-                             R"({"applications": [
+      &config.message(),
+      absl::StrFormat(
+          R"({"applications": [
                                   {
                                     "name": "ping",
                                     "executable_name": "%s",
@@ -321,8 +325,8 @@
                                     "args": ["--shm_base", "%s"]
                                   }
                                 ]})",
-                             ArtifactPath("aos/events/ping"), FLAGS_shm_base,
-                             ArtifactPath("aos/events/pong"), FLAGS_shm_base));
+          ArtifactPath("aos/events/ping"), absl::GetFlag(FLAGS_shm_base),
+          ArtifactPath("aos/events/pong"), absl::GetFlag(FLAGS_shm_base)));
 
   const aos::Configuration *config_msg = &new_config.message();
 
@@ -397,8 +401,9 @@
       aos::configuration::ReadConfig(config_file);
 
   auto new_config = aos::configuration::MergeWithConfig(
-      &config.message(), absl::StrFormat(
-                             R"({"applications": [
+      &config.message(),
+      absl::StrFormat(
+          R"({"applications": [
                                   {
                                     "name": "ping",
                                     "executable_name": "%s",
@@ -411,8 +416,8 @@
                                     "args": ["--shm_base", "%s"]
                                   }
                                 ]})",
-                             ArtifactPath("aos/events/ping"), FLAGS_shm_base,
-                             ArtifactPath("aos/events/pong"), FLAGS_shm_base));
+          ArtifactPath("aos/events/ping"), absl::GetFlag(FLAGS_shm_base),
+          ArtifactPath("aos/events/pong"), absl::GetFlag(FLAGS_shm_base)));
 
   const aos::Configuration *config_msg = &new_config.message();
 
@@ -488,8 +493,9 @@
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
       aos::configuration::ReadConfig(config_file);
   auto new_config = aos::configuration::MergeWithConfig(
-      &config.message(), absl::StrFormat(
-                             R"({"applications": [
+      &config.message(),
+      absl::StrFormat(
+          R"({"applications": [
                                 {
                                   "name": "ping",
                                   "executable_name": "%s",
@@ -502,8 +508,8 @@
                                   "args": ["--shm_base", "%s"]
                                 }
                               ]})",
-                             ArtifactPath("aos/events/ping"), FLAGS_shm_base,
-                             ArtifactPath("aos/events/pong"), FLAGS_shm_base));
+          ArtifactPath("aos/events/ping"), absl::GetFlag(FLAGS_shm_base),
+          ArtifactPath("aos/events/pong"), absl::GetFlag(FLAGS_shm_base)));
 
   const aos::Configuration *config_msg = &new_config.message();
   // Set up starter with config file
diff --git a/aos/starter/starterd.cc b/aos/starter/starterd.cc
index 64858d4..127bf41 100644
--- a/aos/starter/starterd.cc
+++ b/aos/starter/starterd.cc
@@ -4,8 +4,9 @@
 #include <ostream>
 #include <string>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
@@ -14,33 +15,34 @@
 #include "aos/starter/starterd_lib.h"
 #include "aos/util/file.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
-DEFINE_string(user, "",
-              "Starter runs as though this user ran a SUID binary if set.");
-DEFINE_string(version_string, "",
-              "Version to report for starterd and subprocesses.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
+ABSL_FLAG(std::string, user, "",
+          "Starter runs as though this user ran a SUID binary if set.");
+ABSL_FLAG(std::string, version_string, "",
+          "Version to report for starterd and subprocesses.");
 
-DECLARE_string(shm_base);
-DEFINE_bool(purge_shm_base, false,
-            "If true, delete everything in --shm_base before starting.");
+ABSL_DECLARE_FLAG(std::string, shm_base);
+ABSL_FLAG(bool, purge_shm_base, false,
+          "If true, delete everything in --shm_base before starting.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  if (FLAGS_purge_shm_base) {
-    aos::util::UnlinkRecursive(FLAGS_shm_base);
+  if (absl::GetFlag(FLAGS_purge_shm_base)) {
+    aos::util::UnlinkRecursive(absl::GetFlag(FLAGS_shm_base));
   }
 
-  if (!FLAGS_user.empty()) {
+  if (!absl::GetFlag(FLAGS_user).empty()) {
     uid_t uid;
     uid_t gid;
     {
-      struct passwd *user_data = getpwnam(FLAGS_user.c_str());
+      struct passwd *user_data = getpwnam(absl::GetFlag(FLAGS_user).c_str());
       if (user_data != nullptr) {
         uid = user_data->pw_uid;
         gid = user_data->pw_gid;
       } else {
-        LOG(FATAL) << "Could not find user " << FLAGS_user;
+        LOG(FATAL) << "Could not find user " << absl::GetFlag(FLAGS_user);
         return 1;
       }
     }
@@ -51,24 +53,24 @@
     constexpr int kUnchanged = -1;
     if (setresgid(/* ruid */ gid, /* euid */ gid,
                   /* suid */ kUnchanged) != 0) {
-      PLOG(FATAL) << "Failed to change GID to " << FLAGS_user << ", group "
-                  << gid;
+      PLOG(FATAL) << "Failed to change GID to " << absl::GetFlag(FLAGS_user)
+                  << ", group " << gid;
     }
 
     if (setresuid(/* ruid */ uid, /* euid */ uid,
                   /* suid */ kUnchanged) != 0) {
-      PLOG(FATAL) << "Failed to change UID to " << FLAGS_user;
+      PLOG(FATAL) << "Failed to change UID to " << absl::GetFlag(FLAGS_user);
     }
   }
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   const aos::Configuration *config_msg = &config.message();
 
   aos::starter::Starter starter(config_msg);
-  if (!FLAGS_version_string.empty()) {
-    starter.event_loop()->SetVersionString(FLAGS_version_string);
+  if (!absl::GetFlag(FLAGS_version_string).empty()) {
+    starter.event_loop()->SetVersionString(absl::GetFlag(FLAGS_version_string));
   }
 
   starter.Run();
diff --git a/aos/starter/starterd_lib.cc b/aos/starter/starterd_lib.cc
index 79e564e..e507507 100644
--- a/aos/starter/starterd_lib.cc
+++ b/aos/starter/starterd_lib.cc
@@ -11,27 +11,29 @@
 #include <thread>
 #include <utility>
 
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/flatbuffer_builder.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/events/context.h"
 #include "aos/json_to_flatbuffer.h"
 
 // FLAGS_shm_base is defined elsewhere, declare it here so it can be used
 // to override the shared memory folder for unit testing.
-DECLARE_string(shm_base);
+ABSL_DECLARE_FLAG(std::string, shm_base);
 // FLAGS_permissions is defined elsewhere, declare it here so it can be used
 // to set the file permissions on the shared memory block.
-DECLARE_uint32(permissions);
+ABSL_DECLARE_FLAG(uint32_t, permissions);
 
-DEFINE_uint32(queue_initialization_threads, 0,
-              "Number of threads to spin up to initialize the queue.  0 means "
-              "use the main thread.");
-DECLARE_bool(enable_ftrace);
+ABSL_FLAG(uint32_t, queue_initialization_threads, 0,
+          "Number of threads to spin up to initialize the queue.  0 means "
+          "use the main thread.");
+ABSL_DECLARE_FLAG(bool, enable_ftrace);
 
 namespace aos::starter {
 
@@ -64,7 +66,7 @@
           1),
       timing_report_fetcher_(
           event_loop_.MakeFetcher<aos::timing::Report>("/aos")),
-      shm_base_(FLAGS_shm_base),
+      shm_base_(absl::GetFlag(FLAGS_shm_base)),
       listener_(&event_loop_,
                 [this](signalfd_siginfo signal) { OnSignal(signal); }),
       top_(&event_loop_, aos::util::Top::TrackThreadsMode::kDisabled,
@@ -132,7 +134,7 @@
     std::vector<const aos::Channel *> channels_to_construct;
     for (const aos::Channel *channel : *config_msg_->channels()) {
       if (aos::configuration::ChannelIsReadableOnNode(channel, this_node)) {
-        if (FLAGS_queue_initialization_threads == 0) {
+        if (absl::GetFlag(FLAGS_queue_initialization_threads) == 0) {
           AddChannel(channel);
         } else {
           channels_to_construct.push_back(channel);
@@ -140,11 +142,12 @@
       }
     }
 
-    if (FLAGS_queue_initialization_threads != 0) {
+    if (absl::GetFlag(FLAGS_queue_initialization_threads) != 0) {
       std::mutex pool_mutex;
       std::vector<std::thread> threads;
-      threads.reserve(FLAGS_queue_initialization_threads);
-      for (size_t i = 0; i < FLAGS_queue_initialization_threads; ++i) {
+      threads.reserve(absl::GetFlag(FLAGS_queue_initialization_threads));
+      for (size_t i = 0; i < absl::GetFlag(FLAGS_queue_initialization_threads);
+           ++i) {
         threads.emplace_back([this, &pool_mutex, &channels_to_construct]() {
           while (true) {
             const aos::Channel *channel;
@@ -160,7 +163,8 @@
           }
         });
       }
-      for (size_t i = 0; i < FLAGS_queue_initialization_threads; ++i) {
+      for (size_t i = 0; i < absl::GetFlag(FLAGS_queue_initialization_threads);
+           ++i) {
         threads[i].join();
       }
     }
@@ -230,7 +234,7 @@
   if (info.ssi_signo == SIGCHLD) {
     // SIGCHLD messages can be collapsed if multiple are received, so all
     // applications must check their status.
-    if (FLAGS_enable_ftrace) {
+    if (absl::GetFlag(FLAGS_enable_ftrace)) {
       ftrace_.FormatMessage("SIGCHLD");
       ftrace_.TurnOffOrDie();
     }
@@ -324,7 +328,8 @@
   CHECK(channel != nullptr);
   std::unique_ptr<aos::ipc_lib::MemoryMappedQueue> queue =
       std::make_unique<aos::ipc_lib::MemoryMappedQueue>(
-          shm_base_, FLAGS_permissions, event_loop_.configuration(), channel);
+          shm_base_, absl::GetFlag(FLAGS_permissions),
+          event_loop_.configuration(), channel);
 
   {
     std::unique_lock<std::mutex> locker(queue_mutex_);
diff --git a/aos/starter/subprocess.cc b/aos/starter/subprocess.cc
index c36d59b..593945b 100644
--- a/aos/starter/subprocess.cc
+++ b/aos/starter/subprocess.cc
@@ -15,9 +15,11 @@
 #include <ostream>
 #include <ratio>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_split.h"
-#include "glog/logging.h"
 
 #include "aos/util/file.h"
 #include "aos/util/process_info_generated.h"
@@ -655,7 +657,7 @@
       last_timing_report_ +
           // Leave a bit of margin on the timing report receipt time, to allow
           // for timing errors.
-          3 * std::chrono::milliseconds(FLAGS_timing_report_ms) >
+          3 * std::chrono::milliseconds(absl::GetFlag(FLAGS_timing_report_ms)) >
       event_loop_->monotonic_now());
   status_builder.add_last_stop_reason(stop_reason_);
   if (pid_ != -1) {
diff --git a/aos/starter/subprocess_reliable_test.cc b/aos/starter/subprocess_reliable_test.cc
index a395870..894b6fe 100644
--- a/aos/starter/subprocess_reliable_test.cc
+++ b/aos/starter/subprocess_reliable_test.cc
@@ -9,8 +9,9 @@
 #include <string>
 #include <thread>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/aos/starter/subprocess_test.cc b/aos/starter/subprocess_test.cc
index 2951b2b..d2dc3b0 100644
--- a/aos/starter/subprocess_test.cc
+++ b/aos/starter/subprocess_test.cc
@@ -6,10 +6,11 @@
 
 #include <ostream>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_join.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -25,15 +26,10 @@
 
 class SubprocessTest : public ::testing::Test {
  protected:
-  SubprocessTest() : shm_dir_(aos::testing::TestTmpDir() + "/aos") {
-    FLAGS_shm_base = shm_dir_;
-
+  SubprocessTest() {
     // Nuke the shm dir:
-    aos::util::UnlinkRecursive(shm_dir_);
+    aos::util::UnlinkRecursive(absl::GetFlag(FLAGS_shm_base));
   }
-
-  gflags::FlagSaver flag_saver_;
-  std::string shm_dir_;
 };
 
 TEST_F(SubprocessTest, CaptureOutputs) {
diff --git a/aos/stl_mutex/BUILD b/aos/stl_mutex/BUILD
index bc1e428..46c5bb9 100644
--- a/aos/stl_mutex/BUILD
+++ b/aos/stl_mutex/BUILD
@@ -8,7 +8,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "//aos/ipc_lib:aos_sync",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/stl_mutex/stl_mutex.h b/aos/stl_mutex/stl_mutex.h
index c719805..8450e73 100644
--- a/aos/stl_mutex/stl_mutex.h
+++ b/aos/stl_mutex/stl_mutex.h
@@ -4,7 +4,8 @@
 #include <mutex>
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/ipc_lib/aos_sync.h"
 #include "aos/macros.h"
diff --git a/aos/testing/BUILD b/aos/testing/BUILD
index 729c978..52fa271 100644
--- a/aos/testing/BUILD
+++ b/aos/testing/BUILD
@@ -12,8 +12,9 @@
     deps = [
         "//aos:init",
         "//aos/testing:tmpdir",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_googletest//:gtest",
     ],
 )
@@ -62,7 +63,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/testing/gtest_main.cc b/aos/testing/gtest_main.cc
index 1940988..ecf2889 100644
--- a/aos/testing/gtest_main.cc
+++ b/aos/testing/gtest_main.cc
@@ -1,14 +1,15 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/init.h"
 #include "aos/testing/tmpdir.h"
 
-DEFINE_bool(print_logs, false,
-            "Print the log messages as they are being generated.");
-DEFINE_string(log_file, "",
-              "Print all log messages to FILE instead of standard output.");
+ABSL_FLAG(bool, print_logs, false,
+          "Print the log messages as they are being generated.");
+ABSL_FLAG(std::string, log_file, "",
+          "Print all log messages to FILE instead of standard output.");
 
 namespace aos::testing {
 
@@ -20,22 +21,20 @@
 
 GTEST_API_ int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
-  FLAGS_logtostderr = true;
-
   aos::InitGoogle(&argc, &argv);
 
-  if (FLAGS_print_logs) {
+  if (absl::GetFlag(FLAGS_print_logs)) {
     if (::aos::testing::ForcePrintLogsDuringTests) {
       ::aos::testing::ForcePrintLogsDuringTests();
     }
   }
 
-  if (!FLAGS_log_file.empty()) {
+  if (!absl::GetFlag(FLAGS_log_file).empty()) {
     if (::aos::testing::ForcePrintLogsDuringTests) {
       ::aos::testing::ForcePrintLogsDuringTests();
     }
     if (::aos::testing::SetLogFileName) {
-      ::aos::testing::SetLogFileName(FLAGS_log_file.c_str());
+      ::aos::testing::SetLogFileName(absl::GetFlag(FLAGS_log_file).c_str());
     }
   }
 
diff --git a/aos/testing/prevent_exit.cc b/aos/testing/prevent_exit.cc
index 7c8da60..a475e45 100644
--- a/aos/testing/prevent_exit.cc
+++ b/aos/testing/prevent_exit.cc
@@ -4,7 +4,8 @@
 
 #include <cstdlib>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos::testing {
 namespace {
diff --git a/aos/testing/tmpdir.cc b/aos/testing/tmpdir.cc
index 0953a21..0aa00ea 100644
--- a/aos/testing/tmpdir.cc
+++ b/aos/testing/tmpdir.cc
@@ -3,6 +3,8 @@
 #include <cstdlib>
 #include <string>
 
+#include "absl/flags/flag.h"
+
 #include "aos/ipc_lib/shm_base.h"
 
 namespace aos::testing {
@@ -19,6 +21,8 @@
 
 std::string TestTmpDir() { return TestTmpDirOr("/tmp"); }
 
-void SetTestShmBase() { SetShmBase(TestTmpDirOr(FLAGS_shm_base)); }
+void SetTestShmBase() {
+  SetShmBase(TestTmpDirOr(absl::GetFlag(FLAGS_shm_base)));
+}
 
 }  // namespace aos::testing
diff --git a/aos/time/BUILD b/aos/time/BUILD
index 04ae38f..ffd7089 100644
--- a/aos/time/BUILD
+++ b/aos/time/BUILD
@@ -9,7 +9,8 @@
     visibility = ["//visibility:public"],
     deps = select({
         "@platforms//os:linux": [
-            "@com_github_google_glog//:glog",
+            "@com_google_absl//absl/log",
+            "@com_google_absl//absl/log:check",
             "@com_google_absl//absl/strings",
         ],
         "//conditions:default": ["//motors/core"],
diff --git a/aos/time/time.cc b/aos/time/time.cc
index 0e02481..3c88931 100644
--- a/aos/time/time.cc
+++ b/aos/time/time.cc
@@ -15,8 +15,9 @@
 
 #ifdef __linux__
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/numbers.h"
-#include "glog/logging.h"
 
 #else  // __linux__
 
diff --git a/aos/util/BUILD b/aos/util/BUILD
index 7e19d4d..814bab6 100644
--- a/aos/util/BUILD
+++ b/aos/util/BUILD
@@ -63,7 +63,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -203,7 +204,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -346,7 +348,8 @@
     deps = [
         "//aos/scoped:scoped_fd",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/types:span",
     ],
@@ -390,7 +393,8 @@
         ":process_info_fbs",
         "//aos/containers:ring_buffer",
         "//aos/events:event_loop",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -418,7 +422,8 @@
     hdrs = ["scoped_pipe.h"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -513,8 +518,9 @@
         ":config_validator_lib",
         "//aos:json_to_flatbuffer",
         "//aos/testing:googletest",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_googletest//:gtest",
     ],
 )
@@ -527,7 +533,8 @@
         ":foxglove_websocket_lib",
         "//aos:init",
         "//aos/events:shm_event_loop",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/flags:usage",
     ],
 )
 
@@ -561,7 +568,8 @@
         "//aos/events/logging:log_writer",
         "//aos/network:timestamp_channel",
         "//aos/testing:tmpdir",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_googletest//:gtest",
     ],
 )
@@ -616,8 +624,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "//aos/containers:inlined_vector",
-        "@com_github_google_glog//:glog",
         "@com_github_tartanllama_expected",
+        "@com_google_absl//absl/log",
         "@com_google_absl//absl/strings:str_format",
     ],
 )
diff --git a/aos/util/config_validator.cc b/aos/util/config_validator.cc
index 0ee1018..660a7bd 100644
--- a/aos/util/config_validator.cc
+++ b/aos/util/config_validator.cc
@@ -1,6 +1,6 @@
 #include <memory>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
@@ -9,9 +9,9 @@
 #include "aos/util/config_validator_config_generated.h"
 #include "aos/util/config_validator_lib.h"
 
-DEFINE_string(config, "", "Name of the config file to replay using.");
-DEFINE_string(validation_config, "{}",
-              "JSON config to use to validate the config.");
+ABSL_FLAG(std::string, config, "", "Name of the config file to replay using.");
+ABSL_FLAG(std::string, validation_config, "{}",
+          "JSON config to use to validate the config.");
 /* This binary is used to validate that all of the
    needed remote timestamps channels are in the config
    to log the timestamps.
@@ -23,14 +23,14 @@
    each one
    Reference superstructure_lib_test.cc*/
 TEST(ConfigValidatorTest, ReadConfig) {
-  ASSERT_TRUE(!FLAGS_config.empty());
+  ASSERT_TRUE(!absl::GetFlag(FLAGS_config).empty());
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   const aos::FlatbufferDetachedBuffer<aos::util::ConfigValidatorConfig>
       validator_config =
           aos::JsonToFlatbuffer<aos::util::ConfigValidatorConfig>(
-              FLAGS_validation_config);
+              absl::GetFlag(FLAGS_validation_config));
   aos::util::ConfigIsValid(&config.message(), &validator_config.message());
 }
 
diff --git a/aos/util/config_validator_lib.cc b/aos/util/config_validator_lib.cc
index 4347017..79309b0 100644
--- a/aos/util/config_validator_lib.cc
+++ b/aos/util/config_validator_lib.cc
@@ -13,12 +13,13 @@
 #include <utility>
 #include <vector>
 
+#include "absl/flags/declare.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/detached_buffer.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags_declare.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/event_loop.h"
@@ -36,7 +37,7 @@
 #include "aos/util/file.h"
 #include "aos/util/simulation_logger.h"
 
-DECLARE_bool(validate_timestamp_logger_nodes);
+ABSL_DECLARE_FLAG(bool, validate_timestamp_logger_nodes);
 
 namespace aos::util {
 
diff --git a/aos/util/error_counter.h b/aos/util/error_counter.h
index 7837f9e..c18c019 100644
--- a/aos/util/error_counter.h
+++ b/aos/util/error_counter.h
@@ -4,10 +4,11 @@
 
 #include <array>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/flatbuffer_builder.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 namespace aos::util {
 // Class to manage simple error counters for flatbuffer status message.
diff --git a/aos/util/file.h b/aos/util/file.h
index d0037fd..881af33 100644
--- a/aos/util/file.h
+++ b/aos/util/file.h
@@ -12,8 +12,9 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/scoped/scoped_fd.h"
 
diff --git a/aos/util/filesystem_monitor.cc b/aos/util/filesystem_monitor.cc
index df1dd22..be3229b 100644
--- a/aos/util/filesystem_monitor.cc
+++ b/aos/util/filesystem_monitor.cc
@@ -9,13 +9,14 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_split.h"
 #include "flatbuffers/buffer.h"
 #include "flatbuffers/flatbuffer_builder.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
@@ -24,7 +25,8 @@
 #include "aos/init.h"
 #include "aos/util/filesystem_generated.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
 
 namespace aos::util {
 namespace {
@@ -145,7 +147,7 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop shm_event_loop(&config.message());
 
diff --git a/aos/util/foxglove_websocket.cc b/aos/util/foxglove_websocket.cc
index 57326de..d71ceba 100644
--- a/aos/util/foxglove_websocket.cc
+++ b/aos/util/foxglove_websocket.cc
@@ -1,6 +1,7 @@
 #include <string>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -8,21 +9,21 @@
 #include "aos/init.h"
 #include "aos/util/foxglove_websocket_lib.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config.");
-DEFINE_uint32(port, 8765, "Port to use for foxglove websocket server.");
-DEFINE_string(mode, "flatbuffer", "json or flatbuffer serialization.");
-DEFINE_bool(fetch_pinned_channels, true,
-            "Set this to allow foxglove_websocket to make fetchers on channels "
-            "with a read_method of PIN (see aos/configuration.fbs; PIN is an "
-            "enum value). Having this enabled will cause foxglove to  consume "
-            "extra shared memory resources.");
-DEFINE_bool(
-    canonical_channel_names, false,
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the config.");
+ABSL_FLAG(uint32_t, port, 8765, "Port to use for foxglove websocket server.");
+ABSL_FLAG(std::string, mode, "flatbuffer", "json or flatbuffer serialization.");
+ABSL_FLAG(bool, fetch_pinned_channels, true,
+          "Set this to allow foxglove_websocket to make fetchers on channels "
+          "with a read_method of PIN (see aos/configuration.fbs; PIN is an "
+          "enum value). Having this enabled will cause foxglove to  consume "
+          "extra shared memory resources.");
+ABSL_FLAG(
+    bool, canonical_channel_names, false,
     "If set, use full channel names; by default, will shorten names to be the "
     "shortest possible version of the name (e.g., /aos instead of /pi/aos).");
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Runs a websocket server that a foxglove instance can connect to in "
       "order to view live data on a device.\n\n"
       "Typical Usage: foxglove_websocket [--port 8765]\n"
@@ -51,19 +52,19 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
   aos::FoxgloveWebsocketServer server(
-      &event_loop, FLAGS_port,
-      FLAGS_mode == "flatbuffer"
+      &event_loop, absl::GetFlag(FLAGS_port),
+      absl::GetFlag(FLAGS_mode) == "flatbuffer"
           ? aos::FoxgloveWebsocketServer::Serialization::kFlatbuffer
           : aos::FoxgloveWebsocketServer::Serialization::kJson,
-      FLAGS_fetch_pinned_channels
+      absl::GetFlag(FLAGS_fetch_pinned_channels)
           ? aos::FoxgloveWebsocketServer::FetchPinnedChannels::kYes
           : aos::FoxgloveWebsocketServer::FetchPinnedChannels::kNo,
-      FLAGS_canonical_channel_names
+      absl::GetFlag(FLAGS_canonical_channel_names)
           ? aos::FoxgloveWebsocketServer::CanonicalChannelNames::kCanonical
           : aos::FoxgloveWebsocketServer::CanonicalChannelNames::kShortened);
 
diff --git a/aos/util/foxglove_websocket_lib.cc b/aos/util/foxglove_websocket_lib.cc
index 7a825e4..de19443 100644
--- a/aos/util/foxglove_websocket_lib.cc
+++ b/aos/util/foxglove_websocket_lib.cc
@@ -6,13 +6,14 @@
 #include <utility>
 
 #include "absl/container/btree_set.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/escaping.h"
 #include "absl/types/span.h"
 #include "flatbuffers/reflection_generated.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "nlohmann/json.hpp"
 #include <foxglove/websocket/server.hpp>
 
@@ -24,9 +25,9 @@
 #include "aos/time/time.h"
 #include "aos/util/mcap_logger.h"
 
-DEFINE_uint32(sorting_buffer_ms, 100,
-              "Amount of time to buffer messages to sort them before sending "
-              "them to foxglove.");
+ABSL_FLAG(uint32_t, sorting_buffer_ms, 100,
+          "Amount of time to buffer messages to sort them before sending "
+          "them to foxglove.");
 
 namespace {
 // Period at which to poll the fetchers for all the channels.
@@ -117,7 +118,7 @@
     // out.
     const aos::monotonic_clock::time_point sort_until =
         event_loop_->monotonic_now() -
-        std::chrono::milliseconds(FLAGS_sorting_buffer_ms);
+        std::chrono::milliseconds(absl::GetFlag(FLAGS_sorting_buffer_ms));
 
     // Pair of <send_time, channel id>.
     absl::btree_set<std::pair<aos::monotonic_clock::time_point, ChannelId>>
diff --git a/aos/util/generate_test_log.cc b/aos/util/generate_test_log.cc
index 106e972..c028df7 100644
--- a/aos/util/generate_test_log.cc
+++ b/aos/util/generate_test_log.cc
@@ -1,7 +1,7 @@
 #include <chrono>
 #include <memory>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
@@ -13,8 +13,8 @@
 #include "aos/init.h"
 #include "aos/testing/path.h"
 
-DEFINE_string(output_folder, "",
-              "Name of folder to write the generated logfile to.");
+ABSL_FLAG(std::string, output_folder, "",
+          "Name of folder to write the generated logfile to.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
@@ -38,7 +38,7 @@
   std::unique_ptr<aos::EventLoop> log_writer_event_loop =
       event_loop_factory.MakeEventLoop("log_writer");
   aos::logger::Logger writer(log_writer_event_loop.get());
-  writer.StartLoggingOnRun(FLAGS_output_folder);
+  writer.StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
 
   event_loop_factory.RunFor(std::chrono::seconds(10));
   return 0;
diff --git a/aos/util/log_to_mcap.cc b/aos/util/log_to_mcap.cc
index 11b7940..9dc9cdb 100644
--- a/aos/util/log_to_mcap.cc
+++ b/aos/util/log_to_mcap.cc
@@ -6,9 +6,10 @@
 #include <string>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/reflection_generated.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/configuration.h"
 #include "aos/events/event_loop.h"
@@ -21,23 +22,23 @@
 #include "aos/util/clock_timepoints_schema.h"
 #include "aos/util/mcap_logger.h"
 
-DEFINE_string(node, "", "Node to replay from the perspective of.");
-DEFINE_string(output_path, "/tmp/log.mcap", "Log to output.");
-DEFINE_string(mode, "flatbuffer", "json or flatbuffer serialization.");
-DEFINE_bool(
-    canonical_channel_names, false,
+ABSL_FLAG(std::string, node, "", "Node to replay from the perspective of.");
+ABSL_FLAG(std::string, output_path, "/tmp/log.mcap", "Log to output.");
+ABSL_FLAG(std::string, mode, "flatbuffer", "json or flatbuffer serialization.");
+ABSL_FLAG(
+    bool, canonical_channel_names, false,
     "If set, use full channel names; by default, will shorten names to be the "
     "shortest possible version of the name (e.g., /aos instead of /pi/aos).");
-DEFINE_bool(compress, true, "Whether to use LZ4 compression in MCAP file.");
-DEFINE_bool(include_clocks, true,
-            "Whether to add a /clocks channel that publishes all nodes' clock "
-            "offsets.");
-DEFINE_bool(include_pre_start_messages, false,
-            "If set, *all* messages in the logfile will be included, including "
-            "any that may have occurred prior to the start of the log. This "
-            "can be used to see additional data, but given that data may be "
-            "incomplete prior to the start of the log, you should be careful "
-            "about interpretting data flow when using this flag.");
+ABSL_FLAG(bool, compress, true, "Whether to use LZ4 compression in MCAP file.");
+ABSL_FLAG(bool, include_clocks, true,
+          "Whether to add a /clocks channel that publishes all nodes' clock "
+          "offsets.");
+ABSL_FLAG(bool, include_pre_start_messages, false,
+          "If set, *all* messages in the logfile will be included, including "
+          "any that may have occurred prior to the start of the log. This "
+          "can be used to see additional data, but given that data may be "
+          "incomplete prior to the start of the log, you should be careful "
+          "about interpretting data flow when using this flag.");
 
 // Converts an AOS log to an MCAP log that can be fed into Foxglove. To try this
 // out, run:
@@ -55,7 +56,7 @@
   const std::set<std::string> logger_nodes = aos::logger::LoggerNodes(logfiles);
   CHECK_LT(0u, logger_nodes.size());
   const std::string logger_node = *logger_nodes.begin();
-  std::string replay_node = FLAGS_node;
+  std::string replay_node = absl::GetFlag(FLAGS_node);
   if (replay_node.empty()) {
     if (logger_nodes.size() == 1u) {
       LOG(INFO) << "Guessing \"" << logger_node
@@ -69,7 +70,7 @@
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config;
 
-  if (FLAGS_include_clocks) {
+  if (absl::GetFlag(FLAGS_include_clocks)) {
     aos::logger::LogReader config_reader(logfiles);
 
     if (aos::configuration::MultiNode(config_reader.configuration())) {
@@ -103,7 +104,7 @@
   std::unique_ptr<aos::ClockPublisher> clock_publisher;
 
   std::unique_ptr<aos::EventLoop> mcap_event_loop;
-  CHECK(!FLAGS_output_path.empty());
+  CHECK(!absl::GetFlag(FLAGS_output_path).empty());
   std::unique_ptr<aos::McapLogger> relogger;
   auto startup_handler = [&relogger, &mcap_event_loop, &reader,
                           &clock_event_loop, &clock_publisher, &factory,
@@ -112,22 +113,23 @@
                                "files from multi-boot logs.";
     mcap_event_loop = reader.event_loop_factory()->MakeEventLoop("mcap", node);
     relogger = std::make_unique<aos::McapLogger>(
-        mcap_event_loop.get(), FLAGS_output_path,
-        FLAGS_mode == "flatbuffer" ? aos::McapLogger::Serialization::kFlatbuffer
-                                   : aos::McapLogger::Serialization::kJson,
-        FLAGS_canonical_channel_names
+        mcap_event_loop.get(), absl::GetFlag(FLAGS_output_path),
+        absl::GetFlag(FLAGS_mode) == "flatbuffer"
+            ? aos::McapLogger::Serialization::kFlatbuffer
+            : aos::McapLogger::Serialization::kJson,
+        absl::GetFlag(FLAGS_canonical_channel_names)
             ? aos::McapLogger::CanonicalChannelNames::kCanonical
             : aos::McapLogger::CanonicalChannelNames::kShortened,
-        FLAGS_compress ? aos::McapLogger::Compression::kLz4
-                       : aos::McapLogger::Compression::kNone);
-    if (FLAGS_include_clocks) {
+        absl::GetFlag(FLAGS_compress) ? aos::McapLogger::Compression::kLz4
+                                      : aos::McapLogger::Compression::kNone);
+    if (absl::GetFlag(FLAGS_include_clocks)) {
       clock_event_loop =
           reader.event_loop_factory()->MakeEventLoop("clock", node);
       clock_publisher = std::make_unique<aos::ClockPublisher>(
           &factory, clock_event_loop.get());
     }
   };
-  if (FLAGS_include_pre_start_messages) {
+  if (absl::GetFlag(FLAGS_include_pre_start_messages)) {
     // Note: This condition is subtly different from just using --fetch from
     // mcap_logger.cc. Namely, if there is >1 message on a given channel prior
     // to the logfile start, then fetching in the reader OnStart() is
diff --git a/aos/util/mcap_logger.cc b/aos/util/mcap_logger.cc
index a70da62..47f8298 100644
--- a/aos/util/mcap_logger.cc
+++ b/aos/util/mcap_logger.cc
@@ -6,6 +6,9 @@
 #include <ostream>
 #include <set>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/types/span.h"
 #include "flatbuffers/buffer.h"
@@ -15,9 +18,6 @@
 #include "flatbuffers/reflection_generated.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
-#include "glog/vlog_is_on.h"
 #include "lz4/lz4frame.h"
 #include "nlohmann/json.hpp"
 
@@ -26,14 +26,14 @@
 #include "aos/flatbuffer_merge.h"
 #include "aos/json_to_flatbuffer.h"
 
-DEFINE_uint64(mcap_chunk_size, 10'000'000,
-              "Size, in bytes, of individual MCAP chunks");
-DEFINE_bool(fetch, false,
-            "Whether to fetch most recent messages at start of logfile. Turn "
-            "this on if there are, e.g., one-time messages sent before the "
-            "start of the logfile that you need access to. Turn it off if you "
-            "don't want to deal with having messages that have timestamps that "
-            "may be arbitrarily far before any other interesting messages.");
+ABSL_FLAG(uint64_t, mcap_chunk_size, 10'000'000,
+          "Size, in bytes, of individual MCAP chunks");
+ABSL_FLAG(bool, fetch, false,
+          "Whether to fetch most recent messages at start of logfile. Turn "
+          "this on if there are, e.g., one-time messages sent before the "
+          "start of the logfile that you need access to. Turn it off if you "
+          "don't want to deal with having messages that have timestamps that "
+          "may be arbitrarily far before any other interesting messages.");
 
 namespace aos {
 
@@ -246,13 +246,13 @@
             ChunkStatus *chunk = &current_chunks_[id];
             WriteMessage(id, channel, context, chunk);
             if (static_cast<uint64_t>(chunk->data.tellp()) >
-                FLAGS_mcap_chunk_size) {
+                absl::GetFlag(FLAGS_mcap_chunk_size)) {
               WriteChunk(chunk);
             }
           });
       fetchers_[id] = event_loop_->MakeRawFetcher(channel);
       event_loop_->OnRun([this, id, channel]() {
-        if (FLAGS_fetch && fetchers_[id]->Fetch()) {
+        if (absl::GetFlag(FLAGS_fetch) && fetchers_[id]->Fetch()) {
           WriteMessage(id, channel, fetchers_[id]->context(),
                        &current_chunks_[id]);
         }
diff --git a/aos/util/phased_loop.cc b/aos/util/phased_loop.cc
index 5f87bd0..92bda13 100644
--- a/aos/util/phased_loop.cc
+++ b/aos/util/phased_loop.cc
@@ -3,7 +3,8 @@
 #include <compare>
 #include <ratio>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos::time {
 
diff --git a/aos/util/scoped_pipe.cc b/aos/util/scoped_pipe.cc
index d178c0d..7983f7b 100644
--- a/aos/util/scoped_pipe.cc
+++ b/aos/util/scoped_pipe.cc
@@ -6,7 +6,8 @@
 
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos::util {
 
diff --git a/aos/util/status.cc b/aos/util/status.cc
index dbcd4af..e608ed5 100644
--- a/aos/util/status.cc
+++ b/aos/util/status.cc
@@ -1,5 +1,9 @@
 #include "aos/util/status.h"
 
+#include "absl/log/log.h"
+
+#include "aos/containers/inlined_vector.h"
+
 namespace aos {
 namespace {
 // Constructs a string view from the provided buffer if it has data and
diff --git a/aos/util/status.h b/aos/util/status.h
index fa2f4f0..9880fc7 100644
--- a/aos/util/status.h
+++ b/aos/util/status.h
@@ -4,8 +4,8 @@
 #include <source_location>
 #include <string_view>
 
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
-#include "glog/logging.h"
 #include "tl/expected.hpp"
 
 #include "aos/containers/inlined_vector.h"
diff --git a/aos/util/status_test.cc b/aos/util/status_test.cc
index b838636..fe77c61 100644
--- a/aos/util/status_test.cc
+++ b/aos/util/status_test.cc
@@ -8,8 +8,6 @@
 #include "aos/realtime.h"
 #include "aos/testing/path.h"
 
-DECLARE_bool(die_on_malloc);
-
 namespace aos::testing {
 class ErrorTest : public ::testing::Test {
  protected:
diff --git a/aos/util/threaded_consumer.h b/aos/util/threaded_consumer.h
index 471f6e1..05508a8 100644
--- a/aos/util/threaded_consumer.h
+++ b/aos/util/threaded_consumer.h
@@ -5,7 +5,8 @@
 #include <optional>
 #include <thread>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/condition.h"
 #include "aos/containers/ring_buffer.h"
diff --git a/aos/util/top.cc b/aos/util/top.cc
index 8a78609..28b4e69 100644
--- a/aos/util/top.cc
+++ b/aos/util/top.cc
@@ -15,6 +15,8 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/numeric/int128.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_cat.h"
@@ -22,7 +24,6 @@
 #include "absl/strings/str_split.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "glog/logging.h"
 
 #define PF_KTHREAD 0x00200000
 
@@ -225,9 +226,8 @@
   // Verify we can open the directory.
   DIR *dir = opendir(task_dir.c_str());
   if (dir == nullptr) {
-    LOG_EVERY_T(WARNING, 10) << "Unable to open directory: " << task_dir
-                             << ", error: " << strerror(errno);
-    ;
+    LOG_EVERY_N_SEC(WARNING, 10) << "Unable to open directory: " << task_dir
+                                 << ", error: " << strerror(errno);
     return;
   }
 
diff --git a/aos/util/top_test.cc b/aos/util/top_test.cc
index 7d9d2bb..9dc9c8c 100644
--- a/aos/util/top_test.cc
+++ b/aos/util/top_test.cc
@@ -13,10 +13,12 @@
 #include <thread>
 #include <vector>
 
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/string.h"
 #include "flatbuffers/vector.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 #include <gmock/gmock.h>
 
@@ -40,7 +42,7 @@
 class TopTest : public ::testing::Test {
  protected:
   TopTest()
-      : shm_dir_(aos::testing::TestTmpDir() + "/aos"),
+      : shm_dir_(aos::testing::TestTmpDir()),
         cpu_consumer_([this]() {
           SetThreadName(std::string(kTestCPUConsumer));
           while (!stop_flag_.load()) {
@@ -50,18 +52,18 @@
             aos::testing::ArtifactPath("aos/events/pingpong_config.json")),
         config_(aos::configuration::ReadConfig(config_file_)),
         event_loop_(&config_.message()) {
-    FLAGS_shm_base = shm_dir_;
+    aos::testing::SetShmBase(shm_dir_);
 
     // Nuke the shm dir, to ensure we aren't being affected by any preexisting
     // tests.
-    aos::util::UnlinkRecursive(shm_dir_);
+    aos::util::UnlinkRecursive(shm_dir_ + "/aos");
   }
   ~TopTest() {
     stop_flag_ = true;
     cpu_consumer_.join();
   }
 
-  gflags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
   std::string shm_dir_;
 
   std::thread cpu_consumer_;
diff --git a/aos/util/trapezoid_profile.cc b/aos/util/trapezoid_profile.cc
index be61889..4bd65fa 100644
--- a/aos/util/trapezoid_profile.cc
+++ b/aos/util/trapezoid_profile.cc
@@ -6,7 +6,8 @@
 #include <cstdlib>
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 
diff --git a/aos/uuid.cc b/aos/uuid.cc
index f794ec8..8dfaa0c 100644
--- a/aos/uuid.cc
+++ b/aos/uuid.cc
@@ -8,11 +8,12 @@
 #include <random>
 #include <string_view>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
-DEFINE_string(boot_uuid, "",
-              "If set, override the boot UUID to have this value instead.");
+ABSL_FLAG(std::string, boot_uuid, "",
+          "If set, override the boot UUID to have this value instead.");
 
 namespace aos {
 namespace {
@@ -184,8 +185,9 @@
 }
 
 UUID UUID::BootUUID() {
-  if (!FLAGS_boot_uuid.empty()) {
-    return UUID::FromString(FLAGS_boot_uuid);
+  auto flag = absl::GetFlag(FLAGS_boot_uuid);
+  if (!flag.empty()) {
+    return UUID::FromString(flag);
   }
 
   int fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY);
diff --git a/aos/uuid.h b/aos/uuid.h
index a2cf8ae..1e5d781 100644
--- a/aos/uuid.h
+++ b/aos/uuid.h
@@ -6,9 +6,10 @@
 #include <random>
 #include <string>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 
 namespace aos {
 
diff --git a/aos/uuid_collision_test.cc b/aos/uuid_collision_test.cc
index 99b870b..fce026f 100644
--- a/aos/uuid_collision_test.cc
+++ b/aos/uuid_collision_test.cc
@@ -1,7 +1,8 @@
 #include <set>
 #include <unordered_set>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/uuid.h"
diff --git a/aos/uuid_test.cc b/aos/uuid_test.cc
index f6ed21e..edfd5a8 100644
--- a/aos/uuid_test.cc
+++ b/aos/uuid_test.cc
@@ -1,6 +1,7 @@
 #include "aos/uuid.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 namespace aos::testing {
diff --git a/aos/vision/debug/BUILD b/aos/vision/debug/BUILD
index 7f796b9..9eae63c 100644
--- a/aos/vision/debug/BUILD
+++ b/aos/vision/debug/BUILD
@@ -51,7 +51,8 @@
         "//aos/vision/image:image_stream",
         "//aos/vision/image:image_types",
         "//aos/vision/image:jpeg_routines",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@usr_repo//:gtk+-3.0",
     ],
     alwayslink = 1,
diff --git a/aos/vision/debug/blob_log-source.cc b/aos/vision/debug/blob_log-source.cc
index c5ee67c..5ce60fb 100644
--- a/aos/vision/debug/blob_log-source.cc
+++ b/aos/vision/debug/blob_log-source.cc
@@ -7,7 +7,8 @@
 #include <functional>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/vision/blob/codec.h"
 #include "aos/vision/blob/stream_view.h"
diff --git a/aos/vision/events/BUILD b/aos/vision/events/BUILD
index c722acc..09d4d83 100644
--- a/aos/vision/events/BUILD
+++ b/aos/vision/events/BUILD
@@ -58,7 +58,8 @@
     deps = [
         "//aos:macros",
         "//aos/scoped:scoped_fd",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/aos/vision/events/udp.cc b/aos/vision/events/udp.cc
index 1b1a053..bc45ec8 100644
--- a/aos/vision/events/udp.cc
+++ b/aos/vision/events/udp.cc
@@ -7,7 +7,8 @@
 #include <cstring>
 #include <ostream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace aos::events {
 
diff --git a/build_tests/BUILD b/build_tests/BUILD
index 1eaf737..7a36208 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -15,7 +15,7 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -36,6 +36,8 @@
     data = [
         ":tcmalloc_build_test_binary",
     ],
+    # TODO(austin): Turn this back on when we get memory instrumentation figured out for tcmalloc for --die_on_malloc
+    tags = ["manual"],
     target_compatible_with = ["@platforms//os:linux"],
 )
 
diff --git a/build_tests/gflags.cc b/build_tests/gflags.cc
index b2f0d08..b5bcb57 100644
--- a/build_tests/gflags.cc
+++ b/build_tests/gflags.cc
@@ -1,5 +1,5 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
-DEFINE_int32(test_flag, 0, "Test command-line flag");
+ABSL_FLAG(int32_t, test_flag, 0, "Test command-line flag");
 
-int main() { return FLAGS_test_flag; }
+int main() { return absl::GetFlag(FLAGS_test_flag); }
diff --git a/documentation/aos/docs/getting_started.md b/documentation/aos/docs/getting_started.md
index 916c5a4..d1f56b8 100644
--- a/documentation/aos/docs/getting_started.md
+++ b/documentation/aos/docs/getting_started.md
@@ -410,10 +410,11 @@
 #include "foo/ping_lib.h"
 
 #include "aos/json_to_flatbuffer.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/log.h"
+#include "absl/log/check.h"
 
-DEFINE_int32(sleep_ms, 10, "Time to sleep between pings");
+ABSL_FLAG(int32_t, sleep_ms, 10, "Time to sleep between pings");
 
 namespace aos {
 
@@ -487,7 +488,7 @@
 In `ping_lib.cc`:
 
 ```cpp
-DEFINE_int32(sleep_ms, 10, "Time to sleep between pings");
+ABSL_FLAG(int32_t, sleep_ms, 10, "Time to sleep between pings");
 ```
 
 This creates a command-line flag `--sleep_ms` which can be accessed in the code
@@ -605,8 +606,8 @@
         ":pong_fbs",
         "//aos:json_to_flatbuffer",
         "//aos/events:event_loop",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log","@com_google_absl//absl/log:check",
     ],
 )
 ```
@@ -735,13 +736,13 @@
 #include "foo/ping_lib.h"
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 // Provide a --config flag that can be used to point to the config that the
 // application will use. Generally defaulted to the actual path that will be
 // used on the real system (most applications default to a name of
 // aos_config.json, by convention).
-DEFINE_string(config, "foo/pingpong_config.json", "Path to the config.");
+ABSL_FLAG(std::string, config, "foo/pingpong_config.json", "Path to the config.");
 
 int main(int argc, char **argv) {
   // Various common initialization steps, including command line flag parsing.
@@ -781,7 +782,7 @@
         "//aos:configuration",
         "//aos:init",
         "//aos/events:shm_event_loop",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 ```
@@ -880,7 +881,7 @@
         "//aos:configuration",
         "//aos:init",
         "//aos/events:shm_event_loop",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 ```
diff --git a/frc971/analysis/pdp_values.cc b/frc971/analysis/pdp_values.cc
index b314cc6..15b29b2 100644
--- a/frc971/analysis/pdp_values.cc
+++ b/frc971/analysis/pdp_values.cc
@@ -1,14 +1,15 @@
 #include <fstream>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
 #include "aos/init.h"
 #include "frc971/wpilib/pdp_values_generated.h"
 
-DEFINE_string(output_path, "/tmp/pdp_values.csv", "");
+ABSL_FLAG(std::string, output_path, "/tmp/pdp_values.csv", "");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
@@ -27,7 +28,7 @@
       event_loop_factory.MakeEventLoop("roborio", roborio);
 
   std::ofstream file_stream;
-  file_stream.open(FLAGS_output_path);
+  file_stream.open(absl::GetFlag(FLAGS_output_path));
   file_stream << "timestamp,currents,voltage\n";
 
   event_loop->SkipAosLog();
diff --git a/frc971/analysis/trim_log_to_enabled.cc b/frc971/analysis/trim_log_to_enabled.cc
index fb6b0c6..a92d74e 100644
--- a/frc971/analysis/trim_log_to_enabled.cc
+++ b/frc971/analysis/trim_log_to_enabled.cc
@@ -1,31 +1,34 @@
 #include <optional>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/init.h"
 #include "aos/util/simulation_logger.h"
 #include "frc971/input/joystick_state_generated.h"
 
-DEFINE_string(output_folder, "/tmp/trimmed/",
-              "Name of the folder to write the trimmed log to.");
-DEFINE_string(node, "roborio", "");
-DEFINE_bool(auto, false, "If set, trim the log to just the auto mode.");
-DEFINE_double(pre_enable_time_sec, 10.0,
-              "Amount of time to leave in the new log before the first enable "
-              "signal happens.");
-DEFINE_double(post_enable_time_sec, 1.0,
-              "Amount of time to leave in the new log after the final enable "
-              "signal ends.");
-DEFINE_double(force_start_monotonic, -1.0,
-              "If set, time, in seconds, at which to forcibly trim the start "
-              "of the log.");
-DEFINE_double(
-    force_end_monotonic, -1.0,
+ABSL_FLAG(std::string, output_folder, "/tmp/trimmed/",
+          "Name of the folder to write the trimmed log to.");
+ABSL_FLAG(std::string, node, "roborio", "");
+ABSL_FLAG(bool, auto, false, "If set, trim the log to just the auto mode.");
+ABSL_FLAG(double, pre_enable_time_sec, 10.0,
+          "Amount of time to leave in the new log before the first enable "
+          "signal happens.");
+ABSL_FLAG(double, post_enable_time_sec, 1.0,
+          "Amount of time to leave in the new log after the final enable "
+          "signal ends.");
+ABSL_FLAG(double, force_start_monotonic, -1.0,
+          "If set, time, in seconds, at which to forcibly trim the start "
+          "of the log.");
+ABSL_FLAG(
+    double, force_end_monotonic, -1.0,
     "If set, time, in seconds, at which to forcibly trim the end of the log.");
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "Trims the sections at the start/end of a log where the robot is "
       "disabled.");
   aos::InitGoogle(&argc, &argv);
@@ -34,35 +37,35 @@
   std::optional<aos::monotonic_clock::time_point> start_time;
   std::optional<aos::monotonic_clock::time_point> end_time;
   bool printed_match = false;
-  bool force_time_range = FLAGS_force_start_monotonic > 0;
+  bool force_time_range = absl::GetFlag(FLAGS_force_start_monotonic) > 0;
   // We need to do two passes through the logfile; one to figure out when the
   // start/end times are, one to actually do the trimming.
   if (!force_time_range) {
     aos::logger::LogReader reader(logfiles);
-    const aos::Node *roborio =
-        aos::configuration::GetNode(reader.configuration(), FLAGS_node);
+    const aos::Node *roborio = aos::configuration::GetNode(
+        reader.configuration(), absl::GetFlag(FLAGS_node));
     reader.Register();
     std::unique_ptr<aos::EventLoop> event_loop =
-        reader.event_loop_factory()->MakeEventLoop(FLAGS_node, roborio);
-    event_loop->MakeWatcher(
-        "/aos", [&start_time, &end_time, &printed_match,
-                 &event_loop](const aos::JoystickState &msg) {
-          if (!printed_match && msg.match_type() != aos::MatchType::kNone) {
-            LOG(INFO) << "Match Type: "
-                      << aos::EnumNameMatchType(msg.match_type());
-            LOG(INFO) << "Match #: " << msg.match_number();
-            printed_match = true;
-          }
+        reader.event_loop_factory()->MakeEventLoop(absl::GetFlag(FLAGS_node),
+                                                   roborio);
+    event_loop->MakeWatcher("/aos", [&start_time, &end_time, &printed_match,
+                                     &event_loop](
+                                        const aos::JoystickState &msg) {
+      if (!printed_match && msg.match_type() != aos::MatchType::kNone) {
+        LOG(INFO) << "Match Type: " << aos::EnumNameMatchType(msg.match_type());
+        LOG(INFO) << "Match #: " << msg.match_number();
+        printed_match = true;
+      }
 
-          if (msg.enabled() && (!FLAGS_auto || msg.autonomous())) {
-            // Note that time is monotonic, so we don't need to e.g. do min's or
-            // max's on the start/end time.
-            if (!start_time.has_value()) {
-              start_time = event_loop->context().monotonic_event_time;
-            }
-            end_time = event_loop->context().monotonic_event_time;
-          }
-        });
+      if (msg.enabled() && (!absl::GetFlag(FLAGS_auto) || msg.autonomous())) {
+        // Note that time is monotonic, so we don't need to e.g. do min's or
+        // max's on the start/end time.
+        if (!start_time.has_value()) {
+          start_time = event_loop->context().monotonic_event_time;
+        }
+        end_time = event_loop->context().monotonic_event_time;
+      }
+    });
 
     reader.event_loop_factory()->Run();
 
@@ -76,26 +79,32 @@
     LOG(INFO) << "First enable at " << start_time.value();
     LOG(INFO) << "Final enable at " << end_time.value();
     start_time.value() -= std::chrono::duration_cast<std::chrono::nanoseconds>(
-        std::chrono::duration<double>(FLAGS_pre_enable_time_sec));
+        std::chrono::duration<double>(
+            absl::GetFlag(FLAGS_pre_enable_time_sec)));
     end_time.value() += std::chrono::duration_cast<std::chrono::nanoseconds>(
-        std::chrono::duration<double>(FLAGS_post_enable_time_sec));
+        std::chrono::duration<double>(
+            absl::GetFlag(FLAGS_post_enable_time_sec)));
   } else {
-    CHECK_LT(FLAGS_force_start_monotonic, FLAGS_force_end_monotonic);
+    CHECK_LT(absl::GetFlag(FLAGS_force_start_monotonic),
+             absl::GetFlag(FLAGS_force_end_monotonic));
     start_time = aos::monotonic_clock::time_point(
         std::chrono::duration_cast<std::chrono::nanoseconds>(
-            std::chrono::duration<double>(FLAGS_force_start_monotonic)));
+            std::chrono::duration<double>(
+                absl::GetFlag(FLAGS_force_start_monotonic))));
     end_time = aos::monotonic_clock::time_point(
         std::chrono::duration_cast<std::chrono::nanoseconds>(
-            std::chrono::duration<double>(FLAGS_force_end_monotonic)));
+            std::chrono::duration<double>(
+                absl::GetFlag(FLAGS_force_end_monotonic))));
   }
 
   {
     aos::logger::LogReader reader(logfiles);
-    const aos::Node *roborio =
-        aos::configuration::GetNode(reader.configuration(), FLAGS_node);
+    const aos::Node *roborio = aos::configuration::GetNode(
+        reader.configuration(), absl::GetFlag(FLAGS_node));
     reader.Register();
     std::unique_ptr<aos::EventLoop> event_loop =
-        reader.event_loop_factory()->MakeEventLoop(FLAGS_node, roborio);
+        reader.event_loop_factory()->MakeEventLoop(absl::GetFlag(FLAGS_node),
+                                                   roborio);
     auto exit_timer = event_loop->AddTimer(
         [&reader]() { reader.event_loop_factory()->Exit(); });
     exit_timer->Schedule(start_time.value());
@@ -107,13 +116,13 @@
     // easily auto-detect which node to replay as when consuming the input logs.
     auto loggers = aos::util::MakeLoggersForNodes(
         reader.event_loop_factory(), {logger_nodes.begin(), logger_nodes.end()},
-        FLAGS_output_folder);
+        absl::GetFlag(FLAGS_output_folder));
     exit_timer->Schedule(end_time.value());
 
     reader.event_loop_factory()->Run();
   }
 
-  LOG(INFO) << "Trimmed logs written to " << FLAGS_output_folder;
+  LOG(INFO) << "Trimmed logs written to " << absl::GetFlag(FLAGS_output_folder);
 
   return EXIT_SUCCESS;
 }
diff --git a/frc971/can_logger/BUILD b/frc971/can_logger/BUILD
index 7c4a319..f72f085 100644
--- a/frc971/can_logger/BUILD
+++ b/frc971/can_logger/BUILD
@@ -11,7 +11,8 @@
         "//aos:init",
         "//aos/events:shm_event_loop",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -26,7 +27,8 @@
         ":can_logging_fbs",
         "//aos/events:shm_event_loop",
         "//aos/scoped:scoped_fd",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -51,7 +53,8 @@
         "//aos:init",
         "//aos/events/logging:log_reader",
         "//aos/time",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -67,6 +70,7 @@
         ":can_logging_fbs",
         "//aos/events:event_loop",
         "//aos/scoped:scoped_fd",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/frc971/can_logger/asc_logger.h b/frc971/can_logger/asc_logger.h
index e7d4e74..7ac8b5b 100644
--- a/frc971/can_logger/asc_logger.h
+++ b/frc971/can_logger/asc_logger.h
@@ -4,8 +4,9 @@
 #include <iomanip>
 #include <iostream>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "frc971/can_logger/can_logging_generated.h"
diff --git a/frc971/can_logger/can_logger.cc b/frc971/can_logger/can_logger.cc
index d020f6a..d350672 100644
--- a/frc971/can_logger/can_logger.cc
+++ b/frc971/can_logger/can_logger.cc
@@ -1,12 +1,14 @@
 #include "frc971/can_logger/can_logger.h"
 
-DEFINE_bool(poll, false,
-            "If true, poll the CAN bus every 100ms.  If false, wake up for "
-            "each frame and publish it.");
+#include "absl/flags/flag.h"
 
-DEFINE_int32(priority, 10,
-             "If --poll is not set, set the realtime priority to this.");
-DEFINE_int32(affinity, -1, "If positive, pin to this core.");
+ABSL_FLAG(bool, poll, false,
+          "If true, poll the CAN bus every 100ms.  If false, wake up for "
+          "each frame and publish it.");
+
+ABSL_FLAG(int32_t, priority, 10,
+          "If --poll is not set, set the realtime priority to this.");
+ABSL_FLAG(int32_t, affinity, -1, "If positive, pin to this core.");
 
 namespace frc971::can_logger {
 
@@ -17,12 +19,12 @@
       fd_(socket(PF_CAN, SOCK_RAW | SOCK_NONBLOCK, CAN_RAW)),
       frames_sender_(shm_event_loop_->MakeSender<CanFrame>(channel_name)) {
   // TODO(max): Figure out a proper priority
-  if (!FLAGS_poll) {
-    shm_event_loop_->SetRuntimeRealtimePriority(FLAGS_priority);
+  if (!absl::GetFlag(FLAGS_poll)) {
+    shm_event_loop_->SetRuntimeRealtimePriority(absl::GetFlag(FLAGS_priority));
   }
-  if (FLAGS_affinity >= 0) {
+  if (absl::GetFlag(FLAGS_affinity) >= 0) {
     shm_event_loop_->SetRuntimeAffinity(
-        aos::MakeCpusetFromCpus({FLAGS_affinity}));
+        aos::MakeCpusetFromCpus({absl::GetFlag(FLAGS_affinity)}));
   }
   struct ifreq ifr;
   strcpy(ifr.ifr_name, interface_name.data());
@@ -49,7 +51,7 @@
   CHECK_EQ(opt_size, sizeof(recieve_buffer_size));
   VLOG(0) << "CAN recieve bufffer is " << recieve_buffer_size << " bytes large";
 
-  if (FLAGS_poll) {
+  if (absl::GetFlag(FLAGS_poll)) {
     aos::TimerHandler *timer_handler =
         shm_event_loop_->AddTimer([this]() { Poll(); });
     timer_handler->set_name("CAN logging Loop");
diff --git a/frc971/can_logger/log_to_asc.cc b/frc971/can_logger/log_to_asc.cc
index 73ddd4e..38c09af 100644
--- a/frc971/can_logger/log_to_asc.cc
+++ b/frc971/can_logger/log_to_asc.cc
@@ -5,8 +5,8 @@
 #include "frc971/can_logger/asc_logger.h"
 #include "frc971/can_logger/can_logging_generated.h"
 
-DEFINE_string(node, "", "Node to replay from the perspective of.");
-DEFINE_string(output_path, "/tmp/can_log.asc", "Log to output.");
+ABSL_FLAG(std::string, node, "", "Node to replay from the perspective of.");
+ABSL_FLAG(std::string, output_path, "/tmp/can_log.asc", "Log to output.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
@@ -22,7 +22,7 @@
       break;
     }
   }
-  std::string replay_node = FLAGS_node;
+  std::string replay_node = absl::GetFlag(FLAGS_node);
   if (replay_node.empty() && all_logs_from_same_node) {
     LOG(INFO) << "Guessing \"" << logger_node
               << "\" as node given that --node was not specified.";
@@ -43,14 +43,14 @@
           : aos::configuration::GetNode(reader.configuration(), replay_node);
 
   std::unique_ptr<aos::EventLoop> can_event_loop;
-  CHECK(!FLAGS_output_path.empty());
+  CHECK(!absl::GetFlag(FLAGS_output_path).empty());
   std::unique_ptr<frc971::can_logger::AscLogger> relogger;
 
   factory.GetNodeEventLoopFactory(node)->OnStartup([&relogger, &can_event_loop,
                                                     &reader, node]() {
     can_event_loop = reader.event_loop_factory()->MakeEventLoop("can", node);
     relogger = std::make_unique<frc971::can_logger::AscLogger>(
-        can_event_loop.get(), FLAGS_output_path);
+        can_event_loop.get(), absl::GetFlag(FLAGS_output_path));
   });
   reader.event_loop_factory()->Run();
   reader.Deregister();
diff --git a/frc971/constants/BUILD b/frc971/constants/BUILD
index 3a7e73a..57cae2e 100644
--- a/frc971/constants/BUILD
+++ b/frc971/constants/BUILD
@@ -11,8 +11,9 @@
         "//aos/events:event_loop",
         "//aos/events:shm_event_loop",
         "//aos/network:team_number",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -33,8 +34,9 @@
         "//frc971/constants:constants_sender_lib",
         "//frc971/constants/testdata:constants_data_fbs",
         "//frc971/constants/testdata:constants_list_fbs",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -61,6 +63,7 @@
         "//aos/testing:path",
         "//frc971/constants/testdata:constants_data_fbs",
         "//frc971/constants/testdata:constants_list_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/frc971/constants/constants_sender_example.cc b/frc971/constants/constants_sender_example.cc
index a0b23ce..2beb9ec 100644
--- a/frc971/constants/constants_sender_example.cc
+++ b/frc971/constants/constants_sender_example.cc
@@ -1,5 +1,6 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,19 +10,20 @@
 #include "frc971/constants/testdata/constants_data_generated.h"
 #include "frc971/constants/testdata/constants_list_generated.h"
 
-DEFINE_string(config, "frc971/constants/testdata/aos_config.json",
-              "Path to the config.");
-DEFINE_string(constants_path, "frc971/constants/testdata/test_constants.json",
-              "Path to the constant file");
+ABSL_FLAG(std::string, config, "frc971/constants/testdata/aos_config.json",
+          "Path to the config.");
+ABSL_FLAG(std::string, constants_path,
+          "frc971/constants/testdata/test_constants.json",
+          "Path to the constant file");
 // This is just a sample binary
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
   frc971::constants::ConstantSender<frc971::constants::testdata::ConstantsData,
                                     frc971::constants::testdata::ConstantsList>
-      constants_sender(&event_loop, FLAGS_constants_path);
+      constants_sender(&event_loop, absl::GetFlag(FLAGS_constants_path));
   event_loop.Run();
 
   return 0;
diff --git a/frc971/constants/constants_sender_lib.h b/frc971/constants/constants_sender_lib.h
index 203435a..58da8d2 100644
--- a/frc971/constants/constants_sender_lib.h
+++ b/frc971/constants/constants_sender_lib.h
@@ -1,8 +1,9 @@
 #ifndef FRC971_CONSTANTS_CONSTANTS_SENDER_H_
 #define FRC971_CONSTANTS_CONSTANTS_SENDER_H_
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "aos/events/shm_event_loop.h"
diff --git a/frc971/constants/constants_sender_test.cc b/frc971/constants/constants_sender_test.cc
index e4920d3..c31499f 100644
--- a/frc971/constants/constants_sender_test.cc
+++ b/frc971/constants/constants_sender_test.cc
@@ -1,4 +1,5 @@
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
diff --git a/frc971/control_loops/BUILD b/frc971/control_loops/BUILD
index ccaac40..785d2c7 100644
--- a/frc971/control_loops/BUILD
+++ b/frc971/control_loops/BUILD
@@ -53,7 +53,8 @@
         "@platforms//os:linux": [
             "//aos/logging",
             "//third_party/cddlib",
-            "@com_github_google_glog//:glog",
+            "@com_google_absl//absl/log",
+            "@com_google_absl//absl/log:check",
         ],
         "//conditions:default": [],
     }),
@@ -106,7 +107,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
@@ -123,7 +125,8 @@
         ":runge_kutta",
         "//aos/testing:googletest",
         "//aos/testing:random_seed",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
@@ -386,7 +389,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
diff --git a/frc971/control_loops/aiming/aiming.cc b/frc971/control_loops/aiming/aiming.cc
index 572ed1c..646dc13 100644
--- a/frc971/control_loops/aiming/aiming.cc
+++ b/frc971/control_loops/aiming/aiming.cc
@@ -1,6 +1,7 @@
 #include "frc971/control_loops/aiming/aiming.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "frc971/zeroing/wrap.h"
 
diff --git a/frc971/control_loops/catapult/mpc_problem.h b/frc971/control_loops/catapult/mpc_problem.h
index 04e3936..1cbeb10 100644
--- a/frc971/control_loops/catapult/mpc_problem.h
+++ b/frc971/control_loops/catapult/mpc_problem.h
@@ -1,6 +1,7 @@
 #include "Eigen/Dense"
 #include "Eigen/Sparse"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/realtime.h"
 #include "aos/time/time.h"
diff --git a/frc971/control_loops/control_loop_test.h b/frc971/control_loops/control_loop_test.h
index 8b6ba09..0b918e2 100644
--- a/frc971/control_loops/control_loop_test.h
+++ b/frc971/control_loops/control_loop_test.h
@@ -4,7 +4,8 @@
 #include <chrono>
 #include <string_view>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
diff --git a/frc971/control_loops/double_jointed_arm/BUILD b/frc971/control_loops/double_jointed_arm/BUILD
index c7fcefc..79d464a 100644
--- a/frc971/control_loops/double_jointed_arm/BUILD
+++ b/frc971/control_loops/double_jointed_arm/BUILD
@@ -46,7 +46,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//frc971/control_loops:runge_kutta",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
diff --git a/frc971/control_loops/double_jointed_arm/dynamics.cc b/frc971/control_loops/double_jointed_arm/dynamics.cc
index 4910e6c..76577ec 100644
--- a/frc971/control_loops/double_jointed_arm/dynamics.cc
+++ b/frc971/control_loops/double_jointed_arm/dynamics.cc
@@ -1,6 +1,6 @@
 #include "frc971/control_loops/double_jointed_arm/dynamics.h"
 
-DEFINE_bool(gravity, true, "If true, enable gravity.");
+ABSL_FLAG(bool, gravity, true, "If true, enable gravity.");
 
 namespace frc971::control_loops::arm {
 
diff --git a/frc971/control_loops/double_jointed_arm/dynamics.h b/frc971/control_loops/double_jointed_arm/dynamics.h
index c28a20d..7a92105 100644
--- a/frc971/control_loops/double_jointed_arm/dynamics.h
+++ b/frc971/control_loops/double_jointed_arm/dynamics.h
@@ -2,11 +2,12 @@
 #define FRC971_CONTROL_LOOPS_DOUBLE_JOINTED_ARM_DYNAMICS_H_
 
 #include "Eigen/Dense"
-#include "gflags/gflags.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 
 #include "frc971/control_loops/runge_kutta.h"
 
-DECLARE_bool(gravity);
+ABSL_DECLARE_FLAG(bool, gravity);
 
 namespace frc971::control_loops::arm {
 
@@ -202,7 +203,7 @@
             arm_constants_.r1 * arm_constants_.m1 * ::std::sin(X(2)) *
                 accel_due_to_gravity)
                .finished() *
-           (FLAGS_gravity ? 1.0 : 0.0);
+           (absl::GetFlag(FLAGS_gravity) ? 1.0 : 0.0);
   }
 
   const ::Eigen::Matrix<double, 4, 1> UnboundedDiscreteDynamics(
diff --git a/frc971/control_loops/double_jointed_arm/ekf.cc b/frc971/control_loops/double_jointed_arm/ekf.cc
index b1ae70a..ec63fd1 100644
--- a/frc971/control_loops/double_jointed_arm/ekf.cc
+++ b/frc971/control_loops/double_jointed_arm/ekf.cc
@@ -3,14 +3,15 @@
 #include <iostream>
 
 #include "Eigen/Dense"
+#include "absl/flags/flag.h"
 
 #include "frc971/control_loops/double_jointed_arm/dynamics.h"
 #include "frc971/control_loops/jacobian.h"
 
-DEFINE_double(proximal_voltage_error_uncertainty, 8.0,
-              "Proximal joint voltage error uncertainty.");
-DEFINE_double(distal_voltage_error_uncertainty, 2.0,
-              "Distal joint voltage error uncertainty.");
+ABSL_FLAG(double, proximal_voltage_error_uncertainty, 8.0,
+          "Proximal joint voltage error uncertainty.");
+ABSL_FLAG(double, distal_voltage_error_uncertainty, 2.0,
+          "Distal joint voltage error uncertainty.");
 
 namespace frc971::control_loops::arm {
 
@@ -21,8 +22,8 @@
 ::Eigen::Matrix<double, 6, 6> Q_covariance(
     (::Eigen::DiagonalMatrix<double, 6>().diagonal() << ::std::pow(0.1, 2),
      ::std::pow(2.0, 2), ::std::pow(0.1, 2), ::std::pow(2.0, 2),
-     ::std::pow(FLAGS_proximal_voltage_error_uncertainty, 2),
-     ::std::pow(FLAGS_distal_voltage_error_uncertainty, 2))
+     ::std::pow(absl::GetFlag(FLAGS_proximal_voltage_error_uncertainty), 2),
+     ::std::pow(absl::GetFlag(FLAGS_distal_voltage_error_uncertainty), 2))
         .finished()
         .asDiagonal());
 }  // namespace
@@ -32,8 +33,8 @@
   Q_covariance =
       ((::Eigen::DiagonalMatrix<double, 6>().diagonal() << ::std::pow(0.1, 2),
         ::std::pow(2.0, 2), ::std::pow(0.1, 2), ::std::pow(2.0, 2),
-        ::std::pow(FLAGS_proximal_voltage_error_uncertainty, 2),
-        ::std::pow(FLAGS_distal_voltage_error_uncertainty, 2))
+        ::std::pow(absl::GetFlag(FLAGS_proximal_voltage_error_uncertainty), 2),
+        ::std::pow(absl::GetFlag(FLAGS_distal_voltage_error_uncertainty), 2))
            .finished()
            .asDiagonal());
   P_ = Q_covariance;
diff --git a/frc971/control_loops/double_jointed_arm/trajectory.cc b/frc971/control_loops/double_jointed_arm/trajectory.cc
index 8b5129d..0eaf67e 100644
--- a/frc971/control_loops/double_jointed_arm/trajectory.cc
+++ b/frc971/control_loops/double_jointed_arm/trajectory.cc
@@ -1,17 +1,17 @@
 #include "frc971/control_loops/double_jointed_arm/trajectory.h"
 
 #include "Eigen/Dense"
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/logging/logging.h"
 #include "frc971/control_loops/dlqr.h"
 #include "frc971/control_loops/double_jointed_arm/dynamics.h"
 #include "frc971/control_loops/jacobian.h"
 
-DEFINE_double(lqr_proximal_pos, 0.15, "Position LQR gain");
-DEFINE_double(lqr_proximal_vel, 4.0, "Velocity LQR gain");
-DEFINE_double(lqr_distal_pos, 0.20, "Position LQR gain");
-DEFINE_double(lqr_distal_vel, 4.0, "Velocity LQR gain");
+ABSL_FLAG(double, lqr_proximal_pos, 0.15, "Position LQR gain");
+ABSL_FLAG(double, lqr_proximal_vel, 4.0, "Velocity LQR gain");
+ABSL_FLAG(double, lqr_distal_pos, 0.20, "Position LQR gain");
+ABSL_FLAG(double, lqr_distal_vel, 4.0, "Velocity LQR gain");
 
 namespace frc971::control_loops::arm {
 
@@ -369,10 +369,10 @@
 ::Eigen::Matrix<double, 2, 6> TrajectoryFollower::K_at_state(
     const ::Eigen::Matrix<double, 6, 1> &X,
     const ::Eigen::Matrix<double, 2, 1> &U) {
-  const double kProximalPos = FLAGS_lqr_proximal_pos;
-  const double kProximalVel = FLAGS_lqr_proximal_vel;
-  const double kDistalPos = FLAGS_lqr_distal_pos;
-  const double kDistalVel = FLAGS_lqr_distal_vel;
+  const double kProximalPos = absl::GetFlag(FLAGS_lqr_proximal_pos);
+  const double kProximalVel = absl::GetFlag(FLAGS_lqr_proximal_vel);
+  const double kDistalPos = absl::GetFlag(FLAGS_lqr_distal_pos);
+  const double kDistalVel = absl::GetFlag(FLAGS_lqr_distal_vel);
   const ::Eigen::DiagonalMatrix<double, 4> Q =
       (::Eigen::DiagonalMatrix<double, 4>().diagonal()
            << 1.0 / ::std::pow(kProximalPos, 2),
diff --git a/frc971/control_loops/drivetrain/BUILD b/frc971/control_loops/drivetrain/BUILD
index 800af99..9aca44f 100644
--- a/frc971/control_loops/drivetrain/BUILD
+++ b/frc971/control_loops/drivetrain/BUILD
@@ -330,7 +330,7 @@
         "//aos/testing:googletest",
         "//aos/testing:test_shm",
         "//third_party/matplotlib-cpp",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -624,7 +624,7 @@
         ":spline",
         "//aos/analysis:in_process_plotter",
         "//aos/testing:googletest",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -640,7 +640,8 @@
         "//aos/logging",
         "//frc971/control_loops:control_loops_fbs",
         "//frc971/control_loops:fixed_quadrature",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
         "@org_tuxfamily_eigen//:eigen",
     ],
@@ -665,7 +666,7 @@
         "//aos:flatbuffers",
         "//aos/testing:googletest",
         "//aos/testing:test_shm",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ] + cpu_select({
         "amd64": [
             "//third_party/matplotlib-cpp",
@@ -721,7 +722,7 @@
         "//aos/network:team_number",
         "//third_party/matplotlib-cpp",
         "//y2019/control_loops/drivetrain:drivetrain_base",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
@@ -774,7 +775,8 @@
         "//frc971/control_loops:control_loops_fbs",
         "//frc971/control_loops:quaternion_utils",
         "//frc971/control_loops:runge_kutta",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
diff --git a/frc971/control_loops/drivetrain/distance_spline.cc b/frc971/control_loops/drivetrain/distance_spline.cc
index 80ef4c4..015aca4 100644
--- a/frc971/control_loops/drivetrain/distance_spline.cc
+++ b/frc971/control_loops/drivetrain/distance_spline.cc
@@ -1,6 +1,7 @@
 #include "frc971/control_loops/drivetrain/distance_spline.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/logging/logging.h"
 #include "frc971/control_loops/drivetrain/spline.h"
diff --git a/frc971/control_loops/drivetrain/distance_spline_test.cc b/frc971/control_loops/drivetrain/distance_spline_test.cc
index 806d39e..b2e6ac6 100644
--- a/frc971/control_loops/drivetrain/distance_spline_test.cc
+++ b/frc971/control_loops/drivetrain/distance_spline_test.cc
@@ -2,7 +2,7 @@
 
 #include <vector>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/flatbuffers.h"
@@ -11,7 +11,7 @@
 #include "third_party/matplotlib-cpp/matplotlibcpp.h"
 #endif
 
-DEFINE_bool(plot, false, "If true, plot");
+ABSL_FLAG(bool, plot, false, "If true, plot");
 
 namespace frc971::control_loops::drivetrain::testing {
 
@@ -78,7 +78,7 @@
 
 #if defined(SUPPORT_PLOT)
   // Conditionally plot the functions and their integrals to aid debugging.
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     matplotlibcpp::figure();
     matplotlibcpp::plot(distances_plot, x_plot, {{"label", "x"}});
     matplotlibcpp::plot(distances_plot, ix_plot, {{"label", "ix"}});
@@ -138,7 +138,7 @@
 
 #if defined(SUPPORT_PLOT)
   // Conditionally plot the functions and their integrals to aid debugging.
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     matplotlibcpp::figure();
     matplotlibcpp::plot(distances_plot, theta_plot, {{"label", "theta"}});
     matplotlibcpp::plot(distances_plot, itheta_plot, {{"label", "itheta"}});
diff --git a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
index c1aa2a5..9cd669d 100644
--- a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
@@ -3,7 +3,7 @@
 #include <chrono>
 #include <memory>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -24,8 +24,8 @@
 #include "frc971/control_loops/polytope.h"
 #include "frc971/queues/gyro_generated.h"
 
-DEFINE_string(output_file, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_file, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace frc971::control_loops::drivetrain::testing {
 
@@ -65,11 +65,11 @@
     set_send_delay(chrono::nanoseconds(0));
     set_battery_voltage(12.0);
 
-    if (!FLAGS_output_file.empty()) {
-      unlink(FLAGS_output_file.c_str());
+    if (!absl::GetFlag(FLAGS_output_file).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_file).c_str());
       logger_event_loop_ = MakeEventLoop("logger");
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_file);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_file));
     }
 
     // Run for enough time to allow the gyro/imu zeroing code to run.
diff --git a/frc971/control_loops/drivetrain/drivetrain_test_lib.cc b/frc971/control_loops/drivetrain/drivetrain_test_lib.cc
index 394be07..fc32148 100644
--- a/frc971/control_loops/drivetrain/drivetrain_test_lib.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_test_lib.cc
@@ -2,8 +2,9 @@
 
 #include <chrono>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "frc971/control_loops/drivetrain/trajectory.h"
@@ -18,7 +19,7 @@
 #include "y2016/control_loops/drivetrain/kalman_drivetrain_motor_plant.h"
 #include "y2016/control_loops/drivetrain/polydrivetrain_dog_motor_plant.h"
 
-DEFINE_bool(plot, false, "If true, plot");
+ABSL_FLAG(bool, plot, false, "If true, plot");
 
 namespace frc971::control_loops::drivetrain::testing {
 
@@ -137,7 +138,7 @@
         // Skip this the first time.
         if (!first_) {
           Simulate();
-          if (FLAGS_plot) {
+          if (absl::GetFlag(FLAGS_plot)) {
             EXPECT_TRUE(drivetrain_status_fetcher_.Fetch());
 
             ::Eigen::Matrix<double, 2, 1> actual_position = GetPosition();
@@ -368,7 +369,7 @@
 
 void DrivetrainSimulation::MaybePlot() {
 #if defined(SUPPORT_PLOT)
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     std::cout << "Plotting." << ::std::endl;
     matplotlibcpp::figure();
     matplotlibcpp::plot(actual_x_, actual_y_, {{"label", "actual position"}});
diff --git a/frc971/control_loops/drivetrain/improved_down_estimator.h b/frc971/control_loops/drivetrain/improved_down_estimator.h
index c778ad5..a73d575 100644
--- a/frc971/control_loops/drivetrain/improved_down_estimator.h
+++ b/frc971/control_loops/drivetrain/improved_down_estimator.h
@@ -3,7 +3,8 @@
 
 #include "Eigen/Dense"
 #include "Eigen/Geometry"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "aos/time/time.h"
diff --git a/frc971/control_loops/drivetrain/improved_down_estimator_test.cc b/frc971/control_loops/drivetrain/improved_down_estimator_test.cc
index c128429..c6cda26 100644
--- a/frc971/control_loops/drivetrain/improved_down_estimator_test.cc
+++ b/frc971/control_loops/drivetrain/improved_down_estimator_test.cc
@@ -2,7 +2,8 @@
 
 #include <random>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 #include <Eigen/Geometry>
 
diff --git a/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc b/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc
index ed018b9..4d88ab1 100644
--- a/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc
+++ b/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc
@@ -2,7 +2,7 @@
 
 #include <chrono>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 #include "third_party/matplotlib-cpp/matplotlibcpp.h"
 
@@ -10,7 +10,7 @@
 #include "frc971/control_loops/drivetrain/drivetrain_test_lib.h"
 #include "frc971/control_loops/drivetrain/trajectory.h"
 
-DECLARE_bool(plot);
+ABSL_DECLARE_FLAG(bool, plot);
 
 namespace chrono = ::std::chrono;
 
@@ -117,7 +117,7 @@
   }
 
   void TearDown() override {
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       matplotlibcpp::figure();
       matplotlibcpp::plot(time_, simulation_ul_, {{"label", "ul"}});
       matplotlibcpp::plot(time_, simulation_ur_, {{"label", "ur"}});
diff --git a/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc b/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc
index a4338a8..d08f8eb 100644
--- a/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc
+++ b/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc
@@ -2,7 +2,7 @@
 
 #include <queue>
 
-#include "gtest/gtest.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_writer.h"
 #include "aos/network/message_bridge_server_generated.h"
@@ -15,8 +15,8 @@
 #include "frc971/control_loops/team_number_test_environment.h"
 #include "y2022/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace frc971::control_loops::drivetrain::testing {
 
@@ -77,10 +77,10 @@
     set_team_id(frc971::control_loops::testing::kTeamNumber);
     set_battery_voltage(12.0);
 
-    if (!FLAGS_output_folder.empty()) {
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
 
     test_event_loop_->OnRun([this]() { SetStartingPosition({3.0, 2.0, 0.0}); });
diff --git a/frc971/control_loops/drivetrain/spline_test.cc b/frc971/control_loops/drivetrain/spline_test.cc
index b47f4ac..7209658 100644
--- a/frc971/control_loops/drivetrain/spline_test.cc
+++ b/frc971/control_loops/drivetrain/spline_test.cc
@@ -2,12 +2,12 @@
 
 #include <vector>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/analysis/in_process_plotter.h"
 
-DEFINE_bool(plot, false, "If true, plot");
+ABSL_FLAG(bool, plot, false, "If true, plot");
 
 namespace frc971::control_loops::drivetrain::testing {
 
@@ -21,13 +21,13 @@
 class SplineTest : public ::testing::Test {
  public:
   static void SetUpTestSuite() {
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       plotter_ = std::make_unique<aos::analysis::Plotter>();
     }
   }
 
   static void TearDownTestSuite() {
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       plotter_->Spin();
     }
   }
@@ -39,7 +39,7 @@
                             .finished()),
         spline4_(control_points_),
         spline6_(Spline4To6(control_points_)) {
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       CHECK(plotter_);
       plotter_->Title(TestName());
     }
@@ -47,7 +47,7 @@
   ~SplineTest() {}
 
   void TearDown() override {
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       plotter_->Publish();
     }
   }
@@ -115,7 +115,7 @@
   }
 
   // Conditionally plot the functions and their integrals to aid debugging.
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     plotter_->AddFigure("Spline Attributes Over Alpha");
     plotter_->AddLine(alphas_plot, x_plot, "X");
     plotter_->AddLine(alphas_plot, ix_plot, "Integrated X");
@@ -175,7 +175,7 @@
   }
 
   // Conditionally plot the functions and their integrals to aid debugging.
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     plotter_->AddFigure("Heading Plot");
     plotter_->AddLine(alphas_plot, theta_plot, "theta");
     plotter_->AddLine(alphas_plot, itheta_plot, "Integrated theta");
@@ -226,7 +226,7 @@
   }
 
   // Conditionally plot the functions and their integrals to aid debugging.
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     plotter_->AddFigure("Spline X/Y");
     plotter_->AddLine(alphas_plot, x_plot, "X");
     plotter_->AddLine(alphas_plot, y_plot, "Y");
diff --git a/frc971/control_loops/drivetrain/trajectory_plot.cc b/frc971/control_loops/drivetrain/trajectory_plot.cc
index 9eb95b5..8236e61 100644
--- a/frc971/control_loops/drivetrain/trajectory_plot.cc
+++ b/frc971/control_loops/drivetrain/trajectory_plot.cc
@@ -1,8 +1,9 @@
 #include <chrono>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "third_party/matplotlib-cpp/matplotlibcpp.h"
 
+#include "aos/init.h"
 #include "aos/logging/implementations.h"
 #include "aos/network/team_number.h"
 #include "aos/time/time.h"
@@ -28,15 +29,15 @@
 //
 // https://photos.google.com/share/AF1QipPl34MOTPem2QmmTC3B21dL7GV2_HjxnseRrqxgR60TUasyIPliIuWmnH3yxuSNZw?key=cVhZLUYycXBIZlNTRy10cjZlWm0tcmlqQl9MTE13
 
-DEFINE_bool(plot, true, "If true, plot");
+ABSL_FLAG(bool, plot, true, "If true, plot");
 
-DEFINE_double(dx, 0.0, "Amount to disturb x at the start");
-DEFINE_double(dy, 0.0, "Amount to disturb y at the start");
-DEFINE_double(dt, 0.0, "Amount to disturb theta at the start");
-DEFINE_double(dvl, 0.0, "Amount to disturb vl at the start");
-DEFINE_double(dvr, 0.0, "Amount to disturb vr at the start");
+ABSL_FLAG(double, dx, 0.0, "Amount to disturb x at the start");
+ABSL_FLAG(double, dy, 0.0, "Amount to disturb y at the start");
+ABSL_FLAG(double, dt, 0.0, "Amount to disturb theta at the start");
+ABSL_FLAG(double, dvl, 0.0, "Amount to disturb vl at the start");
+ABSL_FLAG(double, dvr, 0.0, "Amount to disturb vr at the start");
 
-DEFINE_double(forward, 1.0, "Amount to drive forwards");
+ABSL_FLAG(double, forward, 1.0, "Amount to drive forwards");
 
 namespace chrono = ::std::chrono;
 
@@ -45,12 +46,13 @@
 void Main() {
   const DrivetrainConfig<double> config =
       ::y2019::control_loops::drivetrain::GetDrivetrainConfig();
-  Trajectory trajectory(
-      DistanceSpline(Spline(Spline4To6(
-          (::Eigen::Matrix<double, 2, 4>() << 0.0, 1.2 * FLAGS_forward,
-           -0.2 * FLAGS_forward, FLAGS_forward, 0.0, 0.0, 1.0, 1.0)
-              .finished()))),
-      &config, nullptr);
+  Trajectory trajectory(DistanceSpline(Spline(Spline4To6(
+                            (::Eigen::Matrix<double, 2, 4>() << 0.0,
+                             1.2 * absl::GetFlag(FLAGS_forward),
+                             -0.2 * absl::GetFlag(FLAGS_forward),
+                             absl::GetFlag(FLAGS_forward), 0.0, 0.0, 1.0, 1.0)
+                                .finished()))),
+                        &config, nullptr);
   trajectory.set_lateral_acceleration(2.0);
   trajectory.set_longitudinal_acceleration(1.0);
 
@@ -134,11 +136,11 @@
   FinishedTrajectory finished_trajectory(&config, &trajectory_buffer.message());
 
   ::Eigen::Matrix<double, 5, 1> state = ::Eigen::Matrix<double, 5, 1>::Zero();
-  state(0, 0) = FLAGS_dx;
-  state(1, 0) = FLAGS_dy;
-  state(2, 0) = FLAGS_dt;
-  state(3, 0) = FLAGS_dvl;
-  state(4, 0) = FLAGS_dvr;
+  state(0, 0) = absl::GetFlag(FLAGS_dx);
+  state(1, 0) = absl::GetFlag(FLAGS_dy);
+  state(2, 0) = absl::GetFlag(FLAGS_dt);
+  state(3, 0) = absl::GetFlag(FLAGS_dvl);
+  state(4, 0) = absl::GetFlag(FLAGS_dvr);
   ::std::vector<double> simulation_t = length_plan_t;
   ::std::vector<double> simulation_x;
   ::std::vector<double> error_x;
@@ -190,7 +192,7 @@
     simulation_ur.push_back(U(1));
   }
 
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     matplotlibcpp::figure();
     matplotlibcpp::plot(plan_segment_center_distance, plan_type,
                         {{"label", "plan_type"}});
@@ -230,7 +232,7 @@
 }  // namespace frc971::control_loops::drivetrain
 
 int main(int argc, char **argv) {
-  ::gflags::ParseCommandLineFlags(&argc, &argv, false);
+  aos::InitGoogle(&argc, &argv);
   ::aos::network::OverrideTeamNumber(971);
   ::frc971::control_loops::drivetrain::Main();
   return 0;
diff --git a/frc971/control_loops/drivetrain/trajectory_test.cc b/frc971/control_loops/drivetrain/trajectory_test.cc
index 6e9089a..5ff8b5d 100644
--- a/frc971/control_loops/drivetrain/trajectory_test.cc
+++ b/frc971/control_loops/drivetrain/trajectory_test.cc
@@ -3,7 +3,8 @@
 #include <chrono>
 #include <vector>
 
-#include "gflags/gflags.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/testing/test_shm.h"
@@ -18,10 +19,10 @@
 #include "y2016/control_loops/drivetrain/polydrivetrain_dog_motor_plant.h"
 #include "y2019/control_loops/drivetrain/drivetrain_base.h"
 
-DECLARE_bool(plot);
+ABSL_DECLARE_FLAG(bool, plot);
 
-DEFINE_string(output_file, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_file, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace frc971::control_loops::drivetrain::testing {
 
@@ -119,7 +120,7 @@
            length_plan_xva_.size() *
                ::aos::time::DurationInSeconds(dt_config_.dt));
 #if defined(SUPPORT_PLOT)
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       ::std::vector<double> distances = trajectory_->Distances();
 
       for (size_t i = 0; i < length_plan_xva_.size(); ++i) {
diff --git a/frc971/control_loops/flywheel/flywheel_controller_test.cc b/frc971/control_loops/flywheel/flywheel_controller_test.cc
index eaac6e6..e52dc8e 100644
--- a/frc971/control_loops/flywheel/flywheel_controller_test.cc
+++ b/frc971/control_loops/flywheel/flywheel_controller_test.cc
@@ -1,6 +1,7 @@
 #include "frc971/control_loops/flywheel/flywheel_controller.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
@@ -37,7 +38,8 @@
 
     // Confirm that we aren't drawing too much current.  2 motors -> twice the
     // lumped current since our model can't tell them apart.
-    CHECK_NEAR(flywheel_plant_->battery_current(flywheel_U), 0.0, 200.0);
+    CHECK_LE(flywheel_plant_->battery_current(flywheel_U), 200.0);
+    CHECK_GE(flywheel_plant_->battery_current(flywheel_U), -200.0);
 
     flywheel_plant_->Update(flywheel_U);
 
diff --git a/frc971/control_loops/polytope.h b/frc971/control_loops/polytope.h
index cba25f6..41c98e8 100644
--- a/frc971/control_loops/polytope.h
+++ b/frc971/control_loops/polytope.h
@@ -11,7 +11,8 @@
 #include "third_party/cddlib/lib-src/cdd.h"
 // clang-format on
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #endif  // __linux__
 
 namespace frc971::controls {
diff --git a/frc971/control_loops/quaternion_utils.h b/frc971/control_loops/quaternion_utils.h
index e96f5f1..3e40e3f4 100644
--- a/frc971/control_loops/quaternion_utils.h
+++ b/frc971/control_loops/quaternion_utils.h
@@ -3,7 +3,8 @@
 
 #include "Eigen/Dense"
 #include "Eigen/Geometry"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace frc971::controls {
 
diff --git a/frc971/control_loops/quaternion_utils_test.cc b/frc971/control_loops/quaternion_utils_test.cc
index 4e9e97a..2eaeaa0 100644
--- a/frc971/control_loops/quaternion_utils_test.cc
+++ b/frc971/control_loops/quaternion_utils_test.cc
@@ -3,7 +3,8 @@
 #include <random>
 
 #include "Eigen/Dense"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/testing/random_seed.h"
diff --git a/frc971/control_loops/runge_kutta.h b/frc971/control_loops/runge_kutta.h
index 173014e..7f2b6b6 100644
--- a/frc971/control_loops/runge_kutta.h
+++ b/frc971/control_loops/runge_kutta.h
@@ -1,7 +1,8 @@
 #ifndef FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_
 #define FRC971_CONTROL_LOOPS_RUNGE_KUTTA_H_
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <Eigen/Dense>
 
 #include "frc971/control_loops/runge_kutta_helpers.h"
diff --git a/frc971/control_loops/runge_kutta_helpers.h b/frc971/control_loops/runge_kutta_helpers.h
index f9a4ecf..dde7c70 100644
--- a/frc971/control_loops/runge_kutta_helpers.h
+++ b/frc971/control_loops/runge_kutta_helpers.h
@@ -1,7 +1,8 @@
 #ifndef FRC971_CONTROL_LOOPS_RUNGE_KUTTA_HELPERS_H_
 #define FRC971_CONTROL_LOOPS_RUNGE_KUTTA_HELPERS_H_
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <Eigen/Dense>
 
 namespace frc971::control_loops {
diff --git a/frc971/control_loops/state_feedback_loop.h b/frc971/control_loops/state_feedback_loop.h
index 988aaa9..32f27f8 100644
--- a/frc971/control_loops/state_feedback_loop.h
+++ b/frc971/control_loops/state_feedback_loop.h
@@ -12,7 +12,8 @@
 #include "unsupported/Eigen/MatrixFunctions"
 
 #if defined(__linux__)
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/logging/logging.h"
 #endif
diff --git a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc
index ea24ff3..c17b734 100644
--- a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc
+++ b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc
@@ -1,7 +1,8 @@
 #include "frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
 #include "gtest/gtest.h"
 
 #include "frc971/control_loops/capped_test_plant.h"
diff --git a/frc971/control_loops/swerve/BUILD b/frc971/control_loops/swerve/BUILD
index ed2c604..0efe040 100644
--- a/frc971/control_loops/swerve/BUILD
+++ b/frc971/control_loops/swerve/BUILD
@@ -117,7 +117,8 @@
         ":motors",
         "//aos:init",
         "//aos/util:file",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/strings:str_format",
         "@symengine",
diff --git a/frc971/control_loops/swerve/generate_physics.cc b/frc971/control_loops/swerve/generate_physics.cc
index 8a10f89..ee5850c 100644
--- a/frc971/control_loops/swerve/generate_physics.cc
+++ b/frc971/control_loops/swerve/generate_physics.cc
@@ -12,26 +12,30 @@
 #include <numbers>
 #include <utility>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
 #include "absl/strings/str_replace.h"
 #include "absl/strings/substitute.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/init.h"
 #include "aos/util/file.h"
 #include "frc971/control_loops/swerve/motors.h"
 
-DEFINE_string(output_base, "",
-              "Path to strip off the front of the output paths.");
-DEFINE_string(cc_output_path, "", "Path to write generated cc code to");
-DEFINE_string(h_output_path, "", "Path to write generated header code to");
-DEFINE_string(py_output_path, "", "Path to write generated py code to");
-DEFINE_string(casadi_py_output_path, "",
-              "Path to write casadi generated py code to");
+ABSL_FLAG(std::string, output_base, "",
+          "Path to strip off the front of the output paths.");
+ABSL_FLAG(std::string, cc_output_path, "",
+          "Path to write generated cc code to");
+ABSL_FLAG(std::string, h_output_path, "",
+          "Path to write generated header code to");
+ABSL_FLAG(std::string, py_output_path, "",
+          "Path to write generated py code to");
+ABSL_FLAG(std::string, casadi_py_output_path, "",
+          "Path to write casadi generated py code to");
 
-DEFINE_bool(symbolic, false, "If true, write everything out symbolically.");
+ABSL_FLAG(bool, symbolic, false, "If true, write everything out symbolically.");
 
 using SymEngine::abs;
 using SymEngine::add;
@@ -100,7 +104,7 @@
     auto fy = symbol("fy");
     auto moment = symbol("moment");
 
-    if (FLAGS_symbolic) {
+    if (absl::GetFlag(FLAGS_symbolic)) {
       Cx_ = symbol("Cx");
       Cy_ = symbol("Cy");
 
@@ -335,7 +339,8 @@
     std::vector<std::string> result_h;
 
     std::string_view include_guard_stripped = h_path;
-    CHECK(absl::ConsumePrefix(&include_guard_stripped, FLAGS_output_base));
+    CHECK(absl::ConsumePrefix(&include_guard_stripped,
+                              absl::GetFlag(FLAGS_output_base)));
     std::string include_guard =
         absl::StrReplaceAll(absl::AsciiStrToUpper(include_guard_stripped),
                             {{"/", "_"}, {".", "_"}});
@@ -934,14 +939,16 @@
 
   frc971::control_loops::swerve::SwerveSimulation sim;
 
-  if (!FLAGS_cc_output_path.empty() && !FLAGS_h_output_path.empty()) {
-    sim.Write(FLAGS_cc_output_path, FLAGS_h_output_path);
+  if (!absl::GetFlag(FLAGS_cc_output_path).empty() &&
+      !absl::GetFlag(FLAGS_h_output_path).empty()) {
+    sim.Write(absl::GetFlag(FLAGS_cc_output_path),
+              absl::GetFlag(FLAGS_h_output_path));
   }
-  if (!FLAGS_py_output_path.empty()) {
-    sim.WritePy(FLAGS_py_output_path);
+  if (!absl::GetFlag(FLAGS_py_output_path).empty()) {
+    sim.WritePy(absl::GetFlag(FLAGS_py_output_path));
   }
-  if (!FLAGS_casadi_py_output_path.empty()) {
-    sim.WriteCasadi(FLAGS_casadi_py_output_path);
+  if (!absl::GetFlag(FLAGS_casadi_py_output_path).empty()) {
+    sim.WriteCasadi(absl::GetFlag(FLAGS_casadi_py_output_path));
   }
 
   return 0;
diff --git a/frc971/image_streamer/BUILD b/frc971/image_streamer/BUILD
index dce389a..1eae3de 100644
--- a/frc971/image_streamer/BUILD
+++ b/frc971/image_streamer/BUILD
@@ -42,7 +42,8 @@
         "//third_party:gstreamer",
         "//third_party/seasocks",
         "@com_github_google_flatbuffers//:flatbuffers",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings:str_format",
     ],
 )
diff --git a/frc971/image_streamer/image_streamer.cc b/frc971/image_streamer/image_streamer.cc
index b89adc0..8e0c4d0 100644
--- a/frc971/image_streamer/image_streamer.cc
+++ b/frc971/image_streamer/image_streamer.cc
@@ -14,10 +14,11 @@
 #include <map>
 #include <thread>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
 #include "flatbuffers/flatbuffers.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 
 #include "aos/events/glib_main_loop.h"
 #include "aos/events/shm_event_loop.h"
@@ -30,27 +31,28 @@
 #include "seasocks/StringUtil.h"
 #include "seasocks/WebSocket.h"
 
-DEFINE_string(config, "aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_string(device, "/dev/video0",
-              "Camera fd. Ignored if reading from channel");
-DEFINE_string(data_dir, "image_streamer_www",
-              "Directory to serve data files from");
-DEFINE_bool(publish_images, true,
-            "If true, publish images read from v4l2 to /camera.");
-DEFINE_int32(width, 400, "Image width");
-DEFINE_int32(height, 300, "Image height");
-DEFINE_int32(framerate, 25, "Framerate (FPS)");
-DEFINE_int32(brightness, 50, "Camera brightness");
-DEFINE_int32(exposure, 300, "Manual exposure");
-DEFINE_int32(bitrate, 500000, "H264 encode bitrate");
-DEFINE_int32(streaming_port, 1180, "Port to stream images on with seasocks");
-DEFINE_int32(min_port, 5800, "Min rtp port");
-DEFINE_int32(max_port, 5810, "Max rtp port");
-DEFINE_string(listen_on, "",
-              "Channel on which to receive frames from. Used in place of "
-              "internal V4L2 reader. Note: width and height MUST match the "
-              "expected size of channel images.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(std::string, device, "/dev/video0",
+          "Camera fd. Ignored if reading from channel");
+ABSL_FLAG(std::string, data_dir, "image_streamer_www",
+          "Directory to serve data files from");
+ABSL_FLAG(bool, publish_images, true,
+          "If true, publish images read from v4l2 to /camera.");
+ABSL_FLAG(int32_t, width, 400, "Image width");
+ABSL_FLAG(int32_t, height, 300, "Image height");
+ABSL_FLAG(int32_t, framerate, 25, "Framerate (FPS)");
+ABSL_FLAG(int32_t, brightness, 50, "Camera brightness");
+ABSL_FLAG(int32_t, exposure, 300, "Manual exposure");
+ABSL_FLAG(int32_t, bitrate, 500000, "H264 encode bitrate");
+ABSL_FLAG(int32_t, streaming_port, 1180,
+          "Port to stream images on with seasocks");
+ABSL_FLAG(int32_t, min_port, 5800, "Min rtp port");
+ABSL_FLAG(int32_t, max_port, 5810, "Max rtp port");
+ABSL_FLAG(std::string, listen_on, "",
+          "Channel on which to receive frames from. Used in place of "
+          "internal V4L2 reader. Note: width and height MUST match the "
+          "expected size of channel images.");
 
 class Connection;
 
@@ -87,9 +89,9 @@
     // client since we don't expect more than 1 or 2.
 
     std::string exposure;
-    if (FLAGS_exposure > 0) {
+    if (absl::GetFlag(FLAGS_exposure) > 0) {
       exposure = absl::StrFormat(",auto_exposure=1,exposure_time_absolute=%d",
-                                 FLAGS_exposure);
+                                 absl::GetFlag(FLAGS_exposure));
     }
 
     pipeline_ = gst_parse_launch(
@@ -100,8 +102,10 @@
                         "name=appsink "
                         "emit-signals=true sync=false async=false "
                         "caps=video/x-raw,format=YUY2",
-                        FLAGS_device, FLAGS_brightness, exposure, FLAGS_width,
-                        FLAGS_height, FLAGS_framerate)
+                        absl::GetFlag(FLAGS_device),
+                        absl::GetFlag(FLAGS_brightness), exposure,
+                        absl::GetFlag(FLAGS_width), absl::GetFlag(FLAGS_height),
+                        absl::GetFlag(FLAGS_framerate))
             .c_str(),
         &error);
 
@@ -157,7 +161,7 @@
                 std::function<void(GstSample *)> callback)
       : callback_(std::move(callback)) {
     event_loop->MakeWatcher(
-        FLAGS_listen_on,
+        absl::GetFlag(FLAGS_listen_on),
         [this](const frc971::vision::CameraImage &image) { OnImage(image); });
   }
 
@@ -167,8 +171,8 @@
       VLOG(2) << "Skipping CameraImage with no data";
       return;
     }
-    CHECK_EQ(image.rows(), FLAGS_height);
-    CHECK_EQ(image.cols(), FLAGS_width);
+    CHECK_EQ(image.rows(), absl::GetFlag(FLAGS_height));
+    CHECK_EQ(image.cols(), absl::GetFlag(FLAGS_width));
 
     GBytes *bytes = g_bytes_new(image.data()->data(), image.data()->size());
     GstBuffer *buffer = gst_buffer_new_wrapped_bytes(bytes);
@@ -282,8 +286,8 @@
       server_(server),
       manual_restart_handle_(
           event_loop_->AddTimer([this]() { event_loop_->Exit(); })) {
-  if (FLAGS_listen_on.empty()) {
-    if (FLAGS_publish_images) {
+  if (absl::GetFlag(FLAGS_listen_on).empty()) {
+    if (absl::GetFlag(FLAGS_publish_images)) {
       sender_ = event_loop->MakeSender<frc971::vision::CameraImage>("/camera");
     }
     source_ =
@@ -377,7 +381,8 @@
           "application/"
           "x-rtp,media=video,encoding-name=H264,payload=96,clock-rate=90000 !"
           "webrtcbin. ",
-          FLAGS_width, FLAGS_height, FLAGS_bitrate / 1000)
+          absl::GetFlag(FLAGS_width), absl::GetFlag(FLAGS_height),
+          absl::GetFlag(FLAGS_bitrate) / 1000)
           .c_str(),
       &error);
 
@@ -415,8 +420,8 @@
     g_object_get(G_OBJECT(webrtcbin_), "ice-agent", &ice, nullptr);
     CHECK(ice != nullptr);
 
-    g_object_set(ice, "min-rtp-port", FLAGS_min_port, "max-rtp-port",
-                 FLAGS_max_port, nullptr);
+    g_object_set(ice, "min-rtp-port", absl::GetFlag(FLAGS_min_port),
+                 "max-rtp-port", absl::GetFlag(FLAGS_max_port), nullptr);
 
     // We don't need upnp on a local network.
     {
@@ -628,7 +633,7 @@
   gst_init(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
 
   {
@@ -637,14 +642,14 @@
     seasocks::Server server(::std::shared_ptr<seasocks::Logger>(
         new ::aos::seasocks::SeasocksLogger(seasocks::Logger::Level::Info)));
 
-    LOG(INFO) << "Serving from " << FLAGS_data_dir;
+    LOG(INFO) << "Serving from " << absl::GetFlag(FLAGS_data_dir);
 
     auto websocket_handler =
         std::make_shared<WebsocketHandler>(&event_loop, &server);
     server.addWebSocketHandler("/ws", websocket_handler);
 
-    server.startListening(FLAGS_streaming_port);
-    server.setStaticPath(FLAGS_data_dir.c_str());
+    server.startListening(absl::GetFlag(FLAGS_streaming_port));
+    server.setStaticPath(absl::GetFlag(FLAGS_data_dir).c_str());
 
     aos::internal::EPoll *epoll = event_loop.epoll();
 
diff --git a/frc971/imu/imu_calibrator-tmpl.h b/frc971/imu/imu_calibrator-tmpl.h
index 6743106..49d5c20 100644
--- a/frc971/imu/imu_calibrator-tmpl.h
+++ b/frc971/imu/imu_calibrator-tmpl.h
@@ -1,7 +1,10 @@
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+
 #include "frc971/imu/imu_calibrator.h"
 #include "frc971/math/interpolate.h"
 
-DECLARE_int32(imu_zeroing_buffer);
+ABSL_DECLARE_FLAG(int32_t, imu_zeroing_buffer);
 
 namespace frc971::imu {
 
@@ -26,7 +29,8 @@
   const bool plausibly_stationary =
       reading.gyro.squaredNorm() < kGyroMaxZeroingValue * kGyroMaxZeroingValue;
   bool stationary = plausibly_stationary;
-  int earliest_affected_index = readings.size() - FLAGS_imu_zeroing_buffer;
+  int earliest_affected_index =
+      readings.size() - absl::GetFlag(FLAGS_imu_zeroing_buffer);
   for (size_t index = std::max(0, earliest_affected_index);
        index < readings.size(); ++index) {
     if (!plausibly_stationary) {
@@ -75,7 +79,8 @@
 template <typename Scalar>
 void ImuCalibrator<Scalar>::EvaluateRelativeResiduals() {
   for (const auto &readings : imu_readings_) {
-    CHECK_LT(static_cast<size_t>(FLAGS_imu_zeroing_buffer * 2), readings.size())
+    CHECK_LT(static_cast<size_t>(absl::GetFlag(FLAGS_imu_zeroing_buffer) * 2),
+             readings.size())
         << ": Insufficient readings to perform calibration.";
   }
   Scalar base_clock = imu_readings_[origin_index_][0].capture_time_adjusted;
diff --git a/frc971/imu/imu_calibrator.cc b/frc971/imu/imu_calibrator.cc
index 03fa377..73e16e0 100644
--- a/frc971/imu/imu_calibrator.cc
+++ b/frc971/imu/imu_calibrator.cc
@@ -1,6 +1,6 @@
 #include "frc971/imu/imu_calibrator.h"
 
-DEFINE_int32(
-    imu_zeroing_buffer, 100,
+ABSL_FLAG(
+    int32_t, imu_zeroing_buffer, 100,
     "We will only consider readings stationary for purposes if calibration if "
     "this many readings to either side appear to be stationary.");
diff --git a/frc971/imu/imu_calibrator.h b/frc971/imu/imu_calibrator.h
index 58ff12b..d8b7aab 100644
--- a/frc971/imu/imu_calibrator.h
+++ b/frc971/imu/imu_calibrator.h
@@ -6,10 +6,11 @@
 #include <tuple>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
 #include "ceres/ceres.h"
-#include "glog/logging.h"
 #include <Eigen/Core>
 #include <Eigen/Geometry>
 
diff --git a/frc971/imu/imu_calibrator_test.cc b/frc971/imu/imu_calibrator_test.cc
index a341b2a..2546da4 100644
--- a/frc971/imu/imu_calibrator_test.cc
+++ b/frc971/imu/imu_calibrator_test.cc
@@ -2,6 +2,7 @@
 
 #include <random>
 
+#include "absl/flags/reflection.h"
 #include "gtest/gtest.h"
 
 #include "frc971/imu/imu_calibrator_solver.h"
@@ -140,7 +141,7 @@
 // the IMU inputs; feeding in a sine wave works much better for allowing the
 // solver to estimate the offset.
 TEST(ImuCalibratorTest, TimeOffsetTest) {
-  gflags::FlagSaver flag_saver;
+  absl::FlagSaver flag_saver;
 
   std::vector<ImuConfig<double>> nominal_imus = {
       ImuConfig<double>{true, std::nullopt},
diff --git a/frc971/imu_fdcan/BUILD b/frc971/imu_fdcan/BUILD
index c8a6cd7..51357c6 100644
--- a/frc971/imu_fdcan/BUILD
+++ b/frc971/imu_fdcan/BUILD
@@ -91,7 +91,8 @@
         "//aos/events:simulated_event_loop",
         "//aos/testing:googletest",
         "//frc971/can_logger:can_logging_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -110,7 +111,8 @@
         "//aos/events:simulated_event_loop",
         "//aos/testing:googletest",
         "//frc971/can_logger:can_logging_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/frc971/imu_fdcan/can_translator_lib_test.cc b/frc971/imu_fdcan/can_translator_lib_test.cc
index fcef6a4..b62bba6 100644
--- a/frc971/imu_fdcan/can_translator_lib_test.cc
+++ b/frc971/imu_fdcan/can_translator_lib_test.cc
@@ -1,6 +1,7 @@
 #include "frc971/imu_fdcan/can_translator_lib.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
diff --git a/frc971/imu_fdcan/can_translator_main.cc b/frc971/imu_fdcan/can_translator_main.cc
index fdb7107..402448e 100644
--- a/frc971/imu_fdcan/can_translator_main.cc
+++ b/frc971/imu_fdcan/can_translator_main.cc
@@ -1,8 +1,10 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/imu_fdcan/can_translator_lib.h"
 
-DEFINE_string(channel, "/can", "The CAN channel to use");
+ABSL_FLAG(std::string, channel, "/can", "The CAN channel to use");
 
 using frc971::imu_fdcan::CANTranslator;
 
@@ -14,7 +16,7 @@
 
   ::aos::ShmEventLoop event_loop(&config.message());
 
-  CANTranslator translator(&event_loop, FLAGS_channel);
+  CANTranslator translator(&event_loop, absl::GetFlag(FLAGS_channel));
 
   event_loop.Run();
 
diff --git a/frc971/imu_fdcan/dual_imu_blender_lib.cc b/frc971/imu_fdcan/dual_imu_blender_lib.cc
index d390102..3b746fc 100644
--- a/frc971/imu_fdcan/dual_imu_blender_lib.cc
+++ b/frc971/imu_fdcan/dual_imu_blender_lib.cc
@@ -1,9 +1,9 @@
 #include "frc971/imu_fdcan/dual_imu_blender_lib.h"
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
-DEFINE_bool(murata_only, false,
-            "If true then only use the murata value and ignore the tdk.");
+ABSL_FLAG(bool, murata_only, false,
+          "If true then only use the murata value and ignore the tdk.");
 
 // Saturation for the gyro is measured in +- radians/s
 static constexpr double kMurataGyroSaturation = (300.0 * M_PI) / 180;
@@ -124,7 +124,7 @@
     imu_values->set_accelerometer_z(dual_imu->murata()->accelerometer_z());
   }
 
-  if (FLAGS_murata_only) {
+  if (absl::GetFlag(FLAGS_murata_only)) {
     imu_values->set_gyro_x(dual_imu->murata()->gyro_x());
     imu_values->set_gyro_y(dual_imu->murata()->gyro_y());
     imu_values->set_gyro_z(dual_imu->murata()->gyro_z());
diff --git a/frc971/imu_fdcan/dual_imu_blender_lib_test.cc b/frc971/imu_fdcan/dual_imu_blender_lib_test.cc
index 59c7e81..f830c4f 100644
--- a/frc971/imu_fdcan/dual_imu_blender_lib_test.cc
+++ b/frc971/imu_fdcan/dual_imu_blender_lib_test.cc
@@ -1,6 +1,7 @@
 #include "frc971/imu_fdcan/dual_imu_blender_lib.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
diff --git a/frc971/imu_reader/BUILD b/frc971/imu_reader/BUILD
index 809a3fc..d204c56 100644
--- a/frc971/imu_reader/BUILD
+++ b/frc971/imu_reader/BUILD
@@ -17,7 +17,8 @@
         "//aos/util:crc32",
         "//frc971/wpilib:imu_batch_fbs",
         "//frc971/wpilib:imu_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
diff --git a/frc971/imu_reader/imu.cc b/frc971/imu_reader/imu.cc
index acdd6d9..1a74adf 100644
--- a/frc971/imu_reader/imu.cc
+++ b/frc971/imu_reader/imu.cc
@@ -1,6 +1,7 @@
 #include "frc971/imu_reader/imu.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/util/crc32.h"
 
diff --git a/frc971/input/BUILD b/frc971/input/BUILD
index 9e5fd9c..c992932 100644
--- a/frc971/input/BUILD
+++ b/frc971/input/BUILD
@@ -53,7 +53,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         ":joystick_state_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/frc971/input/driver_station_data.cc b/frc971/input/driver_station_data.cc
index 06d2d69..34e8a86 100644
--- a/frc971/input/driver_station_data.cc
+++ b/frc971/input/driver_station_data.cc
@@ -1,6 +1,7 @@
 #include "frc971/input/driver_station_data.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace frc971::input::driver_station {
 
diff --git a/frc971/math/BUILD b/frc971/math/BUILD
index b8cd2fc..b4ce504 100644
--- a/frc971/math/BUILD
+++ b/frc971/math/BUILD
@@ -22,8 +22,9 @@
     deps = [
         ":matrix_fbs",
         "//aos:json_to_flatbuffer",
-        "@com_github_google_glog//:glog",
         "@com_github_tartanllama_expected",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
diff --git a/frc971/math/flatbuffers_matrix.h b/frc971/math/flatbuffers_matrix.h
index cfca897..356b4ec 100644
--- a/frc971/math/flatbuffers_matrix.h
+++ b/frc971/math/flatbuffers_matrix.h
@@ -3,7 +3,8 @@
 // This library provides utilities for converting between a frc971.fbs.Matrix
 // flatbuffer type and an Eigen::Matrix.
 // The interesting methods are ToEigen(), ToEigenOrDie(), and FromEigen().
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "tl/expected.hpp"
 #include <Eigen/Core>
 
diff --git a/frc971/orin/BUILD b/frc971/orin/BUILD
index 250ebef..a95bd84 100644
--- a/frc971/orin/BUILD
+++ b/frc971/orin/BUILD
@@ -52,8 +52,10 @@
         "//aos/time",
         "//third_party:cudart",
         "//third_party/apriltag",
-        "@com_github_google_glog//:glog",
         "@com_github_nvidia_cccl//:cccl",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -210,7 +212,8 @@
         "//aos/events/logging:log_writer",
         "//aos/events/logging:snappy_encoder",
         "//aos/logging:log_namer",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/frc971/orin/apriltag.cc b/frc971/orin/apriltag.cc
index 92513c2..3aa0c1b 100644
--- a/frc971/orin/apriltag.cc
+++ b/frc971/orin/apriltag.cc
@@ -14,7 +14,8 @@
 #include <cub/iterator/transform_input_iterator.cuh>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "third_party/apriltag/common/g2d.h"
 
 #include "aos/time/time.h"
diff --git a/frc971/orin/apriltag_detect.cc b/frc971/orin/apriltag_detect.cc
index 26de7fa..9420ef0 100644
--- a/frc971/orin/apriltag_detect.cc
+++ b/frc971/orin/apriltag_detect.cc
@@ -12,14 +12,16 @@
 #include <cub/iterator/transform_input_iterator.cuh>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 #include "frc971/orin/apriltag.h"
 #include "frc971/orin/labeling_allegretti_2019_BKE.h"
 #include "frc971/orin/threshold.h"
 
-DEFINE_int32(debug_blob_index, 4096, "Blob to print out for");
+ABSL_FLAG(int32_t, debug_blob_index, 4096, "Blob to print out for");
 
 constexpr int kUndistortIterationThreshold = 100;
 constexpr double kUndistortConvergenceEpsilon = 1e-6;
@@ -101,7 +103,7 @@
   quad_corners_host_.resize(0);
   VLOG(1) << "Considering " << fit_quads_host_.size();
   for (const FitQuad &quad : fit_quads_host_) {
-    bool print = quad.blob_index == FLAGS_debug_blob_index;
+    bool print = quad.blob_index == absl::GetFlag(FLAGS_debug_blob_index);
     if (!quad.valid) {
       continue;
     }
diff --git a/frc971/orin/argus_camera.cc b/frc971/orin/argus_camera.cc
index c7825ae..e970754 100644
--- a/frc971/orin/argus_camera.cc
+++ b/frc971/orin/argus_camera.cc
@@ -4,7 +4,9 @@
 #include <filesystem>
 #include <thread>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "Argus/Argus.h"
 #include "Argus/EGLStream.h"
@@ -25,21 +27,22 @@
 #include "frc971/vision/vision_generated.h"
 #include "nvbufsurface.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
-DEFINE_int32(colorformat, NVBUF_COLOR_FORMAT_NV16,
-             "Mode to use.  Don't change unless you know what you are doing.");
-DEFINE_int32(camera, 0, "Camera number");
-DEFINE_int32(mode, 0, "Mode number to use.");
-DEFINE_int32(exposure, 100, "Exposure number to use.");
-DEFINE_int32(gain, 5, "gain number to use.");
-DEFINE_int32(width, 1456, "Image width");
-DEFINE_int32(height, 1088, "Image height");
-DEFINE_double(rgain, 1.0, "R gain");
-DEFINE_double(g1gain, 1.0, "G gain");
-DEFINE_double(g2gain, 1.0, "G gain");
-DEFINE_double(bgain, 1.0, "B gain");
-DEFINE_string(channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(int32_t, colorformat, NVBUF_COLOR_FORMAT_NV16,
+          "Mode to use.  Don't change unless you know what you are doing.");
+ABSL_FLAG(int32_t, camera, 0, "Camera number");
+ABSL_FLAG(int32_t, mode, 0, "Mode number to use.");
+ABSL_FLAG(int32_t, exposure, 100, "Exposure number to use.");
+ABSL_FLAG(int32_t, gain, 5, "gain number to use.");
+ABSL_FLAG(int32_t, width, 1456, "Image width");
+ABSL_FLAG(int32_t, height, 1088, "Image height");
+ABSL_FLAG(double, rgain, 1.0, "R gain");
+ABSL_FLAG(double, g1gain, 1.0, "G gain");
+ABSL_FLAG(double, g2gain, 1.0, "G gain");
+ABSL_FLAG(double, bgain, 1.0, "B gain");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
 
 namespace frc971 {
 
@@ -221,7 +224,8 @@
     CHECK_GT(sensor_modes.size(), 0u);
 
     Argus::ISensorMode *i_sensor_mode =
-        Argus::interface_cast<Argus::ISensorMode>(sensor_modes[FLAGS_mode]);
+        Argus::interface_cast<Argus::ISensorMode>(
+            sensor_modes[absl::GetFlag(FLAGS_mode)]);
     CHECK(i_sensor_mode);
 
     {
@@ -264,10 +268,11 @@
 
     // Build the DmaBuffers
     for (size_t i = 0; i < native_buffers_.size(); ++i) {
-      native_buffers_[i] = DmaBuffer::Create(
-          i_sensor_mode->getResolution(),
-          static_cast<NvBufSurfaceColorFormat>(FLAGS_colorformat),
-          NVBUF_LAYOUT_PITCH);
+      native_buffers_[i] =
+          DmaBuffer::Create(i_sensor_mode->getResolution(),
+                            static_cast<NvBufSurfaceColorFormat>(
+                                absl::GetFlag(FLAGS_colorformat)),
+                            NVBUF_LAYOUT_PITCH);
     }
 
     // Create EGLImages from the native buffers
@@ -350,18 +355,19 @@
 
     i_source_settings->setFrameDurationRange(
         i_sensor_mode->getFrameDurationRange().min());
-    CHECK_EQ(i_source_settings->setSensorMode(sensor_modes[FLAGS_mode]),
+    CHECK_EQ(i_source_settings->setSensorMode(
+                 sensor_modes[absl::GetFlag(FLAGS_mode)]),
              Argus::STATUS_OK);
 
     Argus::Range<float> sensor_mode_analog_gain_range;
-    sensor_mode_analog_gain_range.min() = FLAGS_gain;
-    sensor_mode_analog_gain_range.max() = FLAGS_gain;
+    sensor_mode_analog_gain_range.min() = absl::GetFlag(FLAGS_gain);
+    sensor_mode_analog_gain_range.max() = absl::GetFlag(FLAGS_gain);
     CHECK_EQ(i_source_settings->setGainRange(sensor_mode_analog_gain_range),
              Argus::STATUS_OK);
 
     Argus::Range<uint64_t> limit_exposure_time_range;
-    limit_exposure_time_range.min() = FLAGS_exposure * 1000;
-    limit_exposure_time_range.max() = FLAGS_exposure * 1000;
+    limit_exposure_time_range.min() = absl::GetFlag(FLAGS_exposure) * 1000;
+    limit_exposure_time_range.max() = absl::GetFlag(FLAGS_exposure) * 1000;
     CHECK_EQ(i_source_settings->setExposureTimeRange(limit_exposure_time_range),
              Argus::STATUS_OK);
 
@@ -412,9 +418,9 @@
                 << nvbuf_surf_->surfaceList->planeParams.bytesPerPix[i];
       }
       CHECK_EQ(nvbuf_surf_->surfaceList->planeParams.width[0],
-               static_cast<size_t>(FLAGS_width));
+               static_cast<size_t>(absl::GetFlag(FLAGS_width)));
       CHECK_EQ(nvbuf_surf_->surfaceList->planeParams.height[0],
-               static_cast<size_t>(FLAGS_height));
+               static_cast<size_t>(absl::GetFlag(FLAGS_height)));
     }
     MappedBuffer(const MappedBuffer &other) = delete;
     MappedBuffer &operator=(const MappedBuffer &other) = delete;
@@ -524,10 +530,11 @@
 };
 
 int Main() {
-  std::this_thread::sleep_for(std::chrono::seconds(FLAGS_camera + 1));
+  std::this_thread::sleep_for(
+      std::chrono::seconds(absl::GetFlag(FLAGS_camera) + 1));
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
@@ -535,7 +542,8 @@
   event_loop.SetRuntimeAffinity(aos::MakeCpusetFromCpus({2, 3, 4}));
 
   aos::Sender<frc971::vision::CameraImage> sender =
-      event_loop.MakeSender<frc971::vision::CameraImage>(FLAGS_channel);
+      event_loop.MakeSender<frc971::vision::CameraImage>(
+          absl::GetFlag(FLAGS_channel));
 
   LOG(INFO) << "Started";
   // Initialize the Argus camera provider.
@@ -565,7 +573,8 @@
   }
 
   {
-    ArgusCamera camera(i_camera_provider, camera_devices[FLAGS_camera]);
+    ArgusCamera camera(i_camera_provider,
+                       camera_devices[absl::GetFlag(FLAGS_camera)]);
 
     aos::monotonic_clock::time_point last_time = aos::monotonic_clock::epoch();
 
@@ -586,18 +595,20 @@
             sender.MakeBuilder();
 
         uint8_t *data_pointer = nullptr;
-        builder.fbb()->StartIndeterminateVector(FLAGS_width * FLAGS_height * 2,
-                                                1, 64, &data_pointer);
+        builder.fbb()->StartIndeterminateVector(
+            absl::GetFlag(FLAGS_width) * absl::GetFlag(FLAGS_height) * 2, 1, 64,
+            &data_pointer);
 
         YCbCr422(buffer.nvbuf_surf(), data_pointer);
         flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data_offset =
             builder.fbb()->EndIndeterminateVector(
-                FLAGS_width * FLAGS_height * 2, 1);
+                absl::GetFlag(FLAGS_width) * absl::GetFlag(FLAGS_height) * 2,
+                1);
 
         auto image_builder = builder.MakeBuilder<frc971::vision::CameraImage>();
         image_builder.add_data(data_offset);
-        image_builder.add_rows(FLAGS_height);
-        image_builder.add_cols(FLAGS_width);
+        image_builder.add_rows(absl::GetFlag(FLAGS_height));
+        image_builder.add_cols(absl::GetFlag(FLAGS_width));
         {
           aos::ScopedNotRealtime nrt;
           image_builder.add_monotonic_timestamp_ns(
diff --git a/frc971/orin/argus_monitor.cc b/frc971/orin/argus_monitor.cc
index 13130cc..c145c87 100644
--- a/frc971/orin/argus_monitor.cc
+++ b/frc971/orin/argus_monitor.cc
@@ -2,7 +2,7 @@
 
 #include <iostream>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/aos_cli_utils.h"
 #include "aos/configuration.h"
@@ -10,13 +10,13 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/realtime.h"
 
-DEFINE_int32(priority, -1, "If set, the RT priority to run at.");
-DEFINE_double(max_jitter, 10.00,
-              "The max time in seconds between messages before considering the "
-              "camera processes dead.");
-DEFINE_double(grace_period, 10.00,
-              "The grace period at startup before enforcing that messages must "
-              "flow from the camera processes.");
+ABSL_FLAG(int32_t, priority, -1, "If set, the RT priority to run at.");
+ABSL_FLAG(double, max_jitter, 10.00,
+          "The max time in seconds between messages before considering the "
+          "camera processes dead.");
+ABSL_FLAG(double, grace_period, 10.00,
+          "The grace period at startup before enforcing that messages must "
+          "flow from the camera processes.");
 
 namespace aos {
 
@@ -38,7 +38,8 @@
       timer_handle_->Schedule(
           event_loop->monotonic_now() +
               std::chrono::duration_cast<std::chrono::nanoseconds>(
-                  std::chrono::duration<double>(FLAGS_grace_period)),
+                  std::chrono::duration<double>(
+                      absl::GetFlag(FLAGS_grace_period))),
           std::chrono::milliseconds(1000));
     });
   }
@@ -52,12 +53,13 @@
 
   void RunHealthCheck(aos::EventLoop *event_loop) {
     if (last_time_ + std::chrono::duration_cast<std::chrono::nanoseconds>(
-                         std::chrono::duration<double>(FLAGS_max_jitter)) <
+                         std::chrono::duration<double>(
+                             absl::GetFlag(FLAGS_max_jitter))) <
         event_loop->monotonic_now()) {
       // Restart camera services
       LOG(INFO) << "Restarting camera services";
       LOG(INFO) << "Channel " << channel_name_ << " has not received a message "
-                << FLAGS_max_jitter << " seconds";
+                << absl::GetFlag(FLAGS_max_jitter) << " seconds";
       CHECK_EQ(std::system("aos_starter stop argus_camera0"), 0);
       CHECK_EQ(std::system("aos_starter stop argus_camera1"), 0);
       CHECK_EQ(std::system("sudo systemctl restart nvargus-daemon.service"), 0);
@@ -102,8 +104,9 @@
         std::make_unique<aos::State>(&(cli_info.event_loop.value()), channel));
   }
 
-  if (FLAGS_priority > 0) {
-    cli_info.event_loop->SetRuntimeRealtimePriority(FLAGS_priority);
+  if (absl::GetFlag(FLAGS_priority) > 0) {
+    cli_info.event_loop->SetRuntimeRealtimePriority(
+        absl::GetFlag(FLAGS_priority));
   }
 
   cli_info.event_loop->Run();
diff --git a/frc971/orin/cuda.cc b/frc971/orin/cuda.cc
index 6bcc79c..cd68a6c 100644
--- a/frc971/orin/cuda.cc
+++ b/frc971/orin/cuda.cc
@@ -1,10 +1,10 @@
 #include "frc971/orin/cuda.h"
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
 
-DEFINE_bool(
-    sync, false,
+ABSL_FLAG(
+    bool, sync, false,
     "If true, force synchronization after each step to isolate errors better.");
 
 namespace frc971::apriltag {
@@ -17,11 +17,11 @@
 }
 
 void MaybeCheckAndSynchronize() {
-  if (FLAGS_sync) CheckAndSynchronize();
+  if (absl::GetFlag(FLAGS_sync)) CheckAndSynchronize();
 }
 
 void MaybeCheckAndSynchronize(std::string_view message) {
-  if (FLAGS_sync) CheckAndSynchronize(message);
+  if (absl::GetFlag(FLAGS_sync)) CheckAndSynchronize(message);
 }
 
 }  // namespace frc971::apriltag
diff --git a/frc971/orin/cuda.h b/frc971/orin/cuda.h
index 0e44fb4..293fc84 100644
--- a/frc971/orin/cuda.h
+++ b/frc971/orin/cuda.h
@@ -4,7 +4,8 @@
 #include <chrono>
 #include <span>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "cuda_runtime.h"
 #include "device_launch_parameters.h"
diff --git a/frc971/orin/cuda_april_tag_test.cc b/frc971/orin/cuda_april_tag_test.cc
index 638bf6a..c3cd160 100644
--- a/frc971/orin/cuda_april_tag_test.cc
+++ b/frc971/orin/cuda_april_tag_test.cc
@@ -2,7 +2,10 @@
 #include <random>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 #include "opencv2/imgproc.hpp"
 #include "third_party/apriltag/apriltag.h"
@@ -20,14 +23,14 @@
 #include "frc971/orin/apriltag.h"
 #include "frc971/vision/vision_generated.h"
 
-DEFINE_int32(pixel_border, 10,
-             "Size of image border within which to reject detected corners");
-DEFINE_double(min_decision_margin, 50.0,
-              "Minimum decision margin (confidence) for an apriltag detection");
+ABSL_FLAG(int32_t, pixel_border, 10,
+          "Size of image border within which to reject detected corners");
+ABSL_FLAG(double, min_decision_margin, 50.0,
+          "Minimum decision margin (confidence) for an apriltag detection");
 
-DEFINE_bool(debug, false, "If true, write debug images.");
+ABSL_FLAG(bool, debug, false, "If true, write debug images.");
 
-DECLARE_int32(debug_blob_index);
+ABSL_DECLARE_FLAG(int32_t, debug_blob_index);
 
 // Get access to the intermediates of aprilrobotics.
 extern "C" {
@@ -240,7 +243,7 @@
   tag_detector->nthreads = 6;
   tag_detector->wp = workerpool_create(tag_detector->nthreads);
   tag_detector->qtp.min_white_black_diff = 5;
-  tag_detector->debug = FLAGS_debug;
+  tag_detector->debug = absl::GetFlag(FLAGS_debug);
 
   return tag_detector;
 }
@@ -386,7 +389,7 @@
       apriltag_detection_t *det;
       zarray_get(aprilrobotics_detections_, i, &det);
 
-      if (det->decision_margin > FLAGS_min_decision_margin) {
+      if (det->decision_margin > absl::GetFlag(FLAGS_min_decision_margin)) {
         LOG(INFO) << "Found tag number " << det->id
                   << " hamming: " << det->hamming
                   << " margin: " << det->decision_margin;
@@ -1313,7 +1316,8 @@
       VLOG(1) << "Inspecting blob of size " << group.size() << " global start "
               << accumulated_size;
       for (size_t i = 0; i < group.size(); i++) {
-        if (group[i].blob_index() == (size_t)FLAGS_debug_blob_index) {
+        if (group[i].blob_index() ==
+            (size_t)absl::GetFlag(FLAGS_debug_blob_index)) {
           LOG(INFO) << "For idx " << i << " global " << accumulated_size + i
                     << "(" << group[i].x() << ", " << group[i].y()
                     << "), cuda: " << line_fit_points_cuda[accumulated_size + i]
@@ -1339,7 +1343,8 @@
       }
 
       for (size_t i = 0; i < group.size(); i++) {
-        if (group[i].blob_index() == (size_t)FLAGS_debug_blob_index) {
+        if (group[i].blob_index() ==
+            (size_t)absl::GetFlag(FLAGS_debug_blob_index)) {
           LOG(INFO) << "  Cuda error[" << i << "] -> "
                     << errors_device[accumulated_size + i] << ", filtered "
                     << filtered_errors_device[i + accumulated_size];
@@ -1508,8 +1513,10 @@
             << before_cuda << " vs " << us_cuda << " vs " << after_cuda;
         CHECK_EQ(peaks_device[accumulated_size + i].filtered_point_index,
                  accumulated_size + i);
-        CHECK_NEAR(peaks_device[accumulated_size + i].error,
-                   -filtered_errors_device[accumulated_size + i], 1e-3);
+        CHECK_LE(peaks_device[accumulated_size + i].error,
+                 -filtered_errors_device[accumulated_size + i] + 1e-3);
+        CHECK_GE(peaks_device[accumulated_size + i].error,
+                 -filtered_errors_device[accumulated_size + i] - 1e-3);
         if (is_peak_cuda) {
           CHECK_EQ(peaks_device[accumulated_size + i].blob_index,
                    group[0].blob_index())
@@ -1683,7 +1690,7 @@
       zarray_t *cluster;
       zarray_get(clusters, i, &cluster);
 
-      if (i == FLAGS_debug_blob_index) {
+      if (i == absl::GetFlag(FLAGS_debug_blob_index)) {
         LOG(INFO) << "cuda points for blob " << i << " are";
         for (size_t j = 0; j < sorted_blobs[i].size(); ++j) {
           LOG(INFO) << "  blob[" << j << "]: (" << sorted_blobs[i][j].x()
@@ -1715,10 +1722,15 @@
       QuadCorners cuda_corner = *quad_iterator;
 
       for (size_t point = 0; point < 4; ++point) {
-        CHECK_NEAR(quad_result.p[point][0], cuda_corner.corners[point][0],
-                   1e-3);
-        CHECK_NEAR(quad_result.p[point][1], cuda_corner.corners[point][1],
-                   1e-3);
+        constexpr double kEpsilon = 1e-3;
+        CHECK_LE(quad_result.p[point][0],
+                 cuda_corner.corners[point][0] + kEpsilon);
+        CHECK_GE(quad_result.p[point][0],
+                 cuda_corner.corners[point][0] - kEpsilon);
+        CHECK_LE(quad_result.p[point][1],
+                 cuda_corner.corners[point][1] + kEpsilon);
+        CHECK_GE(quad_result.p[point][1],
+                 cuda_corner.corners[point][1] - kEpsilon);
       }
     }
   }
@@ -1755,7 +1767,8 @@
       zarray_get(aprilrobotics_detections, i, &aprilrobotics_detection);
       zarray_get(gpu_detections, i, &gpu_detection);
 
-      bool valid = gpu_detection->decision_margin > FLAGS_min_decision_margin;
+      bool valid = gpu_detection->decision_margin >
+                   absl::GetFlag(FLAGS_min_decision_margin);
 
       LOG(INFO) << "Found GPU " << (valid ? "valid" : "invalid")
                 << " tag number " << gpu_detection->id
@@ -1774,8 +1787,8 @@
       zarray_get(aprilrobotics_detections, i, &aprilrobotics_detection);
       zarray_get(gpu_detections, i, &gpu_detection);
 
-      const bool valid =
-          gpu_detection->decision_margin > FLAGS_min_decision_margin;
+      const bool valid = gpu_detection->decision_margin >
+                         absl::GetFlag(FLAGS_min_decision_margin);
 
       // TODO(austin): Crank down the thresholds and figure out why these
       // deviate.  It should be the same function for both at this point.
@@ -2151,7 +2164,7 @@
     cuda_detector.DetectCPU(color_image.clone());
   }
   cuda_detector.Check(color_image.clone());
-  if (FLAGS_debug) {
+  if (absl::GetFlag(FLAGS_debug)) {
     cuda_detector.WriteDebug(color_image);
   }
 }
@@ -2175,7 +2188,7 @@
   cuda_detector.DetectGPU(color_image.clone());
   cuda_detector.DetectCPU(color_image.clone());
   cuda_detector.Check(color_image.clone());
-  if (FLAGS_debug) {
+  if (absl::GetFlag(FLAGS_debug)) {
     cuda_detector.WriteDebug(color_image);
   }
 }
@@ -2289,7 +2302,7 @@
   cuda_detector.DetectGPU(color_image.clone());
   cuda_detector.DetectCPU(color_image.clone());
   cuda_detector.Check(color_image.clone());
-  if (FLAGS_debug) {
+  if (absl::GetFlag(FLAGS_debug)) {
     cuda_detector.WriteDebug(color_image);
   }
 }
@@ -2314,7 +2327,7 @@
   cuda_detector.DetectGPU(color_image.clone());
   cuda_detector.DetectCPU(color_image.clone());
   cuda_detector.Check(color_image.clone());
-  if (FLAGS_debug) {
+  if (absl::GetFlag(FLAGS_debug)) {
     cuda_detector.WriteDebug(color_image);
   }
 }
diff --git a/frc971/orin/gpu_apriltag.cc b/frc971/orin/gpu_apriltag.cc
index 425e45f..83ae3ee 100644
--- a/frc971/orin/gpu_apriltag.cc
+++ b/frc971/orin/gpu_apriltag.cc
@@ -2,6 +2,7 @@
 
 #include <chrono>
 
+#include "absl/flags/flag.h"
 #include "third_party/apriltag/apriltag.h"
 #include "third_party/apriltag/apriltag_pose.h"
 #include "third_party/apriltag/tag16h5.h"
@@ -18,18 +19,18 @@
 #include "frc971/vision/charuco_lib.h"
 #include "frc971/vision/vision_util_lib.h"
 
-DEFINE_bool(debug, false, "If true, write debug images.");
-DEFINE_double(
-    max_expected_distortion, 0.314,
+ABSL_FLAG(bool, debug, false, "If true, write debug images.");
+ABSL_FLAG(
+    double, max_expected_distortion, 0.314,
     "Maximum expected value for unscaled distortion factors. Will scale "
     "distortion factors so that this value (and a higher distortion) maps to "
     "1.0.");
-DEFINE_double(min_decision_margin, 50.0,
-              "Minimum decision margin (confidence) for an apriltag detection");
-DEFINE_int32(pixel_border, 150,
-             "Size of image border within which to reject detected corners");
-DEFINE_uint64(pose_estimation_iterations, 50,
-              "Number of iterations for apriltag pose estimation.");
+ABSL_FLAG(double, min_decision_margin, 50.0,
+          "Minimum decision margin (confidence) for an apriltag detection");
+ABSL_FLAG(int32_t, pixel_border, 150,
+          "Size of image border within which to reject detected corners");
+ABSL_FLAG(uint64_t, pose_estimation_iterations, 50,
+          "Number of iterations for apriltag pose estimation.");
 
 namespace frc971::apriltag {
 
@@ -111,7 +112,7 @@
   tag_detector->nthreads = 6;
   tag_detector->wp = workerpool_create(tag_detector->nthreads);
   tag_detector->qtp.min_white_black_diff = 5;
-  tag_detector->debug = FLAGS_debug;
+  tag_detector->debug = absl::GetFlag(FLAGS_debug);
 
   return tag_detector;
 }
@@ -169,7 +170,8 @@
   double distortion_factor =
       avg_distance /
       cv::norm(cv::Point2d(image_size_.width, image_size_.height));
-  return std::min(distortion_factor / FLAGS_max_expected_distortion, 1.0);
+  return std::min(
+      distortion_factor / absl::GetFlag(FLAGS_max_expected_distortion), 1.0);
 }
 
 std::vector<cv::Point2f> ApriltagDetector::MakeCornerVector(
@@ -195,7 +197,7 @@
   gpu_detector_.Detect(color_image.data);
   image_size_ = color_image.size();
   cv::Mat image_copy;
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     // TODO: Need to figure out how to extract displayable color image from this
     image_copy = color_image.clone();
   }
@@ -204,10 +206,10 @@
 
   aos::monotonic_clock::time_point end_time = aos::monotonic_clock::now();
 
-  const uint32_t min_x = FLAGS_pixel_border;
-  const uint32_t max_x = color_image.cols - FLAGS_pixel_border;
-  const uint32_t min_y = FLAGS_pixel_border;
-  const uint32_t max_y = color_image.rows - FLAGS_pixel_border;
+  const uint32_t min_x = absl::GetFlag(FLAGS_pixel_border);
+  const uint32_t max_x = color_image.cols - absl::GetFlag(FLAGS_pixel_border);
+  const uint32_t min_y = absl::GetFlag(FLAGS_pixel_border);
+  const uint32_t max_y = color_image.rows - absl::GetFlag(FLAGS_pixel_border);
 
   // Define variables for storing / visualizing the output
   std::vector<Detection> results;
@@ -219,7 +221,8 @@
 
     zarray_get(detections, i, &gpu_detection);
 
-    bool valid = gpu_detection->decision_margin > FLAGS_min_decision_margin;
+    bool valid = gpu_detection->decision_margin >
+                 absl::GetFlag(FLAGS_min_decision_margin);
 
     if (valid) {
       // Reject tags that are too close to the boundary, since they often
@@ -303,9 +306,9 @@
       apriltag_pose_t pose_2;
       double pose_error_1;
       double pose_error_2;
-      estimate_tag_pose_orthogonal_iteration(&info, &pose_error_1, &pose_1,
-                                             &pose_error_2, &pose_2,
-                                             FLAGS_pose_estimation_iterations);
+      estimate_tag_pose_orthogonal_iteration(
+          &info, &pose_error_1, &pose_1, &pose_error_2, &pose_2,
+          absl::GetFlag(FLAGS_pose_estimation_iterations));
 
       const aos::monotonic_clock::time_point after_pose_estimation =
           aos::monotonic_clock::now();
@@ -351,7 +354,7 @@
                                      .distortion_factor = distortion_factor,
                                      .pose_error_ratio = pose_error_ratio});
 
-      if (FLAGS_visualize) {
+      if (absl::GetFlag(FLAGS_visualize)) {
         // Draw raw (distorted) corner points in green
         cv::line(image_copy, orig_corner_points[0], orig_corner_points[1],
                  cv::Scalar(0, 255, 0), 2);
@@ -381,7 +384,7 @@
     }
   }
 
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     // Display the result
     // Rotate by 180 degrees to make it upright
     // TODO: Make this an option?
@@ -422,7 +425,7 @@
 
   end_time = aos::monotonic_clock::now();
 
-  if (FLAGS_debug) {
+  if (absl::GetFlag(FLAGS_debug)) {
     timeprofile_display(tag_detector_->tp);
   }
 
diff --git a/frc971/orin/hardware_monitor.cc b/frc971/orin/hardware_monitor.cc
index e1c785b..cc019fd 100644
--- a/frc971/orin/hardware_monitor.cc
+++ b/frc971/orin/hardware_monitor.cc
@@ -1,16 +1,17 @@
 #include <dirent.h>
 #include <sys/statvfs.h>
 
+#include "absl/flags/flag.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_format.h"
-#include "gflags/gflags.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/orin/hardware_stats_generated.h"
 
-DEFINE_string(config, "aos_config.json", "File path of aos configuration");
-DEFINE_bool(log_voltages, false, "If true, log voltages too.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "File path of aos configuration");
+ABSL_FLAG(bool, log_voltages, false, "If true, log voltages too.");
 
 namespace frc971::orin {
 namespace {
@@ -102,7 +103,7 @@
     flatbuffers::Offset<
         flatbuffers::Vector<flatbuffers::Offset<ElectricalReading>>>
         electrical_readings_offset;
-    if (FLAGS_log_voltages) {
+    if (absl::GetFlag(FLAGS_log_voltages)) {
       std::vector<flatbuffers::Offset<ElectricalReading>> electrical_readings;
       // Iterate through INA3221 electrical reading channels
       for (int channel = 1; channel <= 3; channel++) {
@@ -182,7 +183,7 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop shm_event_loop(&config.message());
 
diff --git a/frc971/orin/labeling_allegretti_2019_BKE.cc b/frc971/orin/labeling_allegretti_2019_BKE.cc
index 2806199..0ec1664 100644
--- a/frc971/orin/labeling_allegretti_2019_BKE.cc
+++ b/frc971/orin/labeling_allegretti_2019_BKE.cc
@@ -19,7 +19,8 @@
 
 #include "frc971/orin/labeling_allegretti_2019_BKE.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "cuda_runtime.h"
 #include "device_launch_parameters.h"
diff --git a/frc971/orin/localizer_logger.cc b/frc971/orin/localizer_logger.cc
index ec8d3ac..c571bd7 100644
--- a/frc971/orin/localizer_logger.cc
+++ b/frc971/orin/localizer_logger.cc
@@ -1,8 +1,10 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_writer.h"
@@ -11,15 +13,15 @@
 #include "aos/init.h"
 #include "aos/logging/log_namer.h"
 
-DEFINE_string(config, "aos_config.json", "Config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
 
-DEFINE_double(rotate_every, 30.0,
-              "If set, rotate the logger after this many seconds");
+ABSL_FLAG(double, rotate_every, 30.0,
+          "If set, rotate the logger after this many seconds");
 
-DECLARE_int32(flush_size);
+ABSL_DECLARE_FLAG(int32_t, flush_size);
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "This program provides a simple logger binary that logs all SHMEM data "
       "directly to a file specified at the command line. It does not manage "
       "filenames, so it will just crash if you attempt to overwrite an "
@@ -28,7 +30,7 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
@@ -40,8 +42,8 @@
 
   log_namer->set_extension(aos::logger::SnappyDecoder::kExtension);
   log_namer->set_encoder_factory([](size_t max_message_size) {
-    return std::make_unique<aos::logger::SnappyEncoder>(max_message_size,
-                                                        FLAGS_flush_size);
+    return std::make_unique<aos::logger::SnappyEncoder>(
+        max_message_size, absl::GetFlag(FLAGS_flush_size));
   });
 
   aos::monotonic_clock::time_point last_rotation_time =
@@ -53,11 +55,11 @@
         return (channel->max_size() * channel->frequency()) < 10e6;
       });
 
-  if (FLAGS_rotate_every != 0.0) {
+  if (absl::GetFlag(FLAGS_rotate_every) != 0.0) {
     logger.set_on_logged_period(
         [&logger, &last_rotation_time](aos::monotonic_clock::time_point t) {
-          if (t > last_rotation_time +
-                      std::chrono::duration<double>(FLAGS_rotate_every)) {
+          if (t > last_rotation_time + std::chrono::duration<double>(
+                                           absl::GetFlag(FLAGS_rotate_every))) {
             logger.Rotate();
             last_rotation_time = t;
           }
diff --git a/frc971/solvers/BUILD b/frc971/solvers/BUILD
index 1a8ba9b..35924eb 100644
--- a/frc971/solvers/BUILD
+++ b/frc971/solvers/BUILD
@@ -4,7 +4,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@org_tuxfamily_eigen//:eigen",
     ],
@@ -29,7 +30,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
         "@org_tuxfamily_eigen//:eigen",
     ],
diff --git a/frc971/solvers/convex.h b/frc971/solvers/convex.h
index d8989d8..4a7575d 100644
--- a/frc971/solvers/convex.h
+++ b/frc971/solvers/convex.h
@@ -6,8 +6,9 @@
 
 #include <iomanip>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_join.h"
-#include "glog/logging.h"
 #include <Eigen/Dense>
 
 namespace frc971::solvers {
diff --git a/frc971/solvers/sparse_convex.cc b/frc971/solvers/sparse_convex.cc
index 714b21c..646d7cf 100644
--- a/frc971/solvers/sparse_convex.cc
+++ b/frc971/solvers/sparse_convex.cc
@@ -1,7 +1,8 @@
 #include "frc971/solvers/sparse_convex.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_join.h"
-#include "glog/logging.h"
 #include <Eigen/Sparse>
 #include <Eigen/SparseLU>
 
diff --git a/frc971/solvers/sparse_convex.h b/frc971/solvers/sparse_convex.h
index 074f2f3..dafbcd2 100644
--- a/frc971/solvers/sparse_convex.h
+++ b/frc971/solvers/sparse_convex.h
@@ -6,7 +6,8 @@
 
 #include <iomanip>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <Eigen/Sparse>
 
 namespace frc971::solvers {
diff --git a/frc971/vision/BUILD b/frc971/vision/BUILD
index 14e3d41..48a8fb1 100644
--- a/frc971/vision/BUILD
+++ b/frc971/vision/BUILD
@@ -53,8 +53,9 @@
         "//aos/logging:log_namer",
         "//aos/util:filesystem_fbs",
         "//frc971/input:joystick_state_fbs",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -150,8 +151,9 @@
         "//aos/events:event_loop",
         "//aos/scoped:scoped_fd",
         "//aos/util:threaded_consumer",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -175,7 +177,8 @@
         "//frc971/vision:vision_fbs",
         "//third_party:opencv",
         "@com_github_foxglove_schemas//:schemas",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings:str_format",
         "@com_google_absl//absl/types:span",
         "@org_tuxfamily_eigen//:eigen",
@@ -270,7 +273,8 @@
     deps = [
         "//aos/util:math",
         "//third_party:opencv",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -313,7 +317,8 @@
         "//aos:init",
         "//frc971/vision:visualize_robot",
         "//third_party:opencv",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_ceres_solver//:ceres",
         "@org_tuxfamily_eigen//:eigen",
     ],
@@ -329,7 +334,8 @@
     deps = [
         "//aos/scoped:scoped_fd",
         "//aos/util:file",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings",
     ],
 )
@@ -433,7 +439,8 @@
     deps = [
         "//frc971/vision:calibration_fbs",
         "//third_party:opencv",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/strings:str_format",
     ],
 )
@@ -445,7 +452,8 @@
     deps = [
         "//aos/testing:googletest",
         "//frc971/vision:vision_util_lib",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/frc971/vision/calibration_accumulator.cc b/frc971/vision/calibration_accumulator.cc
index bbf51ee..9b1fa97 100644
--- a/frc971/vision/calibration_accumulator.cc
+++ b/frc971/vision/calibration_accumulator.cc
@@ -5,6 +5,7 @@
 #include <limits>
 
 #include "Eigen/Dense"
+#include "absl/flags/flag.h"
 #include "external/com_github_foxglove_schemas/CompressedImage_schema.h"
 #include "external/com_github_foxglove_schemas/ImageAnnotations_schema.h"
 #include <opencv2/highgui/highgui.hpp>
@@ -16,11 +17,11 @@
 #include "frc971/vision/charuco_lib.h"
 #include "frc971/wpilib/imu_batch_generated.h"
 
-DEFINE_bool(display_undistorted, false,
-            "If true, display the undistorted image.");
-DEFINE_string(save_path, "", "Where to store annotated images");
-DEFINE_bool(save_valid_only, false,
-            "If true, only save images with valid pose estimates");
+ABSL_FLAG(bool, display_undistorted, false,
+          "If true, display the undistorted image.");
+ABSL_FLAG(std::string, save_path, "", "Where to store annotated images");
+ABSL_FLAG(bool, save_valid_only, false,
+          "If true, only save images with valid pose estimates");
 
 namespace frc971::vision {
 using aos::distributed_clock;
@@ -232,8 +233,8 @@
             << "\nT:" << tvecs_eigen[0].transpose().format(HeavyFmt);
   }
 
-  if (FLAGS_visualize) {
-    if (FLAGS_display_undistorted) {
+  if (absl::GetFlag(FLAGS_visualize)) {
+    if (absl::GetFlag(FLAGS_display_undistorted)) {
       const cv::Size image_size(rgb_image.cols, rgb_image.rows);
       cv::Mat undistorted_rgb_image(image_size, CV_8UC3);
       cv::undistort(rgb_image, undistorted_rgb_image,
@@ -247,11 +248,11 @@
     cv::waitKey(1);
   }
 
-  if (FLAGS_save_path != "") {
-    if (!FLAGS_save_valid_only || valid) {
+  if (absl::GetFlag(FLAGS_save_path) != "") {
+    if (!absl::GetFlag(FLAGS_save_valid_only) || valid) {
       static int img_count = 0;
       std::string image_name = absl::StrFormat("/img_%06d.png", img_count);
-      std::string path = FLAGS_save_path + image_name;
+      std::string path = absl::GetFlag(FLAGS_save_path) + image_name;
       VLOG(2) << "Saving image to " << path;
       cv::imwrite(path, rgb_image);
       img_count++;
diff --git a/frc971/vision/ceres/BUILD b/frc971/vision/ceres/BUILD
index f2cb96b..d2671c8 100644
--- a/frc971/vision/ceres/BUILD
+++ b/frc971/vision/ceres/BUILD
@@ -15,7 +15,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
         "@com_google_ceres_solver//:ceres",
         "@org_tuxfamily_eigen//:eigen",
     ],
diff --git a/frc971/vision/ceres/read_g2o.h b/frc971/vision/ceres/read_g2o.h
index c427939..b10ac22 100644
--- a/frc971/vision/ceres/read_g2o.h
+++ b/frc971/vision/ceres/read_g2o.h
@@ -36,7 +36,8 @@
 #include <fstream>
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace ceres::examples {
 
diff --git a/frc971/vision/charuco_lib.cc b/frc971/vision/charuco_lib.cc
index 71c2ff6..dc4cb18 100644
--- a/frc971/vision/charuco_lib.cc
+++ b/frc971/vision/charuco_lib.cc
@@ -4,7 +4,10 @@
 #include <functional>
 #include <string_view>
 
-#include "glog/logging.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/core/eigen.hpp>
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc.hpp>
@@ -15,28 +18,30 @@
 #include "frc971/control_loops/quaternion_utils.h"
 #include "frc971/vision/vision_generated.h"
 
-DEFINE_string(board_template_path, "",
-              "If specified, write an image to the specified path for the "
-              "charuco board pattern.");
-DEFINE_bool(coarse_pattern, true, "If true, use coarse arucos; else, use fine");
-DEFINE_uint32(gray_threshold, 0,
-              "If > 0, threshold image based on this grayscale value");
-DEFINE_bool(large_board, true, "If true, use the large calibration board.");
-DEFINE_uint32(
-    min_charucos, 10,
+ABSL_FLAG(std::string, board_template_path, "",
+          "If specified, write an image to the specified path for the "
+          "charuco board pattern.");
+ABSL_FLAG(bool, coarse_pattern, true,
+          "If true, use coarse arucos; else, use fine");
+ABSL_FLAG(uint32_t, gray_threshold, 0,
+          "If > 0, threshold image based on this grayscale value");
+ABSL_FLAG(bool, large_board, true, "If true, use the large calibration board.");
+ABSL_FLAG(
+    uint32_t, min_charucos, 10,
     "The mininum number of aruco targets in charuco board required to match.");
-DEFINE_uint32(min_id, 0, "Minimum valid charuco id");
-DEFINE_uint32(max_diamonds, 0,
-              "Maximum number of diamonds to see.  Set to 0 for no limit");
-DEFINE_uint32(max_id, 15, "Maximum valid charuco id");
-DEFINE_bool(visualize, false, "Whether to visualize the resulting data.");
-DEFINE_bool(
-    draw_axes, false,
+ABSL_FLAG(uint32_t, min_id, 0, "Minimum valid charuco id");
+ABSL_FLAG(uint32_t, max_diamonds, 0,
+          "Maximum number of diamonds to see.  Set to 0 for no limit");
+ABSL_FLAG(uint32_t, max_id, 15, "Maximum valid charuco id");
+ABSL_FLAG(bool, visualize, false, "Whether to visualize the resulting data.");
+ABSL_FLAG(
+    bool, draw_axes, false,
     "Whether to draw axes on the resulting data-- warning, may cause crashes.");
 
-DEFINE_uint32(disable_delay, 100, "Time after an issue to disable tracing at.");
+ABSL_FLAG(uint32_t, disable_delay, 100,
+          "Time after an issue to disable tracing at.");
 
-DECLARE_bool(enable_ftrace);
+ABSL_DECLARE_FLAG(bool, enable_ftrace);
 
 namespace frc971::vision {
 namespace chrono = std::chrono;
@@ -121,13 +126,14 @@
     const double age_double =
         std::chrono::duration_cast<std::chrono::duration<double>>(age).count();
     if (age > max_age_) {
-      if (FLAGS_enable_ftrace) {
+      if (absl::GetFlag(FLAGS_enable_ftrace)) {
         ftrace_.FormatMessage("Too late receiving image, age: %f\n",
                               age_double);
-        if (FLAGS_disable_delay > 0) {
+        if (absl::GetFlag(FLAGS_disable_delay) > 0) {
           if (!disabling_) {
-            timer_fn_->Schedule(event_loop_->monotonic_now() +
-                                chrono::milliseconds(FLAGS_disable_delay));
+            timer_fn_->Schedule(
+                event_loop_->monotonic_now() +
+                chrono::milliseconds(absl::GetFlag(FLAGS_disable_delay)));
             disabling_ = true;
           }
         } else {
@@ -175,28 +181,32 @@
   if (target_type_ == TargetType::kCharuco ||
       target_type_ == TargetType::kAruco) {
     dictionary_ = cv::aruco::getPredefinedDictionary(
-        FLAGS_large_board ? cv::aruco::DICT_5X5_250 : cv::aruco::DICT_6X6_250);
+        absl::GetFlag(FLAGS_large_board) ? cv::aruco::DICT_5X5_250
+                                         : cv::aruco::DICT_6X6_250);
 
     if (target_type_ == TargetType::kCharuco) {
-      LOG(INFO) << "Using " << (FLAGS_large_board ? "large" : "small")
+      LOG(INFO) << "Using "
+                << (absl::GetFlag(FLAGS_large_board) ? "large" : "small")
                 << " charuco board with "
-                << (FLAGS_coarse_pattern ? "coarse" : "fine") << " pattern";
-      board_ =
-          (FLAGS_large_board
-               ? (FLAGS_coarse_pattern ? cv::aruco::CharucoBoard::create(
-                                             12, 9, 0.06, 0.04666, dictionary_)
-                                       : cv::aruco::CharucoBoard::create(
-                                             25, 18, 0.03, 0.0233, dictionary_))
-               : (FLAGS_coarse_pattern ? cv::aruco::CharucoBoard::create(
-                                             7, 5, 0.04, 0.025, dictionary_)
-                                       // TODO(jim): Need to figure out what
-                                       // size is for small board, fine pattern
-                                       : cv::aruco::CharucoBoard::create(
-                                             7, 5, 0.03, 0.0233, dictionary_)));
-      if (!FLAGS_board_template_path.empty()) {
+                << (absl::GetFlag(FLAGS_coarse_pattern) ? "coarse" : "fine")
+                << " pattern";
+      board_ = (absl::GetFlag(FLAGS_large_board)
+                    ? (absl::GetFlag(FLAGS_coarse_pattern)
+                           ? cv::aruco::CharucoBoard::create(
+                                 12, 9, 0.06, 0.04666, dictionary_)
+                           : cv::aruco::CharucoBoard::create(
+                                 25, 18, 0.03, 0.0233, dictionary_))
+                    : (absl::GetFlag(FLAGS_coarse_pattern)
+                           ? cv::aruco::CharucoBoard::create(7, 5, 0.04, 0.025,
+                                                             dictionary_)
+                           // TODO(jim): Need to figure out what
+                           // size is for small board, fine pattern
+                           : cv::aruco::CharucoBoard::create(7, 5, 0.03, 0.0233,
+                                                             dictionary_)));
+      if (!absl::GetFlag(FLAGS_board_template_path).empty()) {
         cv::Mat board_image;
         board_->draw(cv::Size(600, 500), board_image, 10, 1);
-        cv::imwrite(FLAGS_board_template_path, board_image);
+        cv::imwrite(absl::GetFlag(FLAGS_board_template_path), board_image);
       }
     }
   } else if (target_type_ == TargetType::kCharucoDiamond) {
@@ -244,7 +254,7 @@
     // TODO<Jim>: Either track this down or reimplement drawAxes
     if (result.z() < 0.01) {
       LOG(INFO) << "Skipping, due to z value too small: " << result.z();
-    } else if (FLAGS_draw_axes == true) {
+    } else if (absl::GetFlag(FLAGS_draw_axes) == true) {
       result /= result.z();
       if (target_type_ == TargetType::kCharuco ||
           target_type_ == TargetType::kAprilTag) {
@@ -353,12 +363,13 @@
           .count();
 
   // Have found this useful if there is blurry / noisy images
-  if (FLAGS_gray_threshold > 0) {
+  if (absl::GetFlag(FLAGS_gray_threshold) > 0) {
     cv::Mat gray;
     cv::cvtColor(rgb_image, gray, cv::COLOR_BGR2GRAY);
 
     cv::Mat thresh;
-    cv::threshold(gray, thresh, FLAGS_gray_threshold, 255, cv::THRESH_BINARY);
+    cv::threshold(gray, thresh, absl::GetFlag(FLAGS_gray_threshold), 255,
+                  cv::THRESH_BINARY);
     cv::cvtColor(thresh, rgb_image, cv::COLOR_GRAY2RGB);
   }
 
@@ -382,7 +393,7 @@
       std::vector<cv::Point2f> charuco_corners;
 
       // If enough aruco markers detected for the Charuco board
-      if (marker_ids.size() >= FLAGS_min_charucos) {
+      if (marker_ids.size() >= absl::GetFlag(FLAGS_min_charucos)) {
         // Run everything twice, once with the calibration, and once
         // without. This lets us both collect data to calibrate the
         // intrinsics of the camera (to determine the intrinsics from
@@ -403,7 +414,7 @@
             charuco_corners_with_calibration, charuco_ids_with_calibration,
             calibration_.CameraIntrinsics(), calibration_.CameraDistCoeffs());
 
-        if (charuco_ids.size() >= FLAGS_min_charucos) {
+        if (charuco_ids.size() >= absl::GetFlag(FLAGS_min_charucos)) {
           cv::aruco::drawDetectedCornersCharuco(
               rgb_image, charuco_corners, charuco_ids, cv::Scalar(255, 0, 0));
 
@@ -432,12 +443,14 @@
           }
         } else {
           VLOG(2) << "Age: " << age_double << ", not enough charuco IDs, got "
-                  << charuco_ids.size() << ", needed " << FLAGS_min_charucos;
+                  << charuco_ids.size() << ", needed "
+                  << absl::GetFlag(FLAGS_min_charucos);
         }
       } else {
         VLOG(2) << "Age: " << age_double
                 << ", not enough marker IDs for charuco board, got "
-                << marker_ids.size() << ", needed " << FLAGS_min_charucos;
+                << marker_ids.size() << ", needed "
+                << absl::GetFlag(FLAGS_min_charucos);
       }
     } else if (target_type_ == TargetType::kAruco ||
                target_type_ == TargetType::kAprilTag) {
@@ -466,14 +479,15 @@
       // Should be at least one, and no more than FLAGS_max_diamonds.
       // Different calibration routines will require different values for this
       if (diamond_ids.size() > 0 &&
-          (FLAGS_max_diamonds == 0 ||
-           diamond_ids.size() <= FLAGS_max_diamonds)) {
+          (absl::GetFlag(FLAGS_max_diamonds) == 0 ||
+           diamond_ids.size() <= absl::GetFlag(FLAGS_max_diamonds))) {
         // TODO<Jim>: Could probably make this check more general than
         // requiring range of ids
         bool all_valid_ids = true;
         for (uint i = 0; i < 4; i++) {
           uint id = diamond_ids[0][i];
-          if ((id < FLAGS_min_id) || (id > FLAGS_max_id)) {
+          if ((id < absl::GetFlag(FLAGS_min_id)) ||
+              (id > absl::GetFlag(FLAGS_max_id))) {
             all_valid_ids = false;
             LOG(INFO) << "Got invalid charuco id: " << id;
           }
@@ -505,7 +519,8 @@
         } else {
           VLOG(2) << "Found too many number of diamond markers, which likely "
                      "means false positives were detected: "
-                  << diamond_ids.size() << " > " << FLAGS_max_diamonds;
+                  << diamond_ids.size() << " > "
+                  << absl::GetFlag(FLAGS_max_diamonds);
         }
       }
     } else {
diff --git a/frc971/vision/charuco_lib.h b/frc971/vision/charuco_lib.h
index aac25ee..e53d129 100644
--- a/frc971/vision/charuco_lib.h
+++ b/frc971/vision/charuco_lib.h
@@ -15,7 +15,7 @@
 #include "aos/network/message_bridge_server_generated.h"
 #include "frc971/vision/calibration_generated.h"
 
-DECLARE_bool(visualize);
+ABSL_DECLARE_FLAG(bool, visualize);
 
 namespace frc971::vision {
 
diff --git a/frc971/vision/foxglove_image_converter.cc b/frc971/vision/foxglove_image_converter.cc
index c004ac0..04f6030 100644
--- a/frc971/vision/foxglove_image_converter.cc
+++ b/frc971/vision/foxglove_image_converter.cc
@@ -1,20 +1,23 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/vision/foxglove_image_converter_lib.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_string(channel, "/camera", "Input/Output channel to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(std::string, channel, "/camera", "Input/Output channel to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
   frc971::vision::FoxgloveImageConverter converter(
-      &event_loop, FLAGS_channel, FLAGS_channel,
+      &event_loop, absl::GetFlag(FLAGS_channel), absl::GetFlag(FLAGS_channel),
       frc971::vision::ImageCompression::kJpeg);
 
   event_loop.Run();
diff --git a/frc971/vision/foxglove_image_converter_lib.cc b/frc971/vision/foxglove_image_converter_lib.cc
index 649f1bb..e6ebc4d 100644
--- a/frc971/vision/foxglove_image_converter_lib.cc
+++ b/frc971/vision/foxglove_image_converter_lib.cc
@@ -1,13 +1,14 @@
 #include "frc971/vision/foxglove_image_converter_lib.h"
 
+#include "absl/flags/flag.h"
 #include <opencv2/imgcodecs.hpp>
 #include <opencv2/imgproc.hpp>
 
-DEFINE_int32(jpeg_quality, 60,
-             "Compression quality of JPEGs, 0-100; lower numbers mean lower "
-             "quality and resulting image sizes.");
-DEFINE_uint32(max_period_ms, 100,
-              "Fastest period at which to convert images, to limit CPU usage.");
+ABSL_FLAG(int32_t, jpeg_quality, 60,
+          "Compression quality of JPEGs, 0-100; lower numbers mean lower "
+          "quality and resulting image sizes.");
+ABSL_FLAG(uint32_t, max_period_ms, 100,
+          "Fastest period at which to convert images, to limit CPU usage.");
 
 namespace frc971::vision {
 std::string_view ExtensionForCompression(ImageCompression compression) {
@@ -26,8 +27,9 @@
   // imencode doesn't let us pass in anything other than an std::vector, and
   // performance isn't yet a big enough issue to try to avoid the copy.
   std::vector<uint8_t> buffer;
-  CHECK(cv::imencode(absl::StrCat(".", format), image, buffer,
-                     {cv::IMWRITE_JPEG_QUALITY, FLAGS_jpeg_quality}));
+  CHECK(cv::imencode(
+      absl::StrCat(".", format), image, buffer,
+      {cv::IMWRITE_JPEG_QUALITY, absl::GetFlag(FLAGS_jpeg_quality)}));
   const flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data_offset =
       fbb->CreateVector(buffer);
   const struct timespec timestamp_t = aos::time::to_timespec(eof);
@@ -52,7 +54,7 @@
           [this, compression](const cv::Mat image,
                               const aos::monotonic_clock::time_point eof) {
             if (event_loop_->monotonic_now() >
-                (std::chrono::milliseconds(FLAGS_max_period_ms) +
+                (std::chrono::milliseconds(absl::GetFlag(FLAGS_max_period_ms)) +
                  sender_.monotonic_sent_time())) {
               auto builder = sender_.MakeBuilder();
               builder.CheckOk(builder.Send(
diff --git a/frc971/vision/foxglove_image_converter_test.cc b/frc971/vision/foxglove_image_converter_test.cc
index c9c7d66..3059ad2 100644
--- a/frc971/vision/foxglove_image_converter_test.cc
+++ b/frc971/vision/foxglove_image_converter_test.cc
@@ -1,3 +1,5 @@
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
@@ -6,7 +8,7 @@
 #include "aos/testing/tmpdir.h"
 #include "frc971/vision/foxglove_image_converter_lib.h"
 
-DECLARE_int32(jpeg_quality);
+ABSL_DECLARE_FLAG(int32_t, jpeg_quality);
 
 namespace frc971::vision {
 std::ostream &operator<<(std::ostream &os, ImageCompression compression) {
@@ -34,7 +36,7 @@
     // Because our test image for comparison was generated with a JPEG quality
     // of 95, we need to use that for the test to work. This also protects the
     // tests against future changes to the default JPEG quality.
-    FLAGS_jpeg_quality = 95;
+    absl::SetFlag(&FLAGS_jpeg_quality, 95);
     test_event_loop_->OnRun(
         [this]() { image_sender_.CheckOk(image_sender_.Send(camera_image_)); });
     test_event_loop_->MakeWatcher(
diff --git a/frc971/vision/geometry.h b/frc971/vision/geometry.h
index 3285446..f1495bc 100644
--- a/frc971/vision/geometry.h
+++ b/frc971/vision/geometry.h
@@ -3,7 +3,8 @@
 
 #include <optional>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "opencv2/core/types.hpp"
 
 #include "aos/util/math.h"
diff --git a/frc971/vision/geometry_test.cc b/frc971/vision/geometry_test.cc
index f34594c..070de12 100644
--- a/frc971/vision/geometry_test.cc
+++ b/frc971/vision/geometry_test.cc
@@ -2,7 +2,8 @@
 
 #include <cmath>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/util/math.h"
diff --git a/frc971/vision/image_logger.cc b/frc971/vision/image_logger.cc
index 2984824..cb8fc4e 100644
--- a/frc971/vision/image_logger.cc
+++ b/frc971/vision/image_logger.cc
@@ -1,8 +1,10 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_writer.h"
@@ -12,16 +14,16 @@
 #include "aos/util/filesystem_generated.h"
 #include "frc971/input/joystick_state_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
 
-DEFINE_double(rotate_every, 0.0,
-              "If set, rotate the logger after this many seconds");
-DECLARE_int32(flush_size);
-DEFINE_double(disabled_time, 5.0,
-              "Continue logging if disabled for this amount of time or less");
-DEFINE_bool(direct, false,
-            "If true, write using O_DIRECT and write 512 byte aligned blocks "
-            "whenever possible.");
+ABSL_FLAG(double, rotate_every, 0.0,
+          "If set, rotate the logger after this many seconds");
+ABSL_DECLARE_FLAG(int32_t, flush_size);
+ABSL_FLAG(double, disabled_time, 5.0,
+          "Continue logging if disabled for this amount of time or less");
+ABSL_FLAG(bool, direct, false,
+          "If true, write using O_DIRECT and write 512 byte aligned blocks "
+          "whenever possible.");
 
 std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
     aos::EventLoop *event_loop) {
@@ -33,19 +35,20 @@
   }
 
   return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
-      event_loop, std::make_unique<aos::logger::RenamableFileBackend>(
-                      absl::StrCat(log_name.value(), "/"), FLAGS_direct));
+      event_loop,
+      std::make_unique<aos::logger::RenamableFileBackend>(
+          absl::StrCat(log_name.value(), "/"), absl::GetFlag(FLAGS_direct)));
 }
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "This program provides a simple logger binary that logs all SHMEM data "
       "directly to a file specified at the command line when the robot is "
       "enabled and for a bit of time after.");
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
@@ -60,11 +63,12 @@
       event_loop.monotonic_now();
   aos::logger::Logger logger(&event_loop);
 
-  if (FLAGS_rotate_every != 0.0) {
+  if (absl::GetFlag(FLAGS_rotate_every) != 0.0) {
     logger.set_on_logged_period([&](aos::monotonic_clock::time_point) {
       const auto now = event_loop.monotonic_now();
-      if (logging && now > last_rotation_time + std::chrono::duration<double>(
-                                                    FLAGS_rotate_every)) {
+      if (logging &&
+          now > last_rotation_time + std::chrono::duration<double>(
+                                         absl::GetFlag(FLAGS_rotate_every))) {
         logger.Rotate();
         last_rotation_time = now;
       }
@@ -105,8 +109,9 @@
 
         const bool should_be_logging =
             (enabled ||
-             timestamp < last_disable_time + std::chrono::duration<double>(
-                                                 FLAGS_disabled_time)) &&
+             timestamp <
+                 last_disable_time + std::chrono::duration<double>(
+                                         absl::GetFlag(FLAGS_disabled_time))) &&
             enough_space;
 
         if (!logging && should_be_logging) {
diff --git a/frc971/vision/image_replay.cc b/frc971/vision/image_replay.cc
index 3b75c92..f4b3842 100644
--- a/frc971/vision/image_replay.cc
+++ b/frc971/vision/image_replay.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 
@@ -10,8 +10,8 @@
 #include "aos/logging/log_message_generated.h"
 #include "frc971/vision/vision_generated.h"
 
-DEFINE_string(node, "orin1", "The node to view the log from");
-DEFINE_string(channel, "/camera0", "The channel to view the log from");
+ABSL_FLAG(std::string, node, "orin1", "The node to view the log from");
+ABSL_FLAG(std::string, channel, "/camera0", "The channel to view the log from");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
@@ -23,11 +23,12 @@
   aos::SimulatedEventLoopFactory factory(reader.configuration());
   reader.Register(&factory);
 
-  aos::NodeEventLoopFactory *node = factory.GetNodeEventLoopFactory(FLAGS_node);
+  aos::NodeEventLoopFactory *node =
+      factory.GetNodeEventLoopFactory(absl::GetFlag(FLAGS_node));
 
   std::unique_ptr<aos::EventLoop> image_loop = node->MakeEventLoop("image");
   image_loop->MakeWatcher(
-      "/" + FLAGS_node + "/" + FLAGS_channel,
+      "/" + absl::GetFlag(FLAGS_node) + "/" + absl::GetFlag(FLAGS_channel),
       [](const frc971::vision::CameraImage &msg) {
         cv::Mat color_image(cv::Size(msg.cols(), msg.rows()), CV_8UC2,
                             (void *)msg.data()->data());
diff --git a/frc971/vision/intrinsics_calibration.cc b/frc971/vision/intrinsics_calibration.cc
index e0ec38c..eb5605b 100644
--- a/frc971/vision/intrinsics_calibration.cc
+++ b/frc971/vision/intrinsics_calibration.cc
@@ -1,6 +1,7 @@
 #include <cmath>
 #include <regex>
 
+#include "absl/flags/flag.h"
 #include "absl/strings/str_format.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/highgui/highgui.hpp>
@@ -14,32 +15,35 @@
 #include "frc971/vision/intrinsics_calibration_lib.h"
 
 // TODO: Would be nice to remove this, but it depends on year-by-year Constants
-DEFINE_string(base_intrinsics, "",
-              "Intrinsics to use for estimating board pose prior to solving "
-              "for the new intrinsics.");
-DEFINE_string(calibration_folder, ".", "Folder to place calibration files.");
-DEFINE_string(camera_id, "", "Camera ID in format YY-NN-- year and number.");
-DEFINE_string(channel, "/camera", "Camera channel to use");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_string(cpu_name, "", "Pi/Orin name to calibrate.");
-DEFINE_bool(display_undistorted, false,
-            "If true, display the undistorted image.");
+ABSL_FLAG(std::string, base_intrinsics, "",
+          "Intrinsics to use for estimating board pose prior to solving "
+          "for the new intrinsics.");
+ABSL_FLAG(std::string, calibration_folder, ".",
+          "Folder to place calibration files.");
+ABSL_FLAG(std::string, camera_id, "",
+          "Camera ID in format YY-NN-- year and number.");
+ABSL_FLAG(std::string, channel, "/camera", "Camera channel to use");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(std::string, cpu_name, "", "Pi/Orin name to calibrate.");
+ABSL_FLAG(bool, display_undistorted, false,
+          "If true, display the undistorted image.");
 
 namespace frc971::vision {
 namespace {
 
 void Main() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
-  std::string hostname = FLAGS_cpu_name;
+  std::string hostname = absl::GetFlag(FLAGS_cpu_name);
   if (hostname == "") {
     hostname = aos::network::GetHostname();
     LOG(INFO) << "Using pi/orin name from hostname as " << hostname;
   }
-  CHECK(!FLAGS_base_intrinsics.empty())
+  CHECK(!absl::GetFlag(FLAGS_base_intrinsics).empty())
       << "Need a base intrinsics json to use to auto-capture images when the "
          "camera moves.";
   std::unique_ptr<aos::ExitHandle> exit_handle = event_loop.MakeExitHandle();
@@ -54,18 +58,19 @@
   std::string camera_name = absl::StrCat(
       "/", aos::network::ParsePiOrOrin(hostname).value(),
       std::to_string(aos::network::ParsePiOrOrinNumber(hostname).value()),
-      FLAGS_channel);
+      absl::GetFlag(FLAGS_channel));
   // THIS IS A HACK FOR 2024, since we call Orin2 "Imu"
   if (aos::network::ParsePiOrOrin(hostname).value() == "orin" &&
       aos::network::ParsePiOrOrinNumber(hostname).value() == 2) {
     LOG(INFO) << "\nHACK for 2024: Renaming orin2 to imu\n";
-    camera_name = absl::StrCat("/imu", FLAGS_channel);
+    camera_name = absl::StrCat("/imu", absl::GetFlag(FLAGS_channel));
   }
 
-  IntrinsicsCalibration extractor(&event_loop, hostname, camera_name,
-                                  FLAGS_camera_id, FLAGS_base_intrinsics,
-                                  FLAGS_display_undistorted,
-                                  FLAGS_calibration_folder, exit_handle.get());
+  IntrinsicsCalibration extractor(
+      &event_loop, hostname, camera_name, absl::GetFlag(FLAGS_camera_id),
+      absl::GetFlag(FLAGS_base_intrinsics),
+      absl::GetFlag(FLAGS_display_undistorted),
+      absl::GetFlag(FLAGS_calibration_folder), exit_handle.get());
 
   event_loop.Run();
 
diff --git a/frc971/vision/intrinsics_calibration_lib.cc b/frc971/vision/intrinsics_calibration_lib.cc
index 5584ed7..47e6929 100644
--- a/frc971/vision/intrinsics_calibration_lib.cc
+++ b/frc971/vision/intrinsics_calibration_lib.cc
@@ -1,6 +1,9 @@
 #include "frc971/vision/intrinsics_calibration_lib.h"
 
-DECLARE_bool(visualize);
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+
+ABSL_DECLARE_FLAG(bool, visualize);
 
 namespace frc971::vision {
 
@@ -49,13 +52,13 @@
       calibration_folder_(calibration_folder),
       exit_handle_(exit_handle),
       exit_collection_(false) {
-  if (!FLAGS_visualize) {
+  if (!absl::GetFlag(FLAGS_visualize)) {
     // The only way to exit into the calibration routines is by hitting "q"
     // while visualization is running.  The event_loop doesn't pause enough
     // to handle ctrl-c exit requests
     LOG(INFO) << "Setting visualize to true, since currently the intrinsics "
                  "only works this way";
-    FLAGS_visualize = true;
+    absl::SetFlag(&FLAGS_visualize, true);
   }
   LOG(INFO) << "Hostname is: " << hostname_ << " and camera channel is "
             << camera_channel_;
@@ -73,7 +76,7 @@
     std::vector<std::vector<cv::Point2f>> charuco_corners, bool valid,
     std::vector<Eigen::Vector3d> rvecs_eigen,
     std::vector<Eigen::Vector3d> tvecs_eigen) {
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     // Reduce resolution displayed on remote viewer to prevent lag
     cv::resize(rgb_image, rgb_image,
                cv::Size(rgb_image.cols / 2, rgb_image.rows / 2));
diff --git a/frc971/vision/media_device.cc b/frc971/vision/media_device.cc
index 46f3419..c0f0ec4 100644
--- a/frc971/vision/media_device.cc
+++ b/frc971/vision/media_device.cc
@@ -13,9 +13,10 @@
 #include <string_view>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_split.h"
-#include "glog/logging.h"
 
 #include "aos/scoped/scoped_fd.h"
 #include "aos/util/file.h"
diff --git a/frc971/vision/media_device.h b/frc971/vision/media_device.h
index 31d0882..424a363 100644
--- a/frc971/vision/media_device.h
+++ b/frc971/vision/media_device.h
@@ -12,7 +12,8 @@
 #include <string_view>
 #include <vector>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/scoped/scoped_fd.h"
 
diff --git a/frc971/vision/modify_extrinsics.cc b/frc971/vision/modify_extrinsics.cc
index d021744..355f790 100644
--- a/frc971/vision/modify_extrinsics.cc
+++ b/frc971/vision/modify_extrinsics.cc
@@ -4,6 +4,7 @@
 
 #include "Eigen/Dense"
 #include "Eigen/Geometry"
+#include "absl/flags/flag.h"
 #include "absl/strings/str_format.h"
 
 #include "aos/configuration.h"
@@ -23,28 +24,30 @@
 // By default, writes to /tmp, but will write to calib_files folder if
 // full path is given and calibration_folder is blank
 
-DEFINE_string(orig_calib_file, "",
-              "Intrinsics to use for estimating board pose prior to solving "
-              "for the new intrinsics.");
-DEFINE_string(calibration_folder, "/tmp", "Folder to place calibration files.");
-DEFINE_string(node_name, "",
-              "Node name to use, e.g. orin1, imu; unchanged if blank");
-DEFINE_int32(team_number, -1, "Team number to use; unchanged if -1");
-DEFINE_int32(camera_number, -1, "Camera number to use; unchanged if -1");
+ABSL_FLAG(std::string, orig_calib_file, "",
+          "Intrinsics to use for estimating board pose prior to solving "
+          "for the new intrinsics.");
+ABSL_FLAG(std::string, calibration_folder, "/tmp",
+          "Folder to place calibration files.");
+ABSL_FLAG(std::string, node_name, "",
+          "Node name to use, e.g. orin1, imu; unchanged if blank");
+ABSL_FLAG(int32_t, team_number, -1, "Team number to use; unchanged if -1");
+ABSL_FLAG(int32_t, camera_number, -1, "Camera number to use; unchanged if -1");
 
-DEFINE_bool(set_extrinsics, true, "Set to false to ignore extrinsic data");
-DEFINE_bool(use_inches, true,
-            "Whether to use inches as units (meters if false)");
-DEFINE_bool(use_degrees, true,
-            "Whether to use degrees as units (radians if false)");
-DEFINE_double(camera_x, 0.0, "x location of camera");
-DEFINE_double(camera_y, 0.0, "y location of camera");
-DEFINE_double(camera_z, 0.0, "z location of camera");
+ABSL_FLAG(bool, set_extrinsics, true, "Set to false to ignore extrinsic data");
+ABSL_FLAG(bool, use_inches, true,
+          "Whether to use inches as units (meters if false)");
+ABSL_FLAG(bool, use_degrees, true,
+          "Whether to use degrees as units (radians if false)");
+ABSL_FLAG(double, camera_x, 0.0, "x location of camera");
+ABSL_FLAG(double, camera_y, 0.0, "y location of camera");
+ABSL_FLAG(double, camera_z, 0.0, "z location of camera");
 // Don't currently allow for roll of cameras
-DEFINE_double(camera_yaw, 0.0, "yaw of camera about robot z axis");
-DEFINE_double(camera_pitch, 0.0, "pitch of camera relative to robot y axis");
+ABSL_FLAG(double, camera_yaw, 0.0, "yaw of camera about robot z axis");
+ABSL_FLAG(double, camera_pitch, 0.0,
+          "pitch of camera relative to robot y axis");
 // TODO: This could be done by setting the pixel size and using the intrinsics
-DEFINE_double(focal_length, 0.002, "Focal length in meters");
+ABSL_FLAG(double, focal_length, 0.002, "Focal length in meters");
 
 namespace frc971::vision {
 namespace {
@@ -74,30 +77,34 @@
   // If we're told to set the extrinsics, clear old and add in new
   flatbuffers::Offset<calibration::TransformationMatrix>
       fixed_extrinsics_offset;
-  if (FLAGS_set_extrinsics) {
+  if (absl::GetFlag(FLAGS_set_extrinsics)) {
     cal_copy.mutable_message()->clear_fixed_extrinsics();
     Eigen::Affine3d extrinsic_matrix;
     // Convert to metric
-    double translation_scale = (FLAGS_use_inches ? 0.0254 : 1.0);
-    Eigen::Translation3d translation(FLAGS_camera_x * translation_scale,
-                                     FLAGS_camera_y * translation_scale,
-                                     FLAGS_camera_z * translation_scale);
+    double translation_scale = (absl::GetFlag(FLAGS_use_inches) ? 0.0254 : 1.0);
+    Eigen::Translation3d translation(
+        absl::GetFlag(FLAGS_camera_x) * translation_scale,
+        absl::GetFlag(FLAGS_camera_y) * translation_scale,
+        absl::GetFlag(FLAGS_camera_z) * translation_scale);
 
     // convert to radians
-    double angle_scale = (FLAGS_use_degrees ? M_PI / 180.0 : 1.0);
+    double angle_scale =
+        (absl::GetFlag(FLAGS_use_degrees) ? M_PI / 180.0 : 1.0);
     // The rotation that takes robot coordinates (x forward, z up) to camera
     // coordiantes (z forward, x right)
     Eigen::Quaterniond R_robo_cam =
         Eigen::AngleAxisd(-M_PI / 2.0, Eigen::Vector3d::UnitZ()) *
         Eigen::AngleAxisd(-M_PI / 2.0, Eigen::Vector3d::UnitX());
-    Eigen::AngleAxisd pitchAngle(FLAGS_camera_pitch * angle_scale,
-                                 Eigen::Vector3d::UnitY());
-    Eigen::AngleAxisd yawAngle(FLAGS_camera_yaw * angle_scale,
+    Eigen::AngleAxisd pitchAngle(
+        absl::GetFlag(FLAGS_camera_pitch) * angle_scale,
+        Eigen::Vector3d::UnitY());
+    Eigen::AngleAxisd yawAngle(absl::GetFlag(FLAGS_camera_yaw) * angle_scale,
                                Eigen::Vector3d::UnitZ());
 
     Eigen::Quaterniond rotation = yawAngle * pitchAngle * R_robo_cam;
     Eigen::Vector3d focal_length_offset =
-        (rotation * Eigen::Translation3d(0.0, 0.0, FLAGS_focal_length))
+        (rotation *
+         Eigen::Translation3d(0.0, 0.0, absl::GetFlag(FLAGS_focal_length)))
             .translation();
     translation = translation * Eigen::Translation3d(focal_length_offset);
 
@@ -113,7 +120,7 @@
   calibration::CameraCalibration::Builder camera_calibration_builder(fbb);
   camera_calibration_builder.add_node_name(node_name_offset);
   camera_calibration_builder.add_team_number(team_number);
-  if (FLAGS_set_extrinsics) {
+  if (absl::GetFlag(FLAGS_set_extrinsics)) {
     camera_calibration_builder.add_fixed_extrinsics(fixed_extrinsics_offset);
   }
   camera_calibration_builder.add_camera_number(camera_number);
@@ -136,15 +143,15 @@
               orig_calib_filename);
 
   // Populate the new variables from command-line or from base_calibration
-  std::string node_name =
-      (FLAGS_node_name == "" ? base_calibration.message().node_name()->str()
-                             : FLAGS_node_name);
-  int team_number =
-      (FLAGS_team_number == -1 ? base_calibration.message().team_number()
-                               : FLAGS_team_number);
-  int camera_number =
-      (FLAGS_camera_number == -1 ? base_calibration.message().camera_number()
-                                 : FLAGS_camera_number);
+  std::string node_name = (absl::GetFlag(FLAGS_node_name) == ""
+                               ? base_calibration.message().node_name()->str()
+                               : absl::GetFlag(FLAGS_node_name));
+  int team_number = (absl::GetFlag(FLAGS_team_number) == -1
+                         ? base_calibration.message().team_number()
+                         : absl::GetFlag(FLAGS_team_number));
+  int camera_number = (absl::GetFlag(FLAGS_camera_number) == -1
+                           ? base_calibration.message().camera_number()
+                           : absl::GetFlag(FLAGS_camera_number));
   aos::FlatbufferDetachedBuffer<calibration::CameraCalibration>
       new_calibration = BuildCalibration(&base_calibration.message(), node_name,
                                          camera_number, team_number);
@@ -158,9 +165,9 @@
   std::string camera_id = base_calibration.message().camera_id()->str();
 
   const std::string dirname =
-      (FLAGS_calibration_folder == ""
+      (absl::GetFlag(FLAGS_calibration_folder) == ""
            ? std::filesystem::path(orig_calib_filename).parent_path().string()
-           : FLAGS_calibration_folder);
+           : absl::GetFlag(FLAGS_calibration_folder));
   const std::string new_calib_filename = frc971::vision::CalibrationFilename(
       dirname, node_name.c_str(), team_number, camera_number, camera_id.c_str(),
       time_ss.str());
diff --git a/frc971/vision/target_mapper.cc b/frc971/vision/target_mapper.cc
index f245f37..36f0a29 100644
--- a/frc971/vision/target_mapper.cc
+++ b/frc971/vision/target_mapper.cc
@@ -6,25 +6,26 @@
 #include "frc971/vision/ceres/pose_graph_3d_error_term.h"
 #include "frc971/vision/geometry.h"
 
-DEFINE_uint64(max_num_iterations, 100,
-              "Maximum number of iterations for the ceres solver");
-DEFINE_double(distortion_noise_scalar, 1.0,
-              "Scale the target pose distortion factor by this when computing "
-              "the noise.");
-DEFINE_int32(
-    frozen_target_id, 1,
+ABSL_FLAG(uint64_t, max_num_iterations, 100,
+          "Maximum number of iterations for the ceres solver");
+ABSL_FLAG(double, distortion_noise_scalar, 1.0,
+          "Scale the target pose distortion factor by this when computing "
+          "the noise.");
+ABSL_FLAG(
+    int32_t, frozen_target_id, 1,
     "Freeze the pose of this target so the map can have one fixed point.");
-DEFINE_int32(min_target_id, 1, "Minimum target id to solve for");
-DEFINE_int32(max_target_id, 8, "Maximum target id to solve for");
-DEFINE_bool(visualize_solver, false, "If true, visualize the solving process.");
+ABSL_FLAG(int32_t, min_target_id, 1, "Minimum target id to solve for");
+ABSL_FLAG(int32_t, max_target_id, 8, "Maximum target id to solve for");
+ABSL_FLAG(bool, visualize_solver, false,
+          "If true, visualize the solving process.");
 // This does seem like a strict threshold for a constaint to be considered an
 // outlier, but most inliers were very close together and this is what worked
 // best for map solving.
-DEFINE_double(outlier_std_devs, 1.0,
-              "Number of standard deviations above average error needed for a "
-              "constraint to be considered an outlier and get removed.");
-DEFINE_bool(do_map_fitting, false,
-            "Whether to do a final fit of the solved map to the original map");
+ABSL_FLAG(double, outlier_std_devs, 1.0,
+          "Number of standard deviations above average error needed for a "
+          "constraint to be considered an outlier and get removed.");
+ABSL_FLAG(bool, do_map_fitting, false,
+          "Whether to do a final fit of the solved map to the original map");
 
 namespace frc971::vision {
 Eigen::Affine3d PoseUtils::Pose3dToAffine3d(
@@ -192,14 +193,16 @@
     Q_vision(kOrientation3, kOrientation3) = std::pow(0.02, 2);
 
     // Add uncertainty for the 2 vision measurements (1 at start and 1 at end)
-    P += Q_vision * std::pow(detection_start.distance_from_camera *
-                                 (1.0 + FLAGS_distortion_noise_scalar *
-                                            detection_start.distortion_factor),
-                             2);
-    P += Q_vision * std::pow(detection_end.distance_from_camera *
-                                 (1.0 + FLAGS_distortion_noise_scalar *
-                                            detection_end.distortion_factor),
-                             2);
+    P += Q_vision *
+         std::pow(detection_start.distance_from_camera *
+                      (1.0 + absl::GetFlag(FLAGS_distortion_noise_scalar) *
+                                 detection_start.distortion_factor),
+                  2);
+    P += Q_vision *
+         std::pow(detection_end.distance_from_camera *
+                      (1.0 + absl::GetFlag(FLAGS_distortion_noise_scalar) *
+                                 detection_end.distortion_factor),
+                  2);
   }
 
   return P.inverse();
@@ -381,16 +384,17 @@
   // algorithm has internal damping which mitigates this issue, but it is
   // better to properly constrain the gauge freedom. This can be done by
   // setting one of the poses as constant so the optimizer cannot change it.
-  CHECK_NE(poses->count(FLAGS_frozen_target_id), 0ul)
-      << "Got no poses for frozen target id " << FLAGS_frozen_target_id;
-  CHECK_GE(FLAGS_frozen_target_id, min_constraint_id)
-      << "target to freeze index " << FLAGS_frozen_target_id
+  CHECK_NE(poses->count(absl::GetFlag(FLAGS_frozen_target_id)), 0ul)
+      << "Got no poses for frozen target id "
+      << absl::GetFlag(FLAGS_frozen_target_id);
+  CHECK_GE(absl::GetFlag(FLAGS_frozen_target_id), min_constraint_id)
+      << "target to freeze index " << absl::GetFlag(FLAGS_frozen_target_id)
       << " must be in range of constraints, > " << min_constraint_id;
-  CHECK_LE(FLAGS_frozen_target_id, max_constraint_id)
-      << "target to freeze index " << FLAGS_frozen_target_id
+  CHECK_LE(absl::GetFlag(FLAGS_frozen_target_id), max_constraint_id)
+      << "target to freeze index " << absl::GetFlag(FLAGS_frozen_target_id)
       << " must be in range of constraints, < " << max_constraint_id;
   ceres::examples::MapOfPoses::iterator pose_start_iter =
-      poses->find(FLAGS_frozen_target_id);
+      poses->find(absl::GetFlag(FLAGS_frozen_target_id));
   CHECK(pose_start_iter != poses->end()) << "There are no poses.";
   problem->SetParameterBlockConstant(pose_start_iter->second.p.data());
   problem->SetParameterBlockConstant(pose_start_iter->second.q.coeffs().data());
@@ -401,7 +405,8 @@
   // Set up robot visualization.
   vis_robot_.ClearImage();
 
-  const size_t num_targets = FLAGS_max_target_id - FLAGS_min_target_id;
+  const size_t num_targets =
+      absl::GetFlag(FLAGS_max_target_id) - absl::GetFlag(FLAGS_min_target_id);
   // Translation and rotation error for each target
   const size_t num_residuals = num_targets * 6;
   // Set up the only cost function (also known as residual). This uses
@@ -470,7 +475,7 @@
   CHECK(problem != nullptr);
 
   ceres::Solver::Options options;
-  options.max_num_iterations = FLAGS_max_num_iterations;
+  options.max_num_iterations = absl::GetFlag(FLAGS_max_num_iterations);
   options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
   options.minimizer_progress_to_stdout = false;
 
@@ -489,7 +494,7 @@
                                      &target_pose_problem_1);
   CHECK(SolveOptimizationProblem(&target_pose_problem_1))
       << "The target pose solve 1 was not successful, exiting.";
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     LOG(INFO) << "Displaying constraint graph before removing outliers";
     DisplayConstraintGraph();
     DisplaySolvedVsInitial();
@@ -503,13 +508,13 @@
                                      &target_pose_problem_2);
   CHECK(SolveOptimizationProblem(&target_pose_problem_2))
       << "The target pose solve 2 was not successful, exiting.";
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     LOG(INFO) << "Displaying constraint graph before removing outliers";
     DisplayConstraintGraph();
     DisplaySolvedVsInitial();
   }
 
-  if (FLAGS_do_map_fitting) {
+  if (absl::GetFlag(FLAGS_do_map_fitting)) {
     LOG(INFO) << "Solving the overall map's best alignment to the previous map";
     ceres::Problem map_fitting_problem(
         {.loss_function_ownership = ceres::DO_NOT_TAKE_OWNERSHIP});
@@ -523,14 +528,15 @@
     LOG(INFO) << "H_frozen_actual: "
               << PoseUtils::Affine3dToPose3d(H_frozen_actual);
 
-    auto H_world_frozen =
-        PoseUtils::Pose3dToAffine3d(target_poses_[FLAGS_frozen_target_id]);
+    auto H_world_frozen = PoseUtils::Pose3dToAffine3d(
+        target_poses_[absl::GetFlag(FLAGS_frozen_target_id)]);
     auto H_world_frozenactual = H_world_frozen * H_frozen_actual;
 
     // Offset the solved poses to become the actual ones
     for (auto &[id, pose] : target_poses_) {
       // Don't offset targets we didn't solve for
-      if (id < FLAGS_min_target_id || id > FLAGS_max_target_id) {
+      if (id < absl::GetFlag(FLAGS_min_target_id) ||
+          id > absl::GetFlag(FLAGS_max_target_id)) {
         continue;
       }
 
@@ -553,10 +559,10 @@
     aos::util::WriteStringToFileOrDie(output_path, map_json);
   }
 
-  for (TargetId id_start = FLAGS_min_target_id; id_start < FLAGS_max_target_id;
-       id_start++) {
-    for (TargetId id_end = id_start + 1; id_end <= FLAGS_max_target_id;
-         id_end++) {
+  for (TargetId id_start = absl::GetFlag(FLAGS_min_target_id);
+       id_start < absl::GetFlag(FLAGS_max_target_id); id_start++) {
+    for (TargetId id_end = id_start + 1;
+         id_end <= absl::GetFlag(FLAGS_max_target_id); id_end++) {
       auto H_start_end =
           PoseUtils::Pose3dToAffine3d(target_poses_.at(id_start)).inverse() *
           PoseUtils::Pose3dToAffine3d(target_poses_.at(id_end));
@@ -622,17 +628,19 @@
           << PoseUtils::Affine3dToPose3d(ScalarAffineToDouble(H_frozen_actual));
 
   Affine3s H_world_frozen =
-      PoseUtils::Pose3dToAffine3d(target_poses_.at(FLAGS_frozen_target_id))
+      PoseUtils::Pose3dToAffine3d(
+          target_poses_.at(absl::GetFlag(FLAGS_frozen_target_id)))
           .cast<S>();
   Affine3s H_world_frozenactual = H_world_frozen * H_frozen_actual;
 
   size_t residual_index = 0;
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     vis_robot_.ClearImage();
   }
 
   for (const auto &[id, solved_pose] : target_poses_) {
-    if (id < FLAGS_min_target_id || id > FLAGS_max_target_id) {
+    if (id < absl::GetFlag(FLAGS_min_target_id) ||
+        id > absl::GetFlag(FLAGS_max_target_id)) {
       continue;
     }
 
@@ -669,7 +677,7 @@
     residual[residual_index++] =
         kRotationScalar * R_ideal_actual.angle() * R_ideal_actual.axis().z();
 
-    if (FLAGS_visualize_solver) {
+    if (absl::GetFlag(FLAGS_visualize_solver)) {
       LOG(INFO) << std::to_string(id) + std::string("-est") << " at "
                 << ScalarAffineToDouble(H_world_actual).matrix();
       vis_robot_.DrawFrameAxes(ScalarAffineToDouble(H_world_actual),
@@ -679,7 +687,7 @@
                                std::to_string(id), cv::Scalar(255, 255, 255));
     }
   }
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     cv::imshow("Target maps", vis_robot_.image_);
     cv::waitKey(0);
   }
@@ -763,12 +771,12 @@
             // Remove constraints with errors significantly above
             // the average
             if (err.distance > stats_with_outliers_.avg_err.distance +
-                                   FLAGS_outlier_std_devs *
+                                   absl::GetFlag(FLAGS_outlier_std_devs) *
                                        stats_with_outliers_.std_dev.distance) {
               return true;
             }
             if (err.angle > stats_with_outliers_.avg_err.angle +
-                                FLAGS_outlier_std_devs *
+                                absl::GetFlag(FLAGS_outlier_std_devs) *
                                     stats_with_outliers_.std_dev.angle) {
               return true;
             }
@@ -812,14 +820,15 @@
   LOG(INFO) << "Dumping target constraints to " << path;
   std::ofstream fout(path.data());
   for (const auto &constraint : target_constraints_) {
-    fout << constraint << std::endl;
+    fout << absl::StrCat("", constraint) << std::endl;
   }
   fout.flush();
   fout.close();
 }
 
 void TargetMapper::PrintDiffs() const {
-  for (int id = FLAGS_min_target_id; id <= FLAGS_max_target_id; id++) {
+  for (int id = absl::GetFlag(FLAGS_min_target_id);
+       id <= absl::GetFlag(FLAGS_max_target_id); id++) {
     Eigen::Affine3d H_world_ideal =
         PoseUtils::Pose3dToAffine3d(ideal_target_poses_.at(id));
     Eigen::Affine3d H_world_solved =
@@ -839,20 +848,3 @@
 }
 
 }  // namespace frc971::vision
-
-std::ostream &operator<<(std::ostream &os, ceres::examples::Pose3d pose) {
-  auto rpy = frc971::vision::PoseUtils::QuaternionToEulerAngles(pose.q);
-  os << absl::StrFormat(
-      "{x: %.3f, y: %.3f, z: %.3f, roll: %.3f, pitch: "
-      "%.3f, yaw: %.3f}",
-      pose.p(0), pose.p(1), pose.p(2), rpy(0), rpy(1), rpy(2));
-  return os;
-}
-
-std::ostream &operator<<(std::ostream &os,
-                         ceres::examples::Constraint3d constraint) {
-  os << absl::StrFormat("{id_begin: %d, id_end: %d, pose: ",
-                        constraint.id_begin, constraint.id_end)
-     << constraint.t_be << "}";
-  return os;
-}
diff --git a/frc971/vision/target_mapper.h b/frc971/vision/target_mapper.h
index d1d122e..cae1c69 100644
--- a/frc971/vision/target_mapper.h
+++ b/frc971/vision/target_mapper.h
@@ -3,6 +3,7 @@
 
 #include <unordered_map>
 
+#include "absl/strings/str_format.h"
 #include "ceres/ceres.h"
 
 #include "aos/events/simulated_event_loop.h"
@@ -215,8 +216,23 @@
 
 }  // namespace frc971::vision
 
-std::ostream &operator<<(std::ostream &os, ceres::examples::Pose3d pose);
-std::ostream &operator<<(std::ostream &os,
-                         ceres::examples::Constraint3d constraint);
+namespace ceres::examples {
+template <typename Sink>
+void AbslStringify(Sink &sink, ceres::examples::Pose3d pose) {
+  auto rpy = frc971::vision::PoseUtils::QuaternionToEulerAngles(pose.q);
+  absl::Format(&sink,
+               "{x: %.3f, y: %.3f, z: %.3f, roll: %.3f, pitch: "
+               "%.3f, yaw: %.3f}",
+               pose.p(0), pose.p(1), pose.p(2), rpy(0), rpy(1), rpy(2));
+}
+
+template <typename Sink>
+void AbslStringify(Sink &sink, ceres::examples::Constraint3d constraint) {
+  absl::Format(&sink, "{id_begin: %d, id_end: %d, pose: ", constraint.id_begin,
+               constraint.id_end);
+  AbslStringify(sink, constraint.t_be);
+  sink.Append("}");
+}
+}  // namespace ceres::examples
 
 #endif  // FRC971_VISION_TARGET_MAPPER_H_
diff --git a/frc971/vision/target_mapper_test.cc b/frc971/vision/target_mapper_test.cc
index 8c6d37d..4e9db6f 100644
--- a/frc971/vision/target_mapper_test.cc
+++ b/frc971/vision/target_mapper_test.cc
@@ -2,7 +2,10 @@
 
 #include <random>
 
-#include "glog/logging.h"
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
@@ -10,8 +13,8 @@
 #include "aos/testing/random_seed.h"
 #include "aos/util/math.h"
 
-DECLARE_int32(min_target_id);
-DECLARE_int32(max_target_id);
+ABSL_DECLARE_FLAG(int32_t, min_target_id);
+ABSL_DECLARE_FLAG(int32_t, max_target_id);
 
 namespace frc971::vision {
 
@@ -342,8 +345,8 @@
 }
 
 TEST(TargetMapperTest, TwoTargetsOneConstraint) {
-  FLAGS_min_target_id = 0;
-  FLAGS_max_target_id = 1;
+  absl::SetFlag(&FLAGS_min_target_id, 0);
+  absl::SetFlag(&FLAGS_max_target_id, 1);
 
   ceres::examples::MapOfPoses target_poses;
   target_poses[0] = Make2dPose(5.0, 0.0, M_PI);
@@ -368,8 +371,8 @@
 }
 
 TEST(TargetMapperTest, TwoTargetsTwoConstraints) {
-  FLAGS_min_target_id = 0;
-  FLAGS_max_target_id = 1;
+  absl::SetFlag(&FLAGS_min_target_id, 0);
+  absl::SetFlag(&FLAGS_max_target_id, 1);
 
   ceres::examples::MapOfPoses target_poses;
   target_poses[0] = Make2dPose(5.0, 0.0, M_PI);
@@ -400,8 +403,8 @@
 }
 
 TEST(TargetMapperTest, TwoTargetsOneNoisyConstraint) {
-  FLAGS_min_target_id = 0;
-  FLAGS_max_target_id = 1;
+  absl::SetFlag(&FLAGS_min_target_id, 0);
+  absl::SetFlag(&FLAGS_max_target_id, 1);
 
   ceres::examples::MapOfPoses target_poses;
   target_poses[0] = Make2dPose(5.0, 0.0, M_PI);
@@ -486,8 +489,8 @@
 // when freeing memory. For some reason this segfault occurs only in this test,
 // but when running the test with gdb it doesn't occur...
 TEST_F(ChargedUpTargetMapperTest, DISABLED_FieldCircleMotion) {
-  FLAGS_min_target_id = 1;
-  FLAGS_max_target_id = 8;
+  absl::SetFlag(&FLAGS_min_target_id, 1);
+  absl::SetFlag(&FLAGS_max_target_id, 8);
 
   // Read target map
   auto target_map_fbs = aos::JsonFileToFlatbuffer<TargetMap>(
diff --git a/frc971/vision/v4l2_reader.cc b/frc971/vision/v4l2_reader.cc
index 2d67c9c..e333dc5 100644
--- a/frc971/vision/v4l2_reader.cc
+++ b/frc971/vision/v4l2_reader.cc
@@ -6,8 +6,10 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-DEFINE_bool(ignore_timestamps, false,
-            "Don't require timestamps on images.  Used to allow webcams");
+#include "absl/flags/flag.h"
+
+ABSL_FLAG(bool, ignore_timestamps, false,
+          "Don't require timestamps on images.  Used to allow webcams");
 
 namespace frc971::vision {
 
@@ -233,7 +235,7 @@
     CHECK_EQ(ImageSize(), buffer.length);
   }
   CHECK(buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC);
-  if (!FLAGS_ignore_timestamps) {
+  if (!absl::GetFlag(FLAGS_ignore_timestamps)) {
     // Require that we have good timestamp on images
     CHECK_EQ(buffer.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK,
              static_cast<uint32_t>(V4L2_BUF_FLAG_TSTAMP_SRC_EOF));
diff --git a/frc971/vision/v4l2_reader.h b/frc971/vision/v4l2_reader.h
index 4906d8e..01634e2 100644
--- a/frc971/vision/v4l2_reader.h
+++ b/frc971/vision/v4l2_reader.h
@@ -4,8 +4,8 @@
 #include <array>
 #include <string>
 
+#include "absl/log/check.h"
 #include "absl/types/span.h"
-#include "glog/logging.h"
 
 #include "aos/containers/ring_buffer.h"
 #include "aos/events/epoll.h"
diff --git a/frc971/vision/vision_util_lib.cc b/frc971/vision/vision_util_lib.cc
index 45aa199..089f3ac 100644
--- a/frc971/vision/vision_util_lib.cc
+++ b/frc971/vision/vision_util_lib.cc
@@ -1,7 +1,8 @@
 #include "frc971/vision/vision_util_lib.h"
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/strings/str_format.h"
-#include "glog/logging.h"
 
 namespace frc971::vision {
 
diff --git a/frc971/vision/visualize_robot.cc b/frc971/vision/visualize_robot.cc
index d13668e..52a7695 100644
--- a/frc971/vision/visualize_robot.cc
+++ b/frc971/vision/visualize_robot.cc
@@ -1,6 +1,7 @@
 #include "frc971/vision/visualize_robot.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/core/eigen.hpp>
 #include <opencv2/highgui/highgui.hpp>
diff --git a/frc971/vision/visualize_robot_sample.cc b/frc971/vision/visualize_robot_sample.cc
index ad1d6b6..6e15f2f 100644
--- a/frc971/vision/visualize_robot_sample.cc
+++ b/frc971/vision/visualize_robot_sample.cc
@@ -1,7 +1,8 @@
 #include <math.h>
 
 #include "Eigen/Dense"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/aruco.hpp>
 #include <opencv2/aruco/charuco.hpp>
 #include <opencv2/calib3d.hpp>
diff --git a/frc971/wpilib/ADIS16470.cc b/frc971/wpilib/ADIS16470.cc
index 0b3d45c..f5e2a57 100644
--- a/frc971/wpilib/ADIS16470.cc
+++ b/frc971/wpilib/ADIS16470.cc
@@ -2,7 +2,8 @@
 
 #include <cinttypes>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/containers/sized_array.h"
 #include "aos/time/time.h"
diff --git a/frc971/wpilib/BUILD b/frc971/wpilib/BUILD
index 461eb4a..cfbf18e 100644
--- a/frc971/wpilib/BUILD
+++ b/frc971/wpilib/BUILD
@@ -314,7 +314,8 @@
         "//aos/events:event_loop",
         "//aos/time",
         "//third_party:wpilib",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ],
 )
@@ -432,7 +433,8 @@
         "//aos/time",
         "//aos/util:compiler_memory_barrier",
         "//third_party:wpilib",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -506,7 +508,8 @@
         "//aos/logging",
         "//frc971/control_loops/drivetrain:drivetrain_can_position_fbs",
         "//third_party:phoenix6",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -571,6 +574,6 @@
         "//aos:init",
         "//aos/events:shm_event_loop",
         "//frc971/input:joystick_state_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
diff --git a/frc971/wpilib/ahal/DigitalGlitchFilter.cc b/frc971/wpilib/ahal/DigitalGlitchFilter.cc
index 2b48fc9..811ee8d 100644
--- a/frc971/wpilib/ahal/DigitalGlitchFilter.cc
+++ b/frc971/wpilib/ahal/DigitalGlitchFilter.cc
@@ -10,7 +10,8 @@
 #include <algorithm>
 #include <array>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "frc971/wpilib/ahal/Counter.h"
 #include "frc971/wpilib/ahal/Encoder.h"
diff --git a/frc971/wpilib/ahal/InterruptableSensorBase.cc b/frc971/wpilib/ahal/InterruptableSensorBase.cc
index 06ee513..4f2d877 100644
--- a/frc971/wpilib/ahal/InterruptableSensorBase.cc
+++ b/frc971/wpilib/ahal/InterruptableSensorBase.cc
@@ -7,7 +7,8 @@
 
 #include "frc971/wpilib/ahal/InterruptableSensorBase.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "frc971/wpilib/ahal/WPIErrors.h"
 #include "hal/HAL.h"
diff --git a/frc971/wpilib/ahal/PWM.cc b/frc971/wpilib/ahal/PWM.cc
index 72219aa..3ff75d1 100644
--- a/frc971/wpilib/ahal/PWM.cc
+++ b/frc971/wpilib/ahal/PWM.cc
@@ -9,7 +9,8 @@
 
 #include <sstream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "frc971/wpilib/ahal/PWM.h"
 #include "frc971/wpilib/ahal/WPIErrors.h"
diff --git a/frc971/wpilib/ahal/WPIErrors.h b/frc971/wpilib/ahal/WPIErrors.h
index 601e65a..8a81e1a 100644
--- a/frc971/wpilib/ahal/WPIErrors.h
+++ b/frc971/wpilib/ahal/WPIErrors.h
@@ -9,7 +9,8 @@
 
 #include <cstdint>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #ifdef WPI_ERRORS_DEFINE_STRINGS
 #define S(label, offset, message)            \
diff --git a/frc971/wpilib/dma.cc b/frc971/wpilib/dma.cc
index 2d40aa9..9e716d1 100644
--- a/frc971/wpilib/dma.cc
+++ b/frc971/wpilib/dma.cc
@@ -4,7 +4,8 @@
 #include <cstring>
 #include <type_traits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "frc971/wpilib/ahal/AnalogInput.h"
 #include "frc971/wpilib/ahal/DigitalSource.h"
diff --git a/frc971/wpilib/fpga_time_conversion.h b/frc971/wpilib/fpga_time_conversion.h
index c279089..af80321 100644
--- a/frc971/wpilib/fpga_time_conversion.h
+++ b/frc971/wpilib/fpga_time_conversion.h
@@ -4,7 +4,8 @@
 #include <chrono>
 #include <optional>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 #include "hal/cpp/fpga_clock.h"
diff --git a/frc971/wpilib/joystick_republish.cc b/frc971/wpilib/joystick_republish.cc
index ae6f340..9ea6a1a 100644
--- a/frc971/wpilib/joystick_republish.cc
+++ b/frc971/wpilib/joystick_republish.cc
@@ -1,7 +1,7 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,13 +9,13 @@
 #include "aos/init.h"
 #include "frc971/input/joystick_state_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
 
   aos::Sender<aos::JoystickState> sender(
diff --git a/frc971/wpilib/sensor_reader.cc b/frc971/wpilib/sensor_reader.cc
index 1c8c5d3..3efe122 100644
--- a/frc971/wpilib/sensor_reader.cc
+++ b/frc971/wpilib/sensor_reader.cc
@@ -4,6 +4,8 @@
 
 #include <cinttypes>
 
+#include "absl/flags/flag.h"
+
 #include "aos/init.h"
 #include "aos/logging/logging.h"
 #include "aos/realtime.h"
@@ -14,8 +16,8 @@
 #include "frc971/wpilib/wpilib_interface.h"
 #include "hal/PWM.h"
 
-DEFINE_int32(pwm_offset, 5050 / 2,
-             "Offset of reading the sensors from the start of the PWM cycle");
+ABSL_FLAG(int32_t, pwm_offset, 5050 / 2,
+          "Offset of reading the sensors from the start of the PWM cycle");
 
 namespace frc971::wpilib {
 
@@ -164,11 +166,12 @@
     }
 
     last_tick_timepoint +=
-        ((monotonic_now - chrono::microseconds(FLAGS_pwm_offset) -
+        ((monotonic_now -
+          chrono::microseconds(absl::GetFlag(FLAGS_pwm_offset)) -
           last_tick_timepoint) /
          period_) *
             period_ +
-        chrono::microseconds(FLAGS_pwm_offset);
+        chrono::microseconds(absl::GetFlag(FLAGS_pwm_offset));
     VLOG(1) << "Now " << monotonic_now << " tick " << last_tick_timepoint;
     // If it's over 1/2 of a period back in time, that's wrong.  Move it
     // forwards to now.
diff --git a/frc971/wpilib/talonfx.h b/frc971/wpilib/talonfx.h
index 1f64b5b..dd75328 100644
--- a/frc971/wpilib/talonfx.h
+++ b/frc971/wpilib/talonfx.h
@@ -5,8 +5,9 @@
 #include <cinttypes>
 #include <vector>
 
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "ctre/phoenix6/TalonFX.hpp"
-#include "glog/logging.h"
 
 #include "aos/commonmath.h"
 #include "aos/init.h"
diff --git a/frc971/zeroing/BUILD b/frc971/zeroing/BUILD
index 81ed998..0884baa 100644
--- a/frc971/zeroing/BUILD
+++ b/frc971/zeroing/BUILD
@@ -14,7 +14,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
@@ -46,7 +47,8 @@
         "//frc971/control_loops:control_loops_fbs",
         "//frc971/control_loops/drivetrain:drivetrain_status_fbs",
         "//frc971/wpilib:imu_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
@@ -79,7 +81,8 @@
         "//aos/logging",
         "//frc971:constants",
         "//frc971/control_loops:control_loops_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -108,7 +111,8 @@
                 "//aos/logging",
                 "//frc971:constants",
                 "//frc971/control_loops:control_loops_fbs",
-                "@com_github_google_glog//:glog",
+                "@com_google_absl//absl/log",
+                "@com_google_absl//absl/log:check",
             ],
         ),
         cc_test(
diff --git a/frc971/zeroing/absolute_and_absolute_encoder.cc b/frc971/zeroing/absolute_and_absolute_encoder.cc
index b9ba33d..dab814b 100644
--- a/frc971/zeroing/absolute_and_absolute_encoder.cc
+++ b/frc971/zeroing/absolute_and_absolute_encoder.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 #include <numeric>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/logging/logging.h"
 #include "frc971/zeroing/wrap.h"
diff --git a/frc971/zeroing/absolute_and_absolute_encoder_test.cc b/frc971/zeroing/absolute_and_absolute_encoder_test.cc
index 08ab924..a6e47ca 100644
--- a/frc971/zeroing/absolute_and_absolute_encoder_test.cc
+++ b/frc971/zeroing/absolute_and_absolute_encoder_test.cc
@@ -1,6 +1,7 @@
 #include "frc971/zeroing/absolute_and_absolute_encoder.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/frc971/zeroing/absolute_encoder.cc b/frc971/zeroing/absolute_encoder.cc
index f5e3e3d..c2a795f 100644
--- a/frc971/zeroing/absolute_encoder.cc
+++ b/frc971/zeroing/absolute_encoder.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 #include <numeric>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/containers/error_list.h"
 #include "frc971/zeroing/wrap.h"
diff --git a/frc971/zeroing/averager.h b/frc971/zeroing/averager.h
index 370533f..6e4b888 100644
--- a/frc971/zeroing/averager.h
+++ b/frc971/zeroing/averager.h
@@ -6,7 +6,8 @@
 #include <cstdint>
 
 #include "Eigen/Dense"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace frc971::zeroing {
 
diff --git a/frc971/zeroing/continuous_absolute_encoder.cc b/frc971/zeroing/continuous_absolute_encoder.cc
index ebaf101..3381833 100644
--- a/frc971/zeroing/continuous_absolute_encoder.cc
+++ b/frc971/zeroing/continuous_absolute_encoder.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 #include <numeric>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/containers/error_list.h"
 #include "frc971/zeroing/wrap.h"
diff --git a/frc971/zeroing/hall_effect_and_position.cc b/frc971/zeroing/hall_effect_and_position.cc
index 99454e4..31d0675 100644
--- a/frc971/zeroing/hall_effect_and_position.cc
+++ b/frc971/zeroing/hall_effect_and_position.cc
@@ -4,7 +4,8 @@
 #include <cmath>
 #include <limits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace frc971::zeroing {
 
diff --git a/frc971/zeroing/pot_and_absolute_encoder.cc b/frc971/zeroing/pot_and_absolute_encoder.cc
index bef6f2d..15f283e 100644
--- a/frc971/zeroing/pot_and_absolute_encoder.cc
+++ b/frc971/zeroing/pot_and_absolute_encoder.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 #include <numeric>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/containers/error_list.h"
 #include "frc971/zeroing/wrap.h"
diff --git a/frc971/zeroing/pot_and_index.cc b/frc971/zeroing/pot_and_index.cc
index fb82f22..6a63415 100644
--- a/frc971/zeroing/pot_and_index.cc
+++ b/frc971/zeroing/pot_and_index.cc
@@ -2,7 +2,8 @@
 
 #include <cmath>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace frc971::zeroing {
 
diff --git a/frc971/zeroing/pulse_index.cc b/frc971/zeroing/pulse_index.cc
index 6e9a502..30da4a9 100644
--- a/frc971/zeroing/pulse_index.cc
+++ b/frc971/zeroing/pulse_index.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 #include <limits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace frc971::zeroing {
 
diff --git a/third_party/abseil/abseil.patch b/third_party/abseil/abseil.patch
index 36b37dc..135fba9 100644
--- a/third_party/abseil/abseil.patch
+++ b/third_party/abseil/abseil.patch
@@ -1,5 +1,18 @@
+diff --git a/absl/base/attributes.h b/absl/base/attributes.h
+index d4f67a12..e10f3957 100644
+--- a/absl/base/attributes.h
++++ b/absl/base/attributes.h
+@@ -196,7 +196,7 @@
+ //
+ // Tells the compiler that a given function never returns.
+ #if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__))
+-#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn))
++#define ABSL_ATTRIBUTE_NORETURN [[noreturn]]
+ #elif defined(_MSC_VER)
+ #define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn)
+ #else
 diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake
-index 04e7b444..81884a6d 100644
+index 430916f7..ebc876f2 100644
 --- a/absl/copts/GENERATED_AbseilCopts.cmake
 +++ b/absl/copts/GENERATED_AbseilCopts.cmake
 @@ -49,6 +49,13 @@ list(APPEND ABSL_GCC_FLAGS
@@ -30,7 +43,7 @@
      "-Wvarargs"
      "-Wvla"
      "-Wwrite-strings"
-@@ -95,8 +109,8 @@ list(APPEND ABSL_LLVM_FLAGS
+@@ -96,8 +110,8 @@ list(APPEND ABSL_LLVM_FLAGS
      "-Woverlength-strings"
      "-Wpointer-arith"
      "-Wself-assign"
@@ -40,7 +53,7 @@
      "-Wsign-conversion"
      "-Wstring-conversion"
      "-Wtautological-overlap-compare"
-@@ -114,6 +128,12 @@ list(APPEND ABSL_LLVM_FLAGS
+@@ -115,6 +129,12 @@ list(APPEND ABSL_LLVM_FLAGS
      "-Wno-implicit-int-float-conversion"
      "-Wno-unknown-warning-option"
      "-DNOMINMAX"
@@ -51,9 +64,9 @@
 +    "-Wno-shorten-64-to-32"
 +    "-Wno-stringop-overflow"
  )
-
+ 
  list(APPEND ABSL_LLVM_TEST_FLAGS
-@@ -133,7 +153,7 @@ list(APPEND ABSL_LLVM_TEST_FLAGS
+@@ -134,7 +154,7 @@ list(APPEND ABSL_LLVM_TEST_FLAGS
      "-Woverlength-strings"
      "-Wpointer-arith"
      "-Wself-assign"
@@ -62,7 +75,7 @@
      "-Wstring-conversion"
      "-Wtautological-overlap-compare"
      "-Wtautological-unsigned-zero-compare"
-@@ -150,6 +170,12 @@ list(APPEND ABSL_LLVM_TEST_FLAGS
+@@ -151,6 +171,12 @@ list(APPEND ABSL_LLVM_TEST_FLAGS
      "-Wno-implicit-int-float-conversion"
      "-Wno-unknown-warning-option"
      "-DNOMINMAX"
@@ -76,7 +89,7 @@
      "-Wno-implicit-int-conversion"
      "-Wno-missing-prototypes"
 diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl
-index 84f4bffc..21f487a1 100644
+index 011d8a98..beb94fa7 100644
 --- a/absl/copts/GENERATED_copts.bzl
 +++ b/absl/copts/GENERATED_copts.bzl
 @@ -50,6 +50,13 @@ ABSL_GCC_FLAGS = [
@@ -107,7 +120,7 @@
      "-Wvarargs",
      "-Wvla",
      "-Wwrite-strings",
-@@ -96,8 +110,8 @@ ABSL_LLVM_FLAGS = [
+@@ -97,8 +111,8 @@ ABSL_LLVM_FLAGS = [
      "-Woverlength-strings",
      "-Wpointer-arith",
      "-Wself-assign",
@@ -117,7 +130,7 @@
      "-Wsign-conversion",
      "-Wstring-conversion",
      "-Wtautological-overlap-compare",
-@@ -115,6 +129,12 @@ ABSL_LLVM_FLAGS = [
+@@ -116,6 +130,12 @@ ABSL_LLVM_FLAGS = [
      "-Wno-implicit-int-float-conversion",
      "-Wno-unknown-warning-option",
      "-DNOMINMAX",
@@ -128,9 +141,9 @@
 +    "-Wno-shorten-64-to-32",
 +    "-Wno-stringop-overflow",
  ]
-
+ 
  ABSL_LLVM_TEST_FLAGS = [
-@@ -134,7 +154,7 @@ ABSL_LLVM_TEST_FLAGS = [
+@@ -135,7 +155,7 @@ ABSL_LLVM_TEST_FLAGS = [
      "-Woverlength-strings",
      "-Wpointer-arith",
      "-Wself-assign",
@@ -139,7 +152,7 @@
      "-Wstring-conversion",
      "-Wtautological-overlap-compare",
      "-Wtautological-unsigned-zero-compare",
-@@ -151,6 +171,12 @@ ABSL_LLVM_TEST_FLAGS = [
+@@ -152,6 +172,12 @@ ABSL_LLVM_TEST_FLAGS = [
      "-Wno-implicit-int-float-conversion",
      "-Wno-unknown-warning-option",
      "-DNOMINMAX",
@@ -152,8 +165,28 @@
      "-Wno-deprecated-declarations",
      "-Wno-implicit-int-conversion",
      "-Wno-missing-prototypes",
+diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl
+index ca5f26da..d9303c6b 100644
+--- a/absl/copts/configure_copts.bzl
++++ b/absl/copts/configure_copts.bzl
+@@ -46,13 +46,8 @@ ABSL_DEFAULT_LINKOPTS = select({
+ # environment to build an accelerated RandenHwAes library.
+ ABSL_RANDOM_RANDEN_COPTS = select({
+     # APPLE
+-    ":cpu_darwin_x86_64": ABSL_RANDOM_HWAES_X64_FLAGS,
+-    ":cpu_darwin": ABSL_RANDOM_HWAES_X64_FLAGS,
+-    ":cpu_x64_windows_msvc": ABSL_RANDOM_HWAES_MSVC_X64_FLAGS,
+-    ":cpu_x64_windows": ABSL_RANDOM_HWAES_MSVC_X64_FLAGS,
+-    ":cpu_k8": ABSL_RANDOM_HWAES_X64_FLAGS,
+-    ":cpu_ppc": ["-mcrypto"],
+-    ":cpu_aarch64": ABSL_RANDOM_HWAES_ARM64_FLAGS,
++    "@platforms//cpu:x86_64": ABSL_RANDOM_HWAES_X64_FLAGS,
++    "@platforms//cpu:aarch64": ABSL_RANDOM_HWAES_ARM64_FLAGS,
+ 
+     # Supported by default or unsupported.
+     "//conditions:default": [],
 diff --git a/absl/copts/copts.py b/absl/copts/copts.py
-index 06eeb67b..d2a3e74f 100644
+index e6e11949..ea3e9e9a 100644
 --- a/absl/copts/copts.py
 +++ b/absl/copts/copts.py
 @@ -23,6 +23,13 @@ ABSL_GCC_FLAGS = [
@@ -170,7 +203,7 @@
      "-Wvarargs",
      "-Wvla",  # variable-length array
      "-Wwrite-strings",
-@@ -56,8 +63,8 @@ ABSL_LLVM_FLAGS = [
+@@ -57,8 +64,8 @@ ABSL_LLVM_FLAGS = [
      "-Woverlength-strings",
      "-Wpointer-arith",
      "-Wself-assign",
@@ -180,7 +213,7 @@
      "-Wsign-conversion",
      "-Wstring-conversion",
      "-Wtautological-overlap-compare",
-@@ -80,6 +87,12 @@ ABSL_LLVM_FLAGS = [
+@@ -81,6 +88,12 @@ ABSL_LLVM_FLAGS = [
      "-Wno-unknown-warning-option",
      # Don't define min and max macros (Build on Windows using clang)
      "-DNOMINMAX",
@@ -191,13 +224,89 @@
 +    "-Wno-shorten-64-to-32",
 +    "-Wno-stringop-overflow",
  ]
-
+ 
  ABSL_LLVM_TEST_ADDITIONAL_FLAGS = [
+diff --git a/absl/log/internal/check_op.cc b/absl/log/internal/check_op.cc
+index f4b67647..09d65386 100644
+--- a/absl/log/internal/check_op.cc
++++ b/absl/log/internal/check_op.cc
+@@ -28,6 +28,17 @@
+ #include "absl/base/config.h"
+ #include "absl/strings/str_cat.h"
+ 
++namespace aos {
++void FatalUnsetRealtimePriority() __attribute__((weak));
++}
++
++static void MaybeUnsetRealtime() {
++  if (&aos::FatalUnsetRealtimePriority != nullptr) {
++    aos::FatalUnsetRealtimePriority();
++  }
++}
++
++
+ namespace absl {
+ ABSL_NAMESPACE_BEGIN
+ namespace log_internal {
+@@ -50,6 +61,7 @@ ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*);
+ #undef ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING
+ 
+ CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext) {
++  MaybeUnsetRealtime();
+   stream_ << exprtext << " (";
+ }
+ 
+diff --git a/absl/log/internal/log_message.cc b/absl/log/internal/log_message.cc
+index 10ac2453..30a4909c 100644
+--- a/absl/log/internal/log_message.cc
++++ b/absl/log/internal/log_message.cc
+@@ -60,6 +60,16 @@ extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
+   // Default - Do nothing
+ }
+ 
++namespace aos {
++void FatalUnsetRealtimePriority() __attribute__((weak));
++}
++
++static void MaybeUnsetRealtime() {
++  if (&aos::FatalUnsetRealtimePriority != nullptr) {
++    aos::FatalUnsetRealtimePriority();
++  }
++}
++
+ namespace absl {
+ ABSL_NAMESPACE_BEGIN
+ namespace log_internal {
+@@ -215,15 +225,21 @@ void LogMessage::LogMessageData::FinalizeEncodingAndFormat() {
+   }
+   auto chars_written =
+       static_cast<size_t>(string_remaining.data() - string_buf.data());
+-    string_buf[chars_written++] = '\n';
++  string_buf[chars_written++] = '\n';
+   string_buf[chars_written++] = '\0';
+   entry.text_message_with_prefix_and_newline_and_nul_ =
+       absl::MakeSpan(string_buf).subspan(0, chars_written);
+ }
+ 
+ LogMessage::LogMessage(const char* file, int line, absl::LogSeverity severity)
+-    : data_(absl::make_unique<LogMessageData>(file, line, severity,
+-                                              absl::Now())) {
++    : data_([&]() {
++        if (severity == absl::LogSeverity::kFatal &&
++            absl::log_internal::ExitOnDFatal()) {
++          MaybeUnsetRealtime();
++        }
++        return absl::make_unique<LogMessageData>(file, line, severity,
++                                                 absl::Now());
++      }()) {
+   data_->first_fatal = false;
+   data_->is_perror = false;
+   data_->fail_quietly = false;
 diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel
-index 81ca669b..e839860e 100644
+index 71a742ee..4809b2d0 100644
 --- a/absl/random/internal/BUILD.bazel
 +++ b/absl/random/internal/BUILD.bazel
-@@ -665,6 +665,7 @@ cc_test(
+@@ -692,6 +692,7 @@ cc_test(
  cc_library(
      name = "nanobenchmark",
      srcs = ["nanobenchmark.cc"],
@@ -206,10 +315,10 @@
      textual_hdrs = ["nanobenchmark.h"],
      deps = [
 diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
-index ed330f26..5f1c44b6 100644
+index 8e8371b3..b34d1487 100644
 --- a/absl/strings/BUILD.bazel
 +++ b/absl/strings/BUILD.bazel
-@@ -653,6 +653,7 @@ cc_test(
+@@ -788,6 +788,7 @@ cc_test(
      srcs = [
          "internal/cordz_info_statistics_test.cc",
      ],
@@ -218,13 +327,13 @@
          ":cord",
          ":cord_internal",
 diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel
-index edeabd81..49674f5f 100644
+index 0b43bb12..920c8b9c 100644
 --- a/absl/time/internal/cctz/BUILD.bazel
 +++ b/absl/time/internal/cctz/BUILD.bazel
-@@ -16,6 +16,13 @@ package(features = ["-parse_headers"])
-
+@@ -20,6 +20,13 @@ package(features = [
+ 
  licenses(["notice"])
-
+ 
 +load(
 +    "//absl:copts/configure_copts.bzl",
 +    "ABSL_DEFAULT_COPTS",
@@ -233,9 +342,9 @@
 +)
 +
  ### libraries
-
+ 
  cc_library(
-@@ -24,6 +31,8 @@ cc_library(
+@@ -28,6 +35,8 @@ cc_library(
      hdrs = [
          "include/cctz/civil_time.h",
      ],
@@ -244,23 +353,3 @@
      textual_hdrs = ["include/cctz/civil_time_detail.h"],
      visibility = ["//visibility:public"],
      deps = ["//absl/base:config"],
-diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl
-index ca5f26da..0b10dc0b 100644
---- a/absl/copts/configure_copts.bzl
-+++ b/absl/copts/configure_copts.bzl
-@@ -46,13 +46,8 @@ ABSL_DEFAULT_LINKOPTS = select({
- # environment to build an accelerated RandenHwAes library.
- ABSL_RANDOM_RANDEN_COPTS = select({
-     # APPLE
--    ":cpu_darwin_x86_64": ABSL_RANDOM_HWAES_X64_FLAGS,
--    ":cpu_darwin": ABSL_RANDOM_HWAES_X64_FLAGS,
--    ":cpu_x64_windows_msvc": ABSL_RANDOM_HWAES_MSVC_X64_FLAGS,
--    ":cpu_x64_windows": ABSL_RANDOM_HWAES_MSVC_X64_FLAGS,
--    ":cpu_k8": ABSL_RANDOM_HWAES_X64_FLAGS,
--    ":cpu_ppc": ["-mcrypto"],
--    ":cpu_aarch64": ABSL_RANDOM_HWAES_ARM64_FLAGS,
-+    "@platforms//cpu:x86_64": ABSL_RANDOM_HWAES_X64_FLAGS,
-+    "@platforms//cpu:aarch64": ABSL_RANDOM_HWAES_ARM64_FLAGS,
-
-     # Supported by default or unsupported.
-     "//conditions:default": [],
diff --git a/third_party/ceres.patch b/third_party/ceres.patch
index ce55b60..0bf8295 100644
--- a/third_party/ceres.patch
+++ b/third_party/ceres.patch
@@ -1,28 +1,7 @@
-diff -r -u a/bazel/ceres.bzl b/bazel/ceres.bzl
---- a/bazel/ceres.bzl	2024-06-25 18:35:28.266797366 -0700
-+++ b/bazel/ceres.bzl	2024-06-25 18:25:10.919515348 -0700
-@@ -189,6 +189,9 @@
-             "-I" + internal,
-             "-Wunused-parameter",
-             "-Wno-sign-compare",
-+            "-Wno-format-nonliteral",
-+            "-Wno-unused-parameter",
-+            "-Wno-unused-but-set-variable",
-         ] + schur_eliminator_copts,
- 
-         # These include directories and defines are propagated to other targets
-@@ -214,7 +217,7 @@
-         ],
-         visibility = ["//visibility:public"],
-         deps = [
--            "@com_gitlab_libeigen_eigen//:eigen",
-             "@com_github_google_glog//:glog",
-+            "@org_tuxfamily_eigen//:eigen",
-         ],
-     )
-diff -r -u a/BUILD b/BUILD
---- a/BUILD	2024-06-25 18:35:28.266797366 -0700
-+++ b/BUILD	2024-06-25 18:25:10.919515348 -0700
+diff --git a/BUILD b/BUILD
+index 652c4b17..9c7a799c 100644
+--- a/BUILD
++++ b/BUILD
 @@ -32,6 +32,7 @@
  # not support parameterization around threading choice or sparse backends.
  
@@ -31,15 +10,15 @@
  
  ceres_library(
      name = "ceres",
-@@ -57,6 +58,7 @@
-     ],
+@@ -48,6 +49,7 @@ cc_library(
+     ]],
      copts = [
          "-Wno-sign-compare",
 +        "-Wno-unused-but-set-variable",
          "-DCERES_TEST_SRCDIR_SUFFIX=\\\"data/\\\"",
      ],
      includes = [
-@@ -165,12 +167,16 @@
+@@ -158,12 +160,16 @@ TEST_COPTS = [
      # but in the future disable these warnings only for rotation_test.
      # TODO(keir): When the tests are macro-ified, apply these selectively.
      "-Wno-address",
@@ -55,12 +34,36 @@
      "//:test_util",
 -    "@com_gitlab_libeigen_eigen//:eigen",
 +    "@org_tuxfamily_eigen//:eigen",
-     "@com_github_gflags_gflags//:gflags",
+     "@com_google_absl//absl/flags:flag",
  ]
  
-diff -r -u a/examples/BUILD b/examples/BUILD
---- a/examples/BUILD	2024-06-25 18:35:28.270797439 -0700
-+++ b/examples/BUILD	2024-06-25 18:25:32.355906091 -0700
+diff --git a/bazel/ceres.bzl b/bazel/ceres.bzl
+index ed4d66d9..be8948d7 100644
+--- a/bazel/ceres.bzl
++++ b/bazel/ceres.bzl
+@@ -190,6 +190,9 @@ def ceres_library(
+             "-I" + internal,
+             "-Wunused-parameter",
+             "-Wno-sign-compare",
++            "-Wno-format-nonliteral",
++            "-Wno-unused-parameter",
++            "-Wno-unused-but-set-variable",
+         ] + schur_eliminator_copts,
+ 
+         # These include directories and defines are propagated to other targets
+@@ -215,7 +218,7 @@ def ceres_library(
+         ],
+         visibility = ["//visibility:public"],
+         deps = [
+-            "@com_gitlab_libeigen_eigen//:eigen",
++            "@org_tuxfamily_eigen//:eigen",
+             "@com_google_absl//absl/flags:flag",
+             "@com_google_absl//absl/log",
+             "@com_google_absl//absl/log:check",
+diff --git a/examples/BUILD b/examples/BUILD
+index e45fe318..6296417a 100644
+--- a/examples/BUILD
++++ b/examples/BUILD
 @@ -31,13 +31,14 @@
  EXAMPLE_COPTS = [
      # Needed to silence GFlags complaints.
@@ -74,13 +77,14 @@
      "//:ceres",
 -    "@com_gitlab_libeigen_eigen//:eigen",
 +    "@org_tuxfamily_eigen//:eigen",
-     "@com_github_gflags_gflags//:gflags",
- ]
- 
-diff -r -u a/internal/ceres/autodiff_test.cc b/internal/ceres/autodiff_test.cc
---- a/internal/ceres/autodiff_test.cc	2024-06-25 18:35:28.278797586 -0700
-+++ b/internal/ceres/autodiff_test.cc	2024-06-25 18:25:10.935515640 -0700
-@@ -647,6 +647,10 @@
+     "@com_google_absl//absl/flags:flag",
+     "@com_google_absl//absl/log:log",
+     "@com_google_absl//absl/log:check",
+diff --git a/internal/ceres/autodiff_test.cc b/internal/ceres/autodiff_test.cc
+index b50327cb..19adcae0 100644
+--- a/internal/ceres/autodiff_test.cc
++++ b/internal/ceres/autodiff_test.cc
+@@ -647,6 +647,10 @@ TEST(AutoDiff, VariadicAutoDiff) {
    }
  }
  
@@ -91,7 +95,7 @@
  // This is fragile test that triggers the alignment bug on
  // i686-apple-darwin10-llvm-g++-4.2 (GCC) 4.2.1. It is quite possible,
  // that other combinations of operating system + compiler will
-@@ -671,5 +675,8 @@
+@@ -671,5 +675,8 @@ TEST(AutoDiff, AlignedAllocationTest) {
    // Need this to makes sure that x does not get optimized out.
    x[0] = x[0] + JetT(1.0);
  }
@@ -100,10 +104,11 @@
 +#endif
  
  }  // namespace ceres::internal
-diff -r -u a/internal/ceres/bundle_adjustment_test_util.h b/internal/ceres/bundle_adjustment_test_util.h
---- a/internal/ceres/bundle_adjustment_test_util.h	2024-06-25 18:35:28.278797586 -0700
-+++ b/internal/ceres/bundle_adjustment_test_util.h	2024-06-25 18:32:23.019406091 -0700
-@@ -97,7 +97,8 @@
+diff --git a/internal/ceres/bundle_adjustment_test_util.h b/internal/ceres/bundle_adjustment_test_util.h
+index fb2ac719..993863a2 100644
+--- a/internal/ceres/bundle_adjustment_test_util.h
++++ b/internal/ceres/bundle_adjustment_test_util.h
+@@ -98,7 +98,8 @@ class BundleAdjustmentProblem {
  
   private:
    void ReadData(const std::string& filename) {
@@ -113,10 +118,11 @@
  
      if (!fptr) {
        LOG(FATAL) << "File Error: unable to open file " << filename;
-diff -r -u a/internal/ceres/triplet_sparse_matrix_test.cc b/internal/ceres/triplet_sparse_matrix_test.cc
---- a/internal/ceres/triplet_sparse_matrix_test.cc	2024-06-25 18:35:28.298797952 -0700
-+++ b/internal/ceres/triplet_sparse_matrix_test.cc	2024-06-25 18:25:10.963516152 -0700
-@@ -184,8 +184,15 @@
+diff --git a/internal/ceres/triplet_sparse_matrix_test.cc b/internal/ceres/triplet_sparse_matrix_test.cc
+index e145c1a2..bde9a6ed 100644
+--- a/internal/ceres/triplet_sparse_matrix_test.cc
++++ b/internal/ceres/triplet_sparse_matrix_test.cc
+@@ -184,8 +184,15 @@ TEST(TripletSparseMatrix, AssignmentOperatorSelfAssignment) {
    orig.mutable_values()[1] = 5.2;
    orig.set_num_nonzeros(2);
  
diff --git a/third_party/gflags/.gitattributes b/third_party/gflags/.gitattributes
deleted file mode 100644
index 87fe9c0..0000000
--- a/third_party/gflags/.gitattributes
+++ /dev/null
@@ -1,3 +0,0 @@
-# treat all files in this repository as text files
-# and normalize them to LF line endings when committed
-* text
diff --git a/third_party/gflags/.gitignore b/third_party/gflags/.gitignore
deleted file mode 100644
index 706f7f8..0000000
--- a/third_party/gflags/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-/xcode/
-/build/
-/builds/
-/build-*/
-/_build/
-.DS_Store
-CMakeCache.txt
-DartConfiguration.tcl
-Makefile
-CMakeFiles/
-/Testing/
-/include/gflags/config.h
-/include/gflags/gflags_completions.h
-/include/gflags/gflags_declare.h
-/include/gflags/gflags.h
-/lib/
-/test/gflags_unittest_main.cc
-/test/gflags_unittest-main.cc
-/packages/
-CMakeLists.txt.user
-/bazel-bin
-/bazel-genfiles
-/bazel-gflags
-/bazel-out
-/bazel-testlogs
diff --git a/third_party/gflags/.gitmodules b/third_party/gflags/.gitmodules
deleted file mode 100644
index aa2072c..0000000
--- a/third_party/gflags/.gitmodules
+++ /dev/null
@@ -1,4 +0,0 @@
-[submodule "doc"]
-	path = doc
-	url = https://github.com/gflags/gflags.git
-	branch = gh-pages
diff --git a/third_party/gflags/.travis.yml b/third_party/gflags/.travis.yml
deleted file mode 100644
index 0989c7c..0000000
--- a/third_party/gflags/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# Ubuntu 14.04 Trusty support, to get newer cmake and compilers.
-sudo: required
-dist: trusty
-
-language: cpp
-
-os:
-  - linux
-  - osx
-
-compiler:
-  - clang
-  - gcc
-
-env:
-  - CONFIG=Release
-  - CONFIG=Debug
-
-script:
-  - mkdir out && cd out && cmake -D CMAKE_BUILD_TYPE=$CONFIG -D GFLAGS_BUILD_SHARED_LIBS=ON -D GFLAGS_BUILD_STATIC_LIBS=ON -D GFLAGS_BUILD_TESTING=ON .. && cmake --build . --config $CONFIG && ctest
diff --git a/third_party/gflags/AUTHORS.txt b/third_party/gflags/AUTHORS.txt
deleted file mode 100644
index 887918b..0000000
--- a/third_party/gflags/AUTHORS.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-google-gflags@googlegroups.com
-
diff --git a/third_party/gflags/BUILD b/third_party/gflags/BUILD
deleted file mode 100644
index 1bccf5a..0000000
--- a/third_party/gflags/BUILD
+++ /dev/null
@@ -1,34 +0,0 @@
-# Bazel (http://bazel.io/) BUILD file for gflags.
-#
-# See INSTALL.md for instructions for adding gflags to a Bazel workspace.
-
-licenses(["notice"])
-
-exports_files([
-    "src/gflags_completions.sh",
-    "COPYING.txt",
-])
-
-config_setting(
-    name = "x64_windows",
-    values = {"cpu": "x64_windows"},
-)
-
-load(":bazel/gflags.bzl", "gflags_library", "gflags_sources")
-
-(hdrs, srcs) = gflags_sources(namespace = [
-    "gflags",
-    "google",
-])
-
-gflags_library(
-    srcs = srcs,
-    hdrs = hdrs,
-    threads = 0,
-)
-
-gflags_library(
-    srcs = srcs,
-    hdrs = hdrs,
-    threads = 1,
-)
diff --git a/third_party/gflags/CMakeLists.txt b/third_party/gflags/CMakeLists.txt
deleted file mode 100644
index 9dec647..0000000
--- a/third_party/gflags/CMakeLists.txt
+++ /dev/null
@@ -1,741 +0,0 @@
-## CMake configuration file of gflags project
-##
-## This CMakeLists.txt defines some gflags specific configuration variables
-## using the "gflags_define" utility macro. The default values of these variables
-## can be overridden either on the CMake command-line using the -D option of
-## the cmake command or in a super-project which includes the gflags source
-## tree by setting the GFLAGS_<varname> CMake variables before adding the
-## gflags source directory via CMake's "add_subdirectory" command. Only when
-## the non-cached variable GFLAGS_IS_SUBPROJECT has a value equivalent to FALSE,
-## these configuration variables are added to the CMake cache so they can be
-## edited in the CMake GUI. By default, GFLAGS_IS_SUBPROJECT is set to TRUE when
-## the CMAKE_SOURCE_DIR is not identical to the directory of this CMakeLists.txt
-## file, i.e., the top-level directory of the gflags project source tree.
-##
-## When this project is a subproject (GFLAGS_IS_SUBPROJECT is TRUE), the default
-## settings are such that only the static single-threaded library is built without
-## installation of the gflags files. The "gflags::gflags" target is in this case an ALIAS
-## library target for the "gflags_nothreads_static" library target. Targets which
-## depend on the gflags library should link to the "gflags::gflags" library target.
-##
-## Example CMakeLists.txt of user project which requires separate gflags installation:
-##   cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
-##
-##   project(Foo)
-##
-##   find_package(gflags REQUIRED)
-##
-##   add_executable(foo src/foo.cc)
-##   target_link_libraries(foo gflags::gflags)
-##
-## Example CMakeLists.txt of user project which requires separate single-threaded static gflags installation:
-##   cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
-##
-##   project(Foo)
-##
-##   find_package(gflags COMPONENTS nothreads_static)
-##
-##   add_executable(foo src/foo.cc)
-##   target_link_libraries(foo gflags::gflags)
-##
-## Example CMakeLists.txt of super-project which contains gflags source tree:
-##   cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
-##
-##   project(Foo)
-##
-##   add_subdirectory(gflags)
-##
-##   add_executable(foo src/foo.cc)
-##   target_link_libraries(foo gflags::gflags)
-##
-## Variables to configure the source files:
-## - GFLAGS_IS_A_DLL
-## - GFLAGS_NAMESPACE
-## - GFLAGS_ATTRIBUTE_UNUSED
-## - GFLAGS_INTTYPES_FORMAT
-##
-## Variables to configure the build:
-## - GFLAGS_SOVERSION
-## - GFLAGS_BUILD_SHARED_LIBS
-## - GFLAGS_BUILD_STATIC_LIBS
-## - GFLAGS_BUILD_gflags_LIB
-## - GFLAGS_BUILD_gflags_nothreads_LIB
-## - GFLAGS_BUILD_TESTING
-## - GFLAGS_BUILD_PACKAGING
-##
-## Variables to configure the installation:
-## - GFLAGS_INCLUDE_DIR
-## - GFLAGS_LIBRARY_INSTALL_DIR or LIB_INSTALL_DIR or LIB_SUFFIX
-## - GFLAGS_INSTALL_HEADERS
-## - GFLAGS_INSTALL_SHARED_LIBS
-## - GFLAGS_INSTALL_STATIC_LIBS
-
-cmake_minimum_required (VERSION 3.0.2 FATAL_ERROR)
-
-if (POLICY CMP0042)
-  cmake_policy (SET CMP0042 NEW)
-endif ()
-
-if (POLICY CMP0048)
-  cmake_policy (SET CMP0048 NEW)
-endif ()
-
-# ----------------------------------------------------------------------------
-# includes
-include ("${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake")
-
-# ----------------------------------------------------------------------------
-# package information
-set (PACKAGE_NAME        "gflags")
-set (PACKAGE_VERSION     "2.2.1")
-set (PACKAGE_STRING      "${PACKAGE_NAME} ${PACKAGE_VERSION}")
-set (PACKAGE_TARNAME     "${PACKAGE_NAME}-${PACKAGE_VERSION}")
-set (PACKAGE_BUGREPORT   "https://github.com/gflags/gflags/issues")
-set (PACKAGE_DESCRIPTION "A commandline flags library that allows for distributed flags.")
-set (PACKAGE_URL         "http://gflags.github.io/gflags")
-
-project (${PACKAGE_NAME} VERSION ${PACKAGE_VERSION} LANGUAGES CXX)
-if (CMAKE_VERSION VERSION_LESS 3.4)
-  # C language still needed because the following required CMake modules
-  # (or their dependencies, respectively) are not correctly handling
-  # the case where only CXX is enabled
-  # - CheckTypeSize.cmake (fixed in CMake 3.1, cf. https://cmake.org/Bug/view.php?id=14056)
-  # - FindThreads.cmake   (fixed in CMake 3.4, cf. https://cmake.org/Bug/view.php?id=14905)
-  enable_language (C)
-endif ()
-
-version_numbers (
-  ${PACKAGE_VERSION}
-    PACKAGE_VERSION_MAJOR
-    PACKAGE_VERSION_MINOR
-    PACKAGE_VERSION_PATCH
-)
-
-# shared library ABI version number, can be overridden by package maintainers
-# using -DGFLAGS_SOVERSION=XXX on the command-line
-if (GFLAGS_SOVERSION)
-  set (PACKAGE_SOVERSION "${GFLAGS_SOVERSION}")
-else ()
-  # TODO: Change default SOVERSION back to PACKAGE_VERSION_MAJOR with the
-  #       next increase of major version number (i.e., 3.0.0 -> SOVERSION 3)
-  #       The <major>.<minor> SOVERSION should be used for the 2.x releases
-  #       versions only which temporarily broke the API by changing the default
-  #       namespace from "google" to "gflags".
-  set (PACKAGE_SOVERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}")
-endif ()
-
-# when gflags is included as subproject (e.g., as Git submodule/subtree) in the source
-# tree of a project that uses it, no variables should be added to the CMake cache;
-# users may set the non-cached variable GFLAGS_IS_SUBPROJECT before add_subdirectory(gflags)
-if (NOT DEFINED GFLAGS_IS_SUBPROJECT)
-  if ("^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$")
-    set (GFLAGS_IS_SUBPROJECT FALSE)
-  else ()
-    set (GFLAGS_IS_SUBPROJECT TRUE)
-  endif ()
-endif ()
-
-# prefix for package variables in CMake configuration file
-string (TOUPPER "${PACKAGE_NAME}" PACKAGE_PREFIX)
-
-# convert file path on Windows with back slashes to path with forward slashes
-# otherwise this causes an issue with the cmake_install.cmake script
-file (TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX)
-
-# ----------------------------------------------------------------------------
-# options
-
-# maintain binary backwards compatibility with gflags library version <= 2.0,
-# but at the same time enable the use of the preferred new "gflags" namespace
-gflags_define (STRING NAMESPACE "Name(s) of library namespace (separate multiple options by semicolon)" "google;${PACKAGE_NAME}" "${PACKAGE_NAME}")
-gflags_property (NAMESPACE ADVANCED TRUE)
-set (GFLAGS_NAMESPACE_SECONDARY "${NAMESPACE}")
-list (REMOVE_DUPLICATES GFLAGS_NAMESPACE_SECONDARY)
-if (NOT GFLAGS_NAMESPACE_SECONDARY)
-  message (FATAL_ERROR "GFLAGS_NAMESPACE must be set to one (or more) valid C++ namespace identifier(s separated by semicolon \";\").")
-endif ()
-foreach (ns IN LISTS GFLAGS_NAMESPACE_SECONDARY)
-  if (NOT ns MATCHES "^[a-zA-Z][a-zA-Z0-9_]*$")
-    message (FATAL_ERROR "GFLAGS_NAMESPACE contains invalid namespace identifier: ${ns}")
-  endif ()
-endforeach ()
-list (GET       GFLAGS_NAMESPACE_SECONDARY 0 GFLAGS_NAMESPACE)
-list (REMOVE_AT GFLAGS_NAMESPACE_SECONDARY 0)
-
-# cached build options when gflags is not a subproject, otherwise non-cached CMake variables
-# usage: gflags_define(BOOL <name> <doc> <default> [<subproject default>])
-gflags_define (BOOL BUILD_SHARED_LIBS          "Request build of shared libraries."                                       OFF OFF)
-gflags_define (BOOL BUILD_STATIC_LIBS          "Request build of static libraries (default if BUILD_SHARED_LIBS is OFF)." OFF ON)
-gflags_define (BOOL BUILD_gflags_LIB           "Request build of the multi-threaded gflags library."                      ON  OFF)
-gflags_define (BOOL BUILD_gflags_nothreads_LIB "Request build of the single-threaded gflags library."                     ON  ON)
-gflags_define (BOOL BUILD_PACKAGING            "Enable build of distribution packages using CPack."                       OFF OFF)
-gflags_define (BOOL BUILD_TESTING              "Enable build of the unit tests and their execution using CTest."          OFF OFF)
-gflags_define (BOOL INSTALL_HEADERS            "Request installation of headers and other development files."             ON  OFF)
-gflags_define (BOOL INSTALL_SHARED_LIBS        "Request installation of shared libraries."                                ON  ON)
-gflags_define (BOOL INSTALL_STATIC_LIBS        "Request installation of static libraries."                                ON  OFF)
-gflags_define (BOOL REGISTER_BUILD_DIR         "Request entry of build directory in CMake's package registry."            OFF OFF)
-gflags_define (BOOL REGISTER_INSTALL_PREFIX    "Request entry of installed package in CMake's package registry."          ON  OFF)
-
-gflags_property (BUILD_STATIC_LIBS   ADVANCED TRUE)
-gflags_property (INSTALL_HEADERS     ADVANCED TRUE)
-gflags_property (INSTALL_SHARED_LIBS ADVANCED TRUE)
-gflags_property (INSTALL_STATIC_LIBS ADVANCED TRUE)
-
-if (NOT GFLAGS_IS_SUBPROJECT)
-  foreach (varname IN ITEMS CMAKE_INSTALL_PREFIX)
-    gflags_property (${varname} ADVANCED FALSE)
-  endforeach ()
-  foreach (varname IN ITEMS CMAKE_CONFIGURATION_TYPES CMAKE_OSX_ARCHITECTURES CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT)
-    gflags_property (${varname} ADVANCED TRUE)
-  endforeach ()
-  if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)
-    gflags_set (CMAKE_BUILD_TYPE Release)
-  endif ()
-  if (CMAKE_CONFIGURATION_TYPES)
-    gflags_property (CMAKE_BUILD_TYPE STRINGS "${CMAKE_CONFIGURATION_TYPES}")
-  endif ()
-endif () # NOT GFLAGS_IS_SUBPROJECT
-
-if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
-  set (BUILD_STATIC_LIBS ON)
-endif ()
-if (NOT BUILD_gflags_LIB AND NOT BUILD_gflags_nothreads_LIB)
-  message (FATAL_ERROR "At least one of [GFLAGS_]BUILD_gflags_LIB and [GFLAGS_]BUILD_gflags_nothreads_LIB must be ON.")
-endif ()
-
-gflags_define (STRING INCLUDE_DIR "Name of include directory of installed header files relative to CMAKE_INSTALL_PREFIX/include/" "${PACKAGE_NAME}")
-gflags_property (INCLUDE_DIR ADVANCED TRUE)
-file (TO_CMAKE_PATH "${INCLUDE_DIR}" INCLUDE_DIR)
-if (IS_ABSOLUTE INCLUDE_DIR)
-  message (FATAL_ERROR "[GFLAGS_]INCLUDE_DIR must be a path relative to CMAKE_INSTALL_PREFIX/include/")
-endif ()
-if (INCLUDE_DIR MATCHES "^\\.\\.[/\\]")
-  message (FATAL_ERROR "[GFLAGS_]INCLUDE_DIR must not start with parent directory reference (../)")
-endif ()
-set (GFLAGS_INCLUDE_DIR "${INCLUDE_DIR}")
-
-# ----------------------------------------------------------------------------
-# system checks
-include (CheckTypeSize)
-include (CheckIncludeFileCXX)
-include (CheckCXXSymbolExists)
-
-if (WIN32 AND NOT CYGWIN)
-  set (OS_WINDOWS 1)
-else ()
-  set (OS_WINDOWS 0)
-endif ()
-
-if (MSVC)
-  set (HAVE_SYS_TYPES_H 1)
-  set (HAVE_STDDEF_H    1) # used by CheckTypeSize module
-  set (HAVE_UNISTD_H    0)
-  set (HAVE_SYS_STAT_H  1)
-  set (HAVE_SHLWAPI_H   1)
-  if (MSVC_VERSION VERSION_LESS 1600)
-    check_include_file_cxx ("stdint.h" HAVE_STDINT_H)
-    bool_to_int (HAVE_STDINT_H)  # used in #if directive
-  else ()
-    set (HAVE_STDINT_H 1)
-  endif ()
-  if (MSVC_VERSION VERSION_LESS 1800)
-    check_include_file_cxx ("inttypes.h" HAVE_INTTYPES_H)
-    bool_to_int (HAVE_INTTYPES_H)  # used in #if directive
-  else ()
-    set (HAVE_INTTYPES_H 1)
-  endif ()
-else ()
-  foreach (fname IN ITEMS unistd stdint inttypes sys/types sys/stat fnmatch)
-    string (TOUPPER "${fname}" FNAME)
-    string (REPLACE "/" "_" FNAME "${FNAME}")
-    if (NOT HAVE_${FNAME}_H)
-      check_include_file_cxx ("${fname}.h" HAVE_${FNAME}_H)
-    endif ()
-  endforeach ()
-  if (NOT HAVE_FNMATCH_H AND OS_WINDOWS)
-    check_include_file_cxx ("shlwapi.h" HAVE_SHLWAPI_H)
-  endif ()
-  # the following are used in #if directives not #ifdef
-  bool_to_int (HAVE_STDINT_H)
-  bool_to_int (HAVE_SYS_TYPES_H)
-  bool_to_int (HAVE_INTTYPES_H)
-endif ()
-
-gflags_define (STRING INTTYPES_FORMAT "Format of integer types: \"C99\" (uint32_t), \"BSD\" (u_int32_t), \"VC7\" (__int32)" "")
-gflags_property (INTTYPES_FORMAT STRINGS "C99;BSD;VC7")
-gflags_property (INTTYPES_FORMAT ADVANCED TRUE)
-if (NOT INTTYPES_FORMAT)
-  set (TYPES uint32_t u_int32_t)
-  if (MSVC)
-    list (INSERT TYPES 0 __int32)
-  endif ()
-  foreach (type IN LISTS TYPES)
-    check_type_size (${type} ${type} LANGUAGE CXX)
-    if (HAVE_${type})
-      break ()
-    endif ()
-  endforeach ()
-  if (HAVE_uint32_t)
-    gflags_set (INTTYPES_FORMAT C99)
-  elseif (HAVE_u_int32_t)
-    gflags_set (INTTYPES_FORMAT BSD)
-  elseif (HAVE___int32)
-    gflags_set (INTTYPES_FORMAT VC7)
-  else ()
-    gflags_property (INTTYPES_FORMAT ADVANCED FALSE)
-    message (FATAL_ERROR "Do not know how to define a 32-bit integer quantity on your system!"
-                         " Neither uint32_t, u_int32_t, nor __int32 seem to be available."
-                         " Set [GFLAGS_]INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.")
-  endif ()
-endif ()
-# use of special characters in strings to circumvent bug #0008226
-if ("^${INTTYPES_FORMAT}$" STREQUAL "^WIN$")
-  gflags_set (INTTYPES_FORMAT VC7)
-endif ()
-if (NOT INTTYPES_FORMAT MATCHES "^(C99|BSD|VC7)$")
-  message (FATAL_ERROR "Invalid value for [GFLAGS_]INTTYPES_FORMAT! Choose one of \"C99\", \"BSD\", or \"VC7\"")
-endif ()
-set (GFLAGS_INTTYPES_FORMAT "${INTTYPES_FORMAT}")
-set (GFLAGS_INTTYPES_FORMAT_C99 0)
-set (GFLAGS_INTTYPES_FORMAT_BSD 0)
-set (GFLAGS_INTTYPES_FORMAT_VC7 0)
-set ("GFLAGS_INTTYPES_FORMAT_${INTTYPES_FORMAT}" 1)
-
-if (MSVC)
-  set (HAVE_strtoll 0)
-  set (HAVE_strtoq  0)
-else ()
-  check_cxx_symbol_exists (strtoll stdlib.h HAVE_STRTOLL)
-  if (NOT HAVE_STRTOLL)
-    check_cxx_symbol_exists (strtoq stdlib.h HAVE_STRTOQ)
-  endif ()
-endif ()
-
-if (BUILD_gflags_LIB)
-  set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
-  find_package (Threads)
-  if (Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
-    set (HAVE_PTHREAD 1)
-    check_type_size (pthread_rwlock_t RWLOCK LANGUAGE CXX)
-  else ()
-    set (HAVE_PTHREAD 0)
-  endif ()
-  if (UNIX AND NOT HAVE_PTHREAD)
-    if (CMAKE_HAVE_PTHREAD_H)
-      set (what "library")
-    else ()
-      set (what ".h file")
-    endif ()
-    message (FATAL_ERROR "Could not find pthread${what}. Check the log file"
-                         "\n\t${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
-                         "\nor disable the build of the multi-threaded gflags library (BUILD_gflags_LIB=OFF).")
-  endif ()
-else ()
-  set (HAVE_PTHREAD 0)
-endif ()
-
-# ----------------------------------------------------------------------------
-# source files - excluding root subdirectory and/or .in suffix
-set (PUBLIC_HDRS
-  "gflags.h"
-  "gflags_declare.h"
-  "gflags_completions.h"
-)
-
-if (GFLAGS_NAMESPACE_SECONDARY)
-  set (INCLUDE_GFLAGS_NS_H "// Import gflags library symbols into alternative/deprecated namespace(s)")
-  foreach (ns IN LISTS GFLAGS_NAMESPACE_SECONDARY)
-    string (TOUPPER "${ns}" NS)
-    set (gflags_ns_h "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/gflags_${ns}.h")
-    configure_file ("${PROJECT_SOURCE_DIR}/src/gflags_ns.h.in" "${gflags_ns_h}" @ONLY)
-    list (APPEND PUBLIC_HDRS "${gflags_ns_h}")
-    set (INCLUDE_GFLAGS_NS_H "${INCLUDE_GFLAGS_NS_H}\n#include \"gflags_${ns}.h\"")
-  endforeach ()
-else ()
-  set (INCLUDE_GFLAGS_NS_H)
-endif ()
-
-set (PRIVATE_HDRS
-  "defines.h"
-  "config.h"
-  "util.h"
-  "mutex.h"
-)
-
-set (GFLAGS_SRCS
-  "gflags.cc"
-  "gflags_reporting.cc"
-  "gflags_completions.cc"
-)
-
-if (OS_WINDOWS)
-  list (APPEND PRIVATE_HDRS "windows_port.h")
-  list (APPEND GFLAGS_SRCS  "windows_port.cc")
-endif ()
-
-# ----------------------------------------------------------------------------
-# configure source files
-if (NOT DEFINED GFLAGS_ATTRIBUTE_UNUSED)
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    set (GFLAGS_ATTRIBUTE_UNUSED "__attribute((unused))")
-  else ()
-    set (GFLAGS_ATTRIBUTE_UNUSED)
-  endif ()
-endif ()
-
-# whenever we build a shared library (DLL on Windows), configure the public
-# headers of the API for use of this shared library rather than the optionally
-# also build statically linked library; users can override GFLAGS_DLL_DECL
-# in particular, this done by setting the INTERFACE_COMPILE_DEFINITIONS of
-# static libraries to include an empty definition for GFLAGS_DLL_DECL
-if (NOT DEFINED GFLAGS_IS_A_DLL)
-  if (BUILD_SHARED_LIBS)
-    set (GFLAGS_IS_A_DLL 1)
-  else ()
-    set (GFLAGS_IS_A_DLL 0)
-  endif ()
-endif ()
-
-configure_headers (PUBLIC_HDRS  ${PUBLIC_HDRS})
-configure_sources (PRIVATE_HDRS ${PRIVATE_HDRS})
-configure_sources (GFLAGS_SRCS  ${GFLAGS_SRCS})
-
-# ----------------------------------------------------------------------------
-# output directories
-if (NOT GFLAGS_IS_SUBPROJECT)
-  set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin")
-  set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
-  set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "lib")
-endif ()
-# Set postfixes for generated libraries based on buildtype.
-set(CMAKE_RELEASE_POSTFIX "")
-set(CMAKE_DEBUG_POSTFIX "_debug")
-
-# ----------------------------------------------------------------------------
-# installation directories
-if (OS_WINDOWS)
-  set (RUNTIME_INSTALL_DIR "bin")
-  set (LIBRARY_INSTALL_DIR "lib")
-  set (INCLUDE_INSTALL_DIR "include")
-  set (CONFIG_INSTALL_DIR  "lib/cmake/${PACKAGE_NAME}")
-  set (PKGCONFIG_INSTALL_DIR)
-else ()
-  set (RUNTIME_INSTALL_DIR bin)
-  # The LIB_INSTALL_DIR and LIB_SUFFIX variables are used by the Fedora
-  # package maintainers. Also package maintainers of other distribution
-  # packages need to be able to specify the name of the library directory.
-  if (NOT GFLAGS_LIBRARY_INSTALL_DIR AND LIB_INSTALL_DIR)
-    set (GFLAGS_LIBRARY_INSTALL_DIR "${LIB_INSTALL_DIR}")
-  endif ()
-  gflags_define (PATH LIBRARY_INSTALL_DIR "Directory of installed libraries, e.g., \"lib64\"" "lib${LIB_SUFFIX}")
-  gflags_property (LIBRARY_INSTALL_DIR ADVANCED TRUE)
-  set (INCLUDE_INSTALL_DIR include)
-  set (CONFIG_INSTALL_DIR  ${LIBRARY_INSTALL_DIR}/cmake/${PACKAGE_NAME})
-  set (PKGCONFIG_INSTALL_DIR ${LIBRARY_INSTALL_DIR}/pkgconfig)
-endif ()
-
-# ----------------------------------------------------------------------------
-# add library targets
-set (TARGETS)
-# static vs. shared
-foreach (TYPE IN ITEMS STATIC SHARED)
-  if (BUILD_${TYPE}_LIBS)
-    string (TOLOWER "${TYPE}" type)
-    # whether or not targets are a DLL
-    if (OS_WINDOWS AND "^${TYPE}$" STREQUAL "^SHARED$")
-      set (GFLAGS_IS_A_DLL 1)
-    else ()
-      set (GFLAGS_IS_A_DLL 0)
-    endif ()
-    # filename suffix for static libraries on Windows
-    if (OS_WINDOWS AND "^${TYPE}$" STREQUAL "^STATIC$")
-      set (type_suffix "_${type}")
-    else ()
-      set (type_suffix "")
-    endif ()
-    # multi-threaded vs. single-threaded
-    foreach (opts IN ITEMS "" _nothreads)
-      if (BUILD_gflags${opts}_LIB)
-        set (target_name "gflags${opts}_${type}")
-        add_library (${target_name} ${TYPE} ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
-        set_target_properties (${target_name} PROPERTIES
-          OUTPUT_NAME "gflags${opts}${type_suffix}"
-          VERSION     "${PACKAGE_VERSION}"
-          SOVERSION   "${PACKAGE_SOVERSION}"
-        )
-        set (include_dirs "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>")
-        if (INSTALL_HEADERS)
-          list (APPEND include_dirs "$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>")
-        endif ()
-        target_include_directories (${target_name}
-          PUBLIC  "${include_dirs}"
-          PRIVATE "${PROJECT_SOURCE_DIR}/src;${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}"
-        )
-        target_compile_definitions (${target_name} PUBLIC GFLAGS_IS_A_DLL=${GFLAGS_IS_A_DLL})
-        if (opts MATCHES "nothreads")
-          target_compile_definitions (${target_name} PRIVATE NO_THREADS)
-        elseif (CMAKE_USE_PTHREADS_INIT)
-          target_link_libraries (${target_name} ${CMAKE_THREAD_LIBS_INIT})
-        endif ()
-        if (HAVE_SHLWAPI_H)
-          target_link_libraries (${target_name} shlwapi.lib)
-        endif ()
-        list (APPEND TARGETS ${target_name})
-        # add convenience make target for build of both shared and static libraries
-        if (NOT GFLAGS_IS_SUBPROJECT)
-          if (NOT TARGET gflags${opts})
-            add_custom_target (gflags${opts})
-          endif ()
-          add_dependencies (gflags${opts} ${target_name})
-        endif ()
-      endif ()
-    endforeach ()
-  endif ()
-endforeach ()
-
-# add ALIAS target for use in super-project, prefer static over shared, single-threaded over multi-threaded
-if (GFLAGS_IS_SUBPROJECT)
-  foreach (type IN ITEMS static shared)
-    foreach (opts IN ITEMS "_nothreads" "")
-      if (TARGET gflags${opts}_${type})
-        # Define "gflags" alias for super-projects treating targets of this library as part of their own project
-        # (also for backwards compatibility with gflags 2.2.1 which only defined this alias)
-        add_library (gflags ALIAS gflags${opts}_${type})
-        # Define "gflags::gflags" alias for projects that support both find_package(gflags) and add_subdirectory(gflags)
-        add_library (gflags::gflags ALIAS gflags${opts}_${type})
-        break ()
-      endif ()
-    endforeach ()
-    if (TARGET gflags::gflags)
-       break ()
-    endif ()
-  endforeach ()
-endif ()
-
-# ----------------------------------------------------------------------------
-# installation rules
-set (EXPORT_NAME ${PACKAGE_NAME}-targets)
-file (RELATIVE_PATH INSTALL_PREFIX_REL2CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_INSTALL_DIR}" "${CMAKE_INSTALL_PREFIX}")
-configure_file (cmake/config.cmake.in  "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-install.cmake" @ONLY)
-configure_file (cmake/version.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake" @ONLY)
-
-if (BUILD_SHARED_LIBS AND INSTALL_SHARED_LIBS)
-  foreach (opts IN ITEMS "" _nothreads)
-    if (BUILD_gflags${opts}_LIB)
-      install (TARGETS gflags${opts}_shared
-               EXPORT ${EXPORT_NAME}
-               RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
-               LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
-               ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
-      )
-    endif ()
-  endforeach ()
-endif ()
-if (BUILD_STATIC_LIBS AND INSTALL_STATIC_LIBS)
-  foreach (opts IN ITEMS "" _nothreads)
-    if (BUILD_gflags${opts}_LIB)
-      install (TARGETS gflags${opts}_static
-               EXPORT ${EXPORT_NAME}
-               RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
-               LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
-               ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR}
-      )
-    endif ()
-  endforeach ()
-endif ()
-
-if (INSTALL_HEADERS)
-  install (FILES ${PUBLIC_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/${GFLAGS_INCLUDE_DIR})
-  install (
-    FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-install.cmake"
-    RENAME ${PACKAGE_NAME}-config.cmake
-    DESTINATION ${CONFIG_INSTALL_DIR}
-  )
-  install (
-    FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake"
-    DESTINATION ${CONFIG_INSTALL_DIR}
-  )
-  install (
-    EXPORT ${EXPORT_NAME}
-    NAMESPACE ${PACKAGE_NAME}::
-    DESTINATION ${CONFIG_INSTALL_DIR}
-  )
-  install (
-    EXPORT ${EXPORT_NAME}
-    FILE ${PACKAGE_NAME}-nonamespace-targets.cmake
-    DESTINATION ${CONFIG_INSTALL_DIR}
-  )
-  if (UNIX)
-    install (PROGRAMS src/gflags_completions.sh DESTINATION ${RUNTIME_INSTALL_DIR})
-  endif ()
-endif ()
-
-if (PKGCONFIG_INSTALL_DIR)
-  configure_file ("cmake/package.pc.in" "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}.pc" @ONLY)
-  install (FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}.pc" DESTINATION "${PKGCONFIG_INSTALL_DIR}")
-endif ()
-
-# ----------------------------------------------------------------------------
-# support direct use of build tree
-set (INSTALL_PREFIX_REL2CONFIG_DIR .)
-export (
-  TARGETS ${TARGETS}
-  NAMESPACE ${PACKAGE_NAME}::
-  FILE "${PROJECT_BINARY_DIR}/${EXPORT_NAME}.cmake"
-)
-export (
-  TARGETS ${TARGETS}
-  FILE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-nonamespace-targets.cmake"
-)
-if (REGISTER_BUILD_DIR)
-  export (PACKAGE ${PACKAGE_NAME})
-endif ()
-if (REGISTER_INSTALL_PREFIX)
-  register_gflags_package(${CONFIG_INSTALL_DIR})
-endif ()
-configure_file (cmake/config.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake" @ONLY)
-
-# ----------------------------------------------------------------------------
-# testing - MUST follow the generation of the build tree config file
-if (BUILD_TESTING)
-  include (CTest)
-  add_subdirectory (test)
-endif ()
-
-# ----------------------------------------------------------------------------
-# packaging
-if (BUILD_PACKAGING)
-
-  if (NOT BUILD_SHARED_LIBS AND NOT INSTALL_HEADERS)
-    message (WARNING "Package will contain static libraries without headers!"
-                     "\nRecommended options for generation of runtime package:"
-                     "\n  BUILD_SHARED_LIBS=ON"
-                     "\n  BUILD_STATIC_LIBS=OFF"
-                     "\n  INSTALL_HEADERS=OFF"
-                     "\n  INSTALL_SHARED_LIBS=ON"
-                     "\nRecommended options for generation of development package:"
-                     "\n  BUILD_SHARED_LIBS=ON"
-                     "\n  BUILD_STATIC_LIBS=ON"
-                     "\n  INSTALL_HEADERS=ON"
-                     "\n  INSTALL_SHARED_LIBS=ON"
-                     "\n  INSTALL_STATIC_LIBS=ON"
-    )
-  endif ()
-
-  # default package generators
-  if (APPLE)
-    set (PACKAGE_GENERATOR        "PackageMaker")
-    set (PACKAGE_SOURCE_GENERATOR "TGZ;ZIP")
-  elseif (UNIX)
-    set (PACKAGE_GENERATOR        "DEB;RPM")
-    set (PACKAGE_SOURCE_GENERATOR "TGZ;ZIP")
-  else ()
-    set (PACKAGE_GENERATOR        "ZIP")
-    set (PACKAGE_SOURCE_GENERATOR "ZIP")
-  endif ()
-
-  # used package generators
-  set (CPACK_GENERATOR        "${PACKAGE_GENERATOR}"        CACHE STRING "List of binary package generators (CPack).")
-  set (CPACK_SOURCE_GENERATOR "${PACKAGE_SOURCE_GENERATOR}" CACHE STRING "List of source package generators (CPack).")
-  mark_as_advanced (CPACK_GENERATOR CPACK_SOURCE_GENERATOR)
-
-  # some package generators (e.g., PackageMaker) do not allow .md extension
-  configure_file ("${CMAKE_CURRENT_LIST_DIR}/README.md" "${CMAKE_CURRENT_BINARY_DIR}/README.txt" COPYONLY)
-
-  # common package information
-  set (CPACK_PACKAGE_VENDOR              "Andreas Schuh")
-  set (CPACK_PACKAGE_CONTACT             "google-gflags@googlegroups.com")
-  set (CPACK_PACKAGE_NAME                "${PACKAGE_NAME}")
-  set (CPACK_PACKAGE_VERSION             "${PACKAGE_VERSION}")
-  set (CPACK_PACKAGE_VERSION_MAJOR       "${PACKAGE_VERSION_MAJOR}")
-  set (CPACK_PACKAGE_VERSION_MINOR       "${PACKAGE_VERSION_MINOR}")
-  set (CPACK_PACKAGE_VERSION_PATCH       "${PACKAGE_VERSION_PATCH}")
-  set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE_DESCRIPTION}")
-  set (CPACK_RESOURCE_FILE_WELCOME       "${CMAKE_CURRENT_BINARY_DIR}/README.txt")
-  set (CPACK_RESOURCE_FILE_LICENSE       "${CMAKE_CURRENT_LIST_DIR}/COPYING.txt")
-  set (CPACK_PACKAGE_DESCRIPTION_FILE    "${CMAKE_CURRENT_BINARY_DIR}/README.txt")
-  set (CPACK_INSTALL_PREFIX              "${CMAKE_INSTALL_PREFIX}")
-  set (CPACK_OUTPUT_FILE_PREFIX          packages)
-  set (CPACK_PACKAGE_RELOCATABLE         TRUE)
-  set (CPACK_MONOLITHIC_INSTALL          TRUE)
-
-  # RPM package information -- used in cmake/package.cmake.in also for DEB
-  set (CPACK_RPM_PACKAGE_GROUP   "Development/Libraries")
-  set (CPACK_RPM_PACKAGE_LICENSE "BSD")
-  set (CPACK_RPM_PACKAGE_URL     "${PACKAGE_URL}")
-  set (CPACK_RPM_CHANGELOG_FILE  "${CMAKE_CURRENT_LIST_DIR}/ChangeLog.txt")
-
-  if (INSTALL_HEADERS)
-    set (CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_LIST_DIR}/doc/index.html")
-  else ()
-    set (CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_LIST_DIR}/cmake/README_runtime.txt")
-  endif ()
-
-  # system/architecture
-  if (WINDOWS)
-    if (CMAKE_CL_64)
-      set (CPACK_SYSTEM_NAME "win64")
-    else ()
-      set (CPACK_SYSTEM_NAME "win32")
-    endif ()
-    set (CPACK_PACKAGE_ARCHITECTURE)
-  elseif (APPLE)
-    set (CPACK_PACKAGE_ARCHITECTURE darwin)
-  else ()
-    string (TOLOWER "${CMAKE_SYSTEM_NAME}" CPACK_SYSTEM_NAME)
-    if (CMAKE_CXX_FLAGS MATCHES "-m32")
-      set (CPACK_PACKAGE_ARCHITECTURE i386)
-    else ()
-      execute_process (
-        COMMAND         dpkg --print-architecture
-        RESULT_VARIABLE RV
-        OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE
-      )
-      if (RV EQUAL 0)
-	      string (STRIP "${CPACK_PACKAGE_ARCHITECTURE}" CPACK_PACKAGE_ARCHITECTURE)
-      else ()
-        execute_process (COMMAND uname -m OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE)
-        if (CPACK_PACKAGE_ARCHITECTURE MATCHES "x86_64")
-	        set (CPACK_PACKAGE_ARCHITECTURE amd64)
-        else ()
-          set (CPACK_PACKAGE_ARCHITECTURE i386)
-        endif ()
-      endif ()
-    endif ()
-  endif ()
-
-  # source package settings
-  set (CPACK_SOURCE_TOPLEVEL_TAG      "source")
-  set (CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
-  set (CPACK_SOURCE_IGNORE_FILES      "/\\\\.git/;\\\\.swp$;\\\\.#;/#;\\\\.*~;cscope\\\\.*;/[Bb]uild[.+-_a-zA-Z0-9]*/")
-
-  # default binary package settings
-  set (CPACK_INCLUDE_TOPLEVEL_DIRECTORY TRUE)
-  set (CPACK_PACKAGE_FILE_NAME          "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
-  if (CPACK_PACKAGE_ARCHITECTURE)
-    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_PACKAGE_ARCHITECTURE}")
-  endif ()
-
-  # generator specific configuration file
-  #
-  # allow package maintainers to use their own configuration file
-  # $ cmake -DCPACK_PROJECT_CONFIG_FILE:FILE=/path/to/package/config
-  if (NOT CPACK_PROJECT_CONFIG_FILE)
-    configure_file (
-      "${CMAKE_CURRENT_LIST_DIR}/cmake/package.cmake.in"
-      "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-package.cmake" @ONLY
-    )
-    set (CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-package.cmake")
-  endif ()
-
-  include (CPack)
-
-endif () # BUILD_PACKAGING
-
-if (NOT GFLAGS_IS_SUBPROJECT AND NOT TARGET uninstall)
-  configure_file (
-    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
-    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" @ONLY
-  )
-  add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
-endif ()
diff --git a/third_party/gflags/COPYING.txt b/third_party/gflags/COPYING.txt
deleted file mode 100644
index d15b0c2..0000000
--- a/third_party/gflags/COPYING.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-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.
diff --git a/third_party/gflags/ChangeLog.txt b/third_party/gflags/ChangeLog.txt
deleted file mode 100644
index c26d0ab..0000000
--- a/third_party/gflags/ChangeLog.txt
+++ /dev/null
@@ -1,254 +0,0 @@
-* Tue Jul 11 2017 - Andreas Schuh <andreas.schuh.84@gmail.com>
-
-- gflags: version 2.2.1
-- Link to online documentation in README
-- Merged 194: Include utils by file instead of CMAKE_MODULE_PATH search
-- Merged 195: Remove unused program_name variable
-- Merged 196: Enable language C for older CMake versions when needed
-- Merged 202: Changed include directory in bazel build
-- Merged 207: Mark single argument constructors in mutex.h as explicit
-- Merged 209: Use inttypes.h on VC++ 2013 and later
-- Merged 212: Fix statically linked gflags library with MSVC
-- Meregd 213: Modify installation paths on Windows for vcpkg
-- Merged 215: Fix static initialization order fiasco caused by global registry lock
-- Merged 216: Fix use of ARGC in CMake macros
-- Merged 222: Static code analyzer error regarding strncmp with empty kRootDir
-- Merged 224: Check HAVE_STDINT_H or HAVE_INTTYPES_H for older MSVC versions
-
-* Fri Nov 25 2016 - Andreas Schuh <andreas.schuh.84@gmail.com>
-
-- gflags: version 2.2.0
-- Merged 178: Implicitly convert dashes in option names to underscores
-- Merged 159: CI builds and automatic tests with Travis CI and AppVeyor
-- Merged 158: Use enum for flag value types
-- Merged 126: File name postfix for static libraries on Windows
-- Closed issue 120: Configure and install gflags.pc file for pkg-config users
-- Fixed issue 127: snprintf already defined when building with MSVC 2015
-- Fixed issue 51/138: Memory leaks reported by valgrind
-- Fixed issue 173: Validate flags only once
-- Fixed issue 168: Unsigned and signed comparison in gflags_reporting.cc
-- Fixed issues 176/153: Add -lpthread link argument to Bazel build, refactor BUILD rules
-- Fixed issue 89: Add GFLAGS_IS_A_DLL to imported CMake target INTERFACE_COMPILE_DEFINITIONS
-- Fixed issue 104: Set INTERFACE_INCLUDE_DIRECTORIES of exported CMake targets
-- Fixed issue 174: Missing gflags-targets.cmake file after installation
-- Fixed issue 186: Error linking to gflags IMPLIB with MSVC using CMake
-- Closed issue 106: Add example project to test use of gflags library
-
-* Tue Mar 24 2014 - Andreas Schuh <andreas.schuh.84@gmail.com>
-
-- gflags: version 2.1.2
-- Moved project to GitHub
-- Added GFLAGS_NAMESPACE definition to gflags_declare.h
-- Fixed issue 94: Keep "google" as primary namespace and import symbols into "gflags" namespace
-- Fixed issue 96: Fix binary ABI compatibility with gflags 2.0 using "google" as primary namespace
-- Fixed issue 97/101: Removed (patched) CMake modules and enabled C language instead
-- Fixed issue 103: Set CMake policy CMP0042 to silence warning regarding MACOS_RPATH setting
-
-* Sun Mar 20 2014 - Andreas Schuh <google-gflags@googlegroups.com>
-
-- gflags: version 2.1.1
-- Fixed issue 77: GFLAGS_IS_A_DLL expands to empty string in gflags_declare.h
-- Fixed issue 79: GFLAGS_NAMESPACE not expanded to actual namespace in gflags_declare.h
-- Fixed issue 80: Allow include path to differ from GFLAGS_NAMESPACE
-
-* Thu Mar 20 2014 - Andreas Schuh <google-gflags@googlegroups.com>
-
-- gflags: version 2.1.0
-- Build system configuration using CMake instead of autotools
-- CPack packaging support for Debian/Ubuntu, Red Hat, and Mac OS X
-- Fixed issue 54: Fix "invalid suffix on literal" (C++11)
-- Fixed issue 57: Use _strdup instead of strdup on Windows
-- Fixed issue 62: Change all preprocessor include guards to start with GFLAGS_
-- Fixed issue 64: Add DEFINE_validator macro
-- Fixed issue 73: Warnings in Visual Studio 2010 and unable to compile unit test
-
-* Wed Jan 25 2012 - Google Inc. <google-gflags@googlegroups.com>
-
-- gflags: version 2.0
-- Changed the 'official' gflags email in setup.py/etc
-- Renamed google-gflags.sln to gflags.sln
-- Changed copyright text to reflect Google's relinquished ownership
-
-* Tue Dec 20 2011 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.7
-- Add CommandLineFlagInfo::flag_ptr pointing to current storage (musji)
-- PORTING: flush after writing to stderr, needed on cygwin
-- PORTING: Clean up the GFLAGS_DLL_DECL stuff better
-- Fix a bug in StringPrintf() that affected large strings (csilvers)
-- Die at configure-time when g++ isn't installed
-
-* Fri Jul 29 2011 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.6
-- BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
-- Fix definition of clstring (jyrki)
-- Split up flag declares into its own file (jyrki)
-- Add --version support (csilvers)
-- Update the README for gflags with static libs
-- Update acx_pthread.m4 for nostdlib
-- Change ReparseCommandLineFlags to return void (csilvers)
-- Some doc typofixes and example augmentation (various)
-
-* Mon Jan 24 2011 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.5
-- Better reporting of current vs default value (handler)
-- Add API for cleaning up of memory at program-exit (jmarantz)
-- Fix macros to work inside namespaces (csilvers)
-- Use our own string typedef in case string is redefined (csilvers)
-- Updated to autoconf 2.65
-
-* Wed Oct 13 2010 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.4
-- Add a check to prevent passing 0 to DEFINE_string (jorg)
-- Reduce compile (.o) size (jyrki)
-- Some small changes to quiet debug compiles (alexk)
-- PORTING: better support static linking on windows (csilvers)
-- DOCUMENTATION: change default values, use validators, etc.
-- Update the NEWS file to be non-empty
-- Add pkg-config (.pc) files for libgflags and libgflags_nothreads
-
-* Mon Jan  4 2010 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.3
-- PORTABILITY: can now build and run tests under MSVC (csilvers)
-- Remove the python gflags code, which is now its own package (tansell)
-- Clarify that "last flag wins" in the docs (csilvers)
-- Comment danger of using GetAllFlags in validators (wojtekm)
-- PORTABILITY: Some fixes necessary for c++0x (mboerger)
-- Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
-- INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
-
-* Thu Sep 10 2009 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.2
-- PORTABILITY: can now build and run tests under mingw (csilvers)
-- Using a string arg for a bool flag is a compile-time error (rbayardo)
-- Add --helpxml to gflags.py (salcianu)
-- Protect against a hypothetical global d'tor mutex problem (csilvers)
-- BUGFIX: can now define a flag after 'using namespace google' (hamaji)
-
-* Tue Apr 14 2009 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.1
-- Add both foo and nofoo for boolean flags, with --undefok (andychu)
-- Better document how validators work (wojtekm)
-- Improve binary-detection for bash-completion (mtamsky)
-- Python: Add a concept of "key flags", used with --help (salcianu)
-- Python: Robustify flag_values (salcianu)
-- Python: Add a new DEFINE_bool alias (keir, andrewliu)
-- Python: Do module introspection based on module name (dsturtevant)
-- Fix autoconf a bit better, especially on windows and solaris (ajenjo)
-- BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
-- BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
-- PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
-- PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
-- PORTABILITY: #include more headers to satify new gcc's (csilvers)
-- INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
-
-* Fri Oct  3 2008 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.0
-- Add a missing newline to an error string (bcmills)
-- (otherwise exactly the same as gflags 1.0rc2)
-
-* Thu Sep 18 2008 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.0rc2
-- Report current flag values in --helpxml (hdn)
-- Fix compilation troubles with gcc 4.3.3 (simonb)
-- BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
-- BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
-- BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
-- BUG FIX: Fix python unittest for 64-bit builds (bcmills)
-
-* Tue Aug 19 2008 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 1.0rc1
-- Move #include files from google/ to gflags/ (csilvers)
-- Small optimizations to reduce binary (library) size (jyrki)
-- BUGFIX: forgot a std:: in one of the .h files (csilvers)
-- Speed up locking by making sure calls are inlined (ajenjo)
-- 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
-- PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
-- PORTABILITY: fix code to compile under Visual Studio (ajenjo)
-- PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
-
-* Mon Jul 21 2008 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.9
-- Add the ability to validate a command-line flag (csilvers)
-- Add completion support for commandline flags in bash (daven)
-- Add -W compile flags to Makefile, when using gcc (csilvers)
-- Allow helpstring to be NULL (cristianoc)
-- Improved documentation of classes in the .cc file (csilvers)
-- Fix python bug with AppendFlagValues + shortnames (jjtswan)
-- Use bool instead of int for boolean flags in gflags.py (bcmills)
-- Simplify the way we declare flags, now more foolproof (csilvers)
-- Better error messages when bool flags collide (colohan)
-- Only evaluate DEFINE_foo macro args once (csilvers)
-
-* Wed Mar 26 2008 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.8
-- Export DescribeOneFlag() in the API
-- Add support for automatic line wrapping at 80 cols for gflags.py
-- Bugfix: do not treat an isolated "-" the same as an isolated "--"
-- Update rpm spec to point to Google Code rather than sourceforge (!)
-- Improve documentation (including documenting thread-safety)
-- Improve #include hygiene
-- Improve testing
-
-* Thu Oct 18 2007 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.7
-- Deal even more correctly with libpthread not linked in (csilvers)
-- Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
-- Be more accurate printing default flag values in --help (dsturtevant)
-- Reduce .o file size a bit by using shorter namespace names (jeff)
-- Use relative install path, so 'setup.py --home' works (csilvers)
-- Notice when a boolean flag has a non-boolean default (bnmouli)
-- Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
-- Fix "no modules match" message for --helpshort, etc (hendrie)
-
-* Wed Aug 15 2007 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.6
-- Deal correctly with case that libpthread is not linked in (csilvers)
-- Update Makefile/tests so we pass "make distcheck" (csilvers)
-- Document and test that last assignment to a flag wins (wan)
-
-* Tue Jun 12 2007 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.5
-- Include all m4 macros in the distribution (csilvers)
-- Python: Fix broken data_files field in setup.py (sidlon)
-- Python: better string serliaizing and unparsing (abo, csimmons)
-- Fix checks for NaN and inf to work with Mac OS X (csilvers)
-
-* Thu Apr 19 2007 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.4
-- Remove is_default from GetCommandLineFlagInfo (csilvers)
-- Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
-- A few doc typo cleanups (csilvers)
-
-* Wed Mar 28 2007 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.3
-- python portability fix: use popen instead of subprocess (csilvers)
-- Add is_default to CommandLineFlagInfo (pchien)
-- Make docs a bit prettier (csilvers)
-- Actually include the python files in the distribution! :-/ (csilvers)
-
-* Mon Jan 22 2007 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.2
-- added support for python commandlineflags, as well as c++
-- gflags2man, a script to turn flags into a man page (dchristian)
-
-* Wed Dec 13 2006 - Google Inc. <opensource@google.com>
-
-- google-gflags: version 0.1
diff --git a/third_party/gflags/INSTALL.md b/third_party/gflags/INSTALL.md
deleted file mode 100644
index 76d7edd..0000000
--- a/third_party/gflags/INSTALL.md
+++ /dev/null
@@ -1,83 +0,0 @@
-Installing a binary distribution package
-========================================
-
-No official binary distribution packages are provided by the gflags developers.
-There may, however, be binary packages available for your OS. Please consult
-also the package repositories of your Linux distribution.
-
-For example on Debian/Ubuntu Linux, gflags can be installed using the
-following command:
-
-    sudo apt-get install libgflags-dev
-
-
-Compiling the source code with CMake
-=========================
-
-The build system of gflags is since version 2.1 based on [CMake](http://cmake.org).
-The common steps to build, test, and install software are therefore:
-
-1. Extract source files.
-2. Create build directory and change to it.
-3. Run CMake to configure the build tree.
-4. Build the software using selected build tool.
-5. Test the built software.
-6. Install the built files.
-
-On Unix-like systems with GNU Make as build tool, these build steps can be
-summarized by the following sequence of commands executed in a shell,
-where ```$package``` and ```$version``` are shell variables which represent
-the name of this package and the obtained version of the software.
-
-    $ tar xzf gflags-$version-source.tar.gz
-    $ cd gflags-$version
-    $ mkdir build && cd build
-    $ ccmake ..
-    
-      - Press 'c' to configure the build system and 'e' to ignore warnings.
-      - Set CMAKE_INSTALL_PREFIX and other CMake variables and options.
-      - Continue pressing 'c' until the option 'g' is available.
-      - Then press 'g' to generate the configuration files for GNU Make.
-    
-    $ make
-    $ make test    (optional)
-    $ make install (optional)
-
-In the following, only gflags-specific CMake settings available to
-configure the build and installation are documented. Note that most of these
-variables are for advanced users and binary package maintainers only.
-They usually do not have to be modified.
-
-
-CMake Option                | Description
---------------------------- | -------------------------------------------------------
-CMAKE_INSTALL_PREFIX        | Installation directory, e.g., "/usr/local" on Unix and "C:\Program Files\gflags" on Windows.
-BUILD_SHARED_LIBS           | Request build of dynamic link libraries.
-BUILD_STATIC_LIBS           | Request build of static link libraries. Implied if BUILD_SHARED_LIBS is OFF.
-BUILD_PACKAGING             | Enable binary package generation using CPack.
-BUILD_TESTING               | Build tests for execution by CTest.
-BUILD_NC_TESTS              | Request inclusion of negative compilation tests (requires Python).
-BUILD_CONFIG_TESTS          | Request inclusion of package configuration tests (requires Python).
-BUILD_gflags_LIBS           | Request build of multi-threaded gflags libraries (if threading library found).
-BUILD_gflags_nothreads_LIBS | Request build of single-threaded gflags libraries.
-GFLAGS_NAMESPACE            | Name of the C++ namespace to be used by the gflags library. Note that the public source header files are installed in a subdirectory named after this namespace. To maintain backwards compatibility with the Google Commandline Flags, set this variable to "google". The default is "gflags".
-GFLAGS_INTTYPES_FORMAT      | String identifying format of built-in integer types.
-GFLAGS_INCLUDE_DIR          | Name of headers installation directory relative to CMAKE_INSTALL_PREFIX.
-LIBRARY_INSTALL_DIR         | Name of library installation directory relative to CMAKE_INSTALL_PREFIX.
-INSTALL_HEADERS             | Request installation of public header files.
-
-Using gflags with [Bazel](http://bazel.io)
-=========================
-
-To use gflags in a Bazel project, map it in as an external dependency by editing
-your WORKSPACE file:
-
-    git_repository(
-        name = "com_github_gflags_gflags",
-        commit = "<INSERT COMMIT SHA HERE>",
-        remote = "https://github.com/gflags/gflags.git",
-    )
-
-You can then add `@com_github_gflags_gflags//:gflags` to the `deps` section of a
-`cc_binary` or `cc_library` rule, and `#include <gflags/gflags.h>` to include it
-in your source code.
diff --git a/third_party/gflags/README.md b/third_party/gflags/README.md
deleted file mode 100644
index 9f3e3f2..0000000
--- a/third_party/gflags/README.md
+++ /dev/null
@@ -1,305 +0,0 @@
-[![Build Status](https://travis-ci.org/gflags/gflags.svg?branch=master)](https://travis-ci.org/gflags/gflags)
-[![Build status](https://ci.appveyor.com/api/projects/status/4ctod566ysraus74/branch/master?svg=true)](https://ci.appveyor.com/project/schuhschuh/gflags/branch/master)
-
-The documentation of the gflags library is available online at https://gflags.github.io/gflags/.
-
-11 July 2017
-------------
-
-I've just released gflags 2.2.1.
-
-This maintenance release primarily fixes build issues on Windows and
-false alarms reported by static code analyzers.
-
-Please report any further issues with this release using the GitHub issue tracker.
-
-
-25 November 2016
-----------------
-
-I've finally released gflags 2.2.0.
-
-This release adds support for use of the gflags library as external dependency
-not only in projects using CMake, but also [Bazel](https://bazel.build/),
-or [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/).
-One new minor feature is added in this release: when a command flag argument
-contains dashes, these are implicitly converted to underscores.
-This is to allow those used to separate words of the flag name by dashes
-to do so, while the flag variable names are required to use underscores.
-
-Memory leaks reported by valgrind should be resolved by this release.
-This release fixes build errors with MS Visual Studio 2015.
-
-Please report any further issues with this release using the GitHub issue tracker.
-
-
-24 March 2015
--------------
-
-I've just released gflags 2.1.2.
-
-This release completes the namespace change fixes. In particular,
-it restores binary ABI compatibility with release version 2.0.
-The deprecated "google" namespace is by default still kept as
-primary namespace while symbols are imported into the new "gflags" namespace.
-This can be overridden using the CMake variable GFLAGS_NAMESPACE.
-
-Other fixes of the build configuration are related to the (patched)
-CMake modules FindThreads.cmake and CheckTypeSize.cmake. These have
-been removed and instead the C language is enabled again even though
-gflags is written in C++ only.
-
-This release also marks the complete move of the gflags project
-from Google Code to GitHub. Email addresses of original issue
-reporters got lost in the process. Given the age of most issue reports,
-this should be negligable.
-
-Please report any further issues using the GitHub issue tracker.
-
-
-30 March 2014
--------------
-
-I've just released gflags 2.1.1.
-
-This release fixes a few bugs in the configuration of gflags\_declare.h
-and adds a separate GFLAGS\_INCLUDE\_DIR CMake variable to the build configuration.
-Setting GFLAGS\_NAMESPACE to "google" no longer changes also the include
-path of the public header files. This allows the use of the library with
-other Google projects such as glog which still use the deprecated "google"
-namespace for the gflags library, but include it as "gflags/gflags.h".
-
-20 March 2014
--------------
-
-I've just released gflags 2.1.
-
-The major changes are the use of CMake for the build configuration instead
-of the autotools and packaging support through CPack. The default namespace
-of all C++ symbols is now "gflags" instead of "google". This can be
-configured via the GFLAGS\_NAMESPACE variable.
-
-This release compiles with all major compilers without warnings and passed
-the unit tests on  Ubuntu 12.04, Windows 7 (Visual Studio 2008 and 2010,
-Cygwin, MinGW), and Mac OS X (Xcode 5.1).
-
-The SVN repository on Google Code is now frozen and replaced by a Git
-repository such that it can be used as Git submodule by projects. The main
-hosting of this project remains at Google Code. Thanks to the distributed
-character of Git, I can push (and pull) changes from both GitHub and Google Code
-in order to keep the two public repositories in sync.
-When fixing an issue for a pull request through either of these hosting
-platforms, please reference the issue number as
-[described here](https://code.google.com/p/support/wiki/IssueTracker#Integration_with_version_control).
-For the further development, I am following the
-[Git branching model](http://nvie.com/posts/a-successful-git-branching-model/)
-with feature branch names prefixed by "feature/" and bugfix branch names
-prefixed by "bugfix/", respectively.
-
-Binary and source [packages](https://github.com/schuhschuh/gflags/releases) are available on GitHub.
-
-
-14 January 2014
----------------
-
-The migration of the build system to CMake is almost complete.
-What remains to be done is rewriting the tests in Python such they can be
-executed on non-Unix platforms and splitting them up into separate CTest tests.
-Though merging these changes into the master branch yet remains to be done,
-it is recommended to already start using the
-[cmake-migration](https://github.com/schuhschuh/gflags/tree/cmake-migration) branch.
-
-
-20 April 2013
--------------
-
-More than a year has past since I (Andreas) took over the maintenance for
-`gflags`. Only few minor changes have been made since then, much to my regret.
-To get more involved and stimulate participation in the further
-development of the library, I moved the project source code today to
-[GitHub](https://github.com/schuhschuh/gflags).
-I believe that the strengths of [Git](http://git-scm.com/) will allow for better community collaboration
-as well as ease the integration of changes made by others. I encourage everyone
-who would like to contribute to send me pull requests.
-Git's lightweight feature branches will also provide the right tool for more
-radical changes which should only be merged back into the master branch
-after these are complete and implement the desired behavior.
-
-The SVN repository remains accessible at Google Code and I will keep the
-master branch of the Git repository hosted at GitHub and the trunk of the
-Subversion repository synchronized. Initially, I was going to simply switch the
-Google Code project to Git, but in this case the SVN repository would be
-frozen and force everyone who would like the latest development changes to
-use Git as well. Therefore I decided to host the public Git repository at GitHub
-instead.
-
-Please continue to report any issues with gflags on Google Code. The GitHub project will
-only be used to host the Git repository.
-
-One major change of the project structure I have in mind for the next weeks
-is the migration from autotools to [CMake](http://www.cmake.org/).
-Check out the (unstable!)
-[cmake-migration](https://github.com/schuhschuh/gflags/tree/cmake-migration)
-branch on GitHub for details.
-
-
-25 January 2012
----------------
-
-I've just released gflags 2.0.
-
-The `google-gflags` project has been renamed to `gflags`.  I
-(csilvers) am stepping down as maintainer, to be replaced by Andreas
-Schuh.  Welcome to the team, Andreas!  I've seen the energy you have
-around gflags and the ideas you have for the project going forward,
-and look forward to having you on the team.
-
-I bumped the major version number up to 2 to reflect the new community
-ownership of the project.  All the [changes](ChangeLog.txt)
-are related to the renaming.  There are no functional changes from
-gflags 1.7.  In particular, I've kept the code in the namespace
-`google`, though in a future version it should be renamed to `gflags`.
-I've also kept the `/usr/local/include/google/` subdirectory as
-synonym of `/usr/local/include/gflags/`, though the former name has
-been obsolete for some time now.
-
-
-18 January 2011
----------------
-
-The `google-gflags` Google Code page has been renamed to
-`gflags`, in preparation for the project being renamed to
-`gflags`.  In the coming weeks, I'll be stepping down as
-maintainer for the gflags 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.
-
-
-20 December 2011
-----------------
-
-I've just released gflags 1.7.  This is a minor release; the major
-change is that `CommandLineFlagInfo` now exports the address in memory
-where the flag is located.  There has also been a bugfix involving
-very long --help strings, and some other minor [changes](ChangeLog.txt).
-
-29 July 2011
-------------
-
-I've just released gflags 1.6.  The major new feature in this release
-is support for setting version info, so that --version does something
-useful.
-
-One minor change has required bumping the library number:
-`ReparseCommandlineFlags` now returns `void` instead of `int` (the int
-return value was always meaningless).  Though I doubt anyone ever used
-this (meaningless) return value, technically it's a change to the ABI
-that requires a version bump.  A bit sad.
-
-There's also a procedural change with this release: I've changed the
-internal tools used to integrate Google-supplied patches for gflags
-into the opensource release.  These new tools should result in more
-frequent updates with better change descriptions.  They will also
-result in future `ChangeLog` entries being much more verbose (for better
-or for worse).
-
-See the [ChangeLog](ChangeLog.txt) for a full list of changes for this release.
-
-24 January 2011
----------------
-
-I've just released gflags 1.5.  This release has only minor changes
-from 1.4, including some slightly better reporting in --help, and
-an new memory-cleanup function that can help when running gflags-using
-libraries under valgrind.  The major change is to fix up the macros
-(`DEFINE_bool` and the like) to work more reliably inside namespaces.
-
-If you have not had a problem with these macros, and don't need any of
-the other changes described, there is no need to upgrade.  See the
-[ChangeLog](ChangeLog.txt) for a full list of changes for this release.
-
-11 October 2010
----------------
-
-I've just released gflags 1.4.  This release has only minor changes
-from 1.3, including some documentation tweaks and some work to make
-the library smaller.  If 1.3 is working well for you, there's no
-particular reason to upgrade.
-
-4 January 2010
---------------
-
-I've just released gflags 1.3.  gflags now compiles under MSVC, and
-all tests pass.  I **really** never thought non-unix-y Windows folks
-would want gflags, but at least some of them do.
-
-The major news, though, is that I've separated out the python package
-into its own library, [python-gflags](http://code.google.com/p/python-gflags).
-If you're interested in the Python version of gflags, that's the place to
-get it now.
-
-10 September 2009
------------------
-
-I've just released gflags 1.2.  The major change from gflags 1.1 is it
-now compiles under MinGW (as well as cygwin), and all tests pass.  I
-never thought Windows folks would want unix-style command-line flags,
-since they're so different from the Windows style, but I guess I was
-wrong!
-
-The other changes are minor, such as support for --htmlxml in the
-python version of gflags.
-
-15 April 2009
--------------
-
-I've just released gflags 1.1.  It has only minor changes fdrom gflags
-1.0 (see the [ChangeLog](ChangeLog.txt) for details).
-The major change is that I moved to a new system for creating .deb and .rpm files.
-This allows me to create x86\_64 deb and rpm files.
-
-In the process of moving to this new system, I noticed an
-inconsistency: the tar.gz and .rpm files created libraries named
-libgflags.so, but the deb file created libgoogle-gflags.so.  I have
-fixed the deb file to create libraries like the others.  I'm no expert
-in debian packaging, but I believe this has caused the package name to
-change as well.  Please let me know (at
-[[mailto:google-gflags@googlegroups.com](mailto:google-gflags@googlegroups.com)
-google-gflags@googlegroups.com]) if this causes problems for you --
-especially if you know of a fix!  I would be happy to change the deb
-packages to add symlinks from the old library name to the new
-(libgoogle-gflags.so -> libgflags.so), but that is beyond my knowledge
-of how to make .debs.
-
-If you've tried to install a .rpm or .deb and it doesn't work for you,
-let me know.  I'm excited to finally have 64-bit package files, but
-there may still be some wrinkles in the new system to iron out.
-
-1 October 2008
---------------
-
-gflags 1.0rc2 was out for a few weeks without any issues, so gflags
-1.0 is now released.  This is much like gflags 0.9.  The major change
-is that the .h files have been moved from `/usr/include/google` to
-`/usr/include/gflags`.  While I have backwards-compatibility
-forwarding headeds in place, please rewrite existing code to say
-```
-   #include <gflags/gflags.h>
-```
-instead of
-```
-   #include <google/gflags.h>
-```
-
-I've kept the default namespace to google.  You can still change with
-with the appropriate flag to the configure script (`./configure
---help` to see the flags).  If you have feedback as to whether the
-default namespace should change to gflags, which would be a
-non-backwards-compatible change, send mail to
-`google-gflags@googlegroups.com`!
-
-Version 1.0 also has some neat new features, like support for bash
-commandline-completion of help flags.  See the [ChangeLog](ChangeLog.txt)
-for more details.
-
-If I don't hear any bad news for a few weeks, I'll release 1.0-final.
diff --git a/third_party/gflags/WORKSPACE b/third_party/gflags/WORKSPACE
deleted file mode 100644
index f3707e9..0000000
--- a/third_party/gflags/WORKSPACE
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2006 Google Inc.  All Rights Reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the COPYING.txt file.
-
-# Bazel (http://bazel.io/) WORKSPACE file for gflags.
-workspace(name="com_github_gflags_gflags")
diff --git a/third_party/gflags/appveyor.yml b/third_party/gflags/appveyor.yml
deleted file mode 100644
index a5110e5..0000000
--- a/third_party/gflags/appveyor.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-# Configuration for continuous integration service at appveyor.com
-
-version: '{build}'
-
-os: Visual Studio 2015
-
-environment:
-  matrix:
-  - Toolset: v140
-  - Toolset: v120
-  - Toolset: v110
-  - Toolset: v100
-  - Toolset: v90
-
-platform:
-  - Win32
-  - x64
-
-configuration:
-  - Release
-
-matrix:
-  exclude:
-    - Toolset: v90
-      platform: x64
-    - Toolset: v100
-      platform: x64
-
-build:
-  verbosity: minimal
-
-before_build:
-- ps: |
-    Write-Output "Configuration: $env:CONFIGURATION"
-    Write-Output "Platform: $env:PLATFORM"
-    $generator = switch ($env:TOOLSET)
-    {
-        "v140" {"Visual Studio 14 2015"}
-        "v120" {"Visual Studio 12 2013"}
-        "v110" {"Visual Studio 11 2012"}
-        "v100" {"Visual Studio 10 2010"}
-        "v90" {"Visual Studio 9 2008"}
-    }
-    if ($env:PLATFORM -eq "x64")
-    {
-        $generator = "$generator Win64"
-    }
-
-build_script:
-- ps: |
-    md _build -Force | Out-Null
-    cd _build
-
-    & cmake -G "$generator" -D CMAKE_CONFIGURATION_TYPES="Debug;Release" -D GFLAGS_BUILD_TESTING=ON -D GFLAGS_BUILD_SHARED_LIBS=ON -D GFLAGS_BUILD_STATIC_LIBS=ON ..
-    if ($LastExitCode -ne 0) {
-        throw "Exec: $ErrorMessage"
-    }
-    & cmake --build . --config $env:CONFIGURATION
-    if ($LastExitCode -ne 0) {
-        throw "Exec: $ErrorMessage"
-    }
-
-test_script:
-- ps: |
-    & ctest -C $env:CONFIGURATION --output-on-failure
-    if ($LastExitCode -ne 0) {
-        throw "Exec: $ErrorMessage"
-    }
diff --git a/third_party/gflags/bazel/gflags.bzl b/third_party/gflags/bazel/gflags.bzl
deleted file mode 100644
index bfa006e..0000000
--- a/third_party/gflags/bazel/gflags.bzl
+++ /dev/null
@@ -1,105 +0,0 @@
-# ------------------------------------------------------------------------------
-# Add native rules to configure source files
-def gflags_sources(namespace=["google", "gflags"]):
-    native.genrule(
-        name = "gflags_declare_h",
-        srcs = ["src/gflags_declare.h.in"],
-        outs = ["gflags_declare.h"],
-        cmd  = ("awk '{ " +
-                "gsub(/@GFLAGS_NAMESPACE@/, \"" + namespace[0] + "\"); " +
-                "gsub(/@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@/, \"1\"); " +
-                "gsub(/@([A-Z0-9_]+)@/, \"0\"); " +
-                "print; }' $(<) > $(@)")
-    )
-    gflags_ns_h_files = []
-    for ns in namespace[1:]:
-        gflags_ns_h_file = "gflags_{}.h".format(ns)
-        native.genrule(
-            name = gflags_ns_h_file.replace('.', '_'),
-            srcs = ["src/gflags_ns.h.in"],
-            outs = [gflags_ns_h_file],
-            cmd  = ("awk '{ " +
-                    "gsub(/@ns@/, \"" + ns + "\"); " +
-                    "gsub(/@NS@/, \"" + ns.upper() + "\"); " +
-                    "print; }' $(<) > $(@)")
-        )
-        gflags_ns_h_files.append(gflags_ns_h_file)
-    native.genrule(
-        name = "gflags_h",
-        srcs = ["src/gflags.h.in"],
-        outs = ["gflags.h"],
-        cmd  = ("awk '{ " +
-                "gsub(/@GFLAGS_ATTRIBUTE_UNUSED@/, \"\"); " +
-                "gsub(/@INCLUDE_GFLAGS_NS_H@/, \"" + '\n'.join(["#include \\\"gflags/{}\\\"".format(hdr) for hdr in gflags_ns_h_files]) + "\"); " +
-                "print; }' $(<) > $(@)")
-    )
-    native.genrule(
-        name = "gflags_completions_h",
-        srcs = ["src/gflags_completions.h.in"],
-        outs = ["gflags_completions.h"],
-        cmd  = "awk '{ gsub(/@GFLAGS_NAMESPACE@/, \"" + namespace[0] + "\"); print; }' $(<) > $(@)"
-    )
-    hdrs = [":gflags_h", ":gflags_declare_h", ":gflags_completions_h"]
-    hdrs.extend([':' + hdr.replace('.', '_') for hdr in gflags_ns_h_files])
-    srcs = [
-        "src/config.h",
-        "src/gflags.cc",
-        "src/gflags_completions.cc",
-        "src/gflags_reporting.cc",
-        "src/mutex.h",
-        "src/util.h",
-    ] + select({
-        "//:x64_windows": [
-            "src/windows_port.cc",
-            "src/windows_port.h",
-        ],
-        "//conditions:default": [],
-    })
-    return [hdrs, srcs]
-
-# ------------------------------------------------------------------------------
-# Add native rule to build gflags library
-def gflags_library(hdrs=[], srcs=[], threads=1):
-    name = "gflags"
-    copts = [
-        "-DGFLAGS_BAZEL_BUILD",
-        "-DGFLAGS_INTTYPES_FORMAT_C99",
-        "-DGFLAGS_IS_A_DLL=0",
-        # macros otherwise defined by CMake configured defines.h file
-        "-DHAVE_STDINT_H",
-        "-DHAVE_SYS_TYPES_H",
-        "-DHAVE_INTTYPES_H",
-        "-DHAVE_SYS_STAT_H",
-        "-DHAVE_STRTOLL",
-        "-DHAVE_STRTOQ",
-        "-DHAVE_RWLOCK",
-        "-Wno-format-nonliteral",
-        "-Wno-cast-function-type",
-    ] + select({
-        "//:x64_windows": [
-            "-DOS_WINDOWS",
-        ],
-        "//conditions:default": [
-            "-DHAVE_UNISTD_H",
-            "-DHAVE_FNMATCH_H",
-            "-DHAVE_PTHREAD",
-        ],
-    })
-    linkopts = []
-    if threads:
-        linkopts += select({
-            "//:x64_windows": [],
-            "//conditions:default": ["-lpthread"],
-        })
-    else:
-        name += "_nothreads"
-        copts += ["-DNO_THREADS"]
-    native.cc_library(
-        name       = name,
-        hdrs       = hdrs,
-        srcs       = srcs,
-        copts      = copts,
-        linkopts   = linkopts,
-        visibility = ["//visibility:public"],
-        include_prefix = 'gflags'
-    )
diff --git a/third_party/gflags/cmake/README_runtime.txt b/third_party/gflags/cmake/README_runtime.txt
deleted file mode 100644
index d2556b2..0000000
--- a/third_party/gflags/cmake/README_runtime.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This package contains runtime libraries only which are required
-by applications that use these libraries for the commandline flags
-processing. If you want to develop such application, download
-and install the development package instead.
diff --git a/third_party/gflags/cmake/cmake_uninstall.cmake.in b/third_party/gflags/cmake/cmake_uninstall.cmake.in
deleted file mode 100644
index d00a516..0000000
--- a/third_party/gflags/cmake/cmake_uninstall.cmake.in
+++ /dev/null
@@ -1,26 +0,0 @@
-if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
-  message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
-endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
-
-if (NOT DEFINED CMAKE_INSTALL_PREFIX)
-  set (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
-endif ()
- message(${CMAKE_INSTALL_PREFIX})
-
-file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
-string(REGEX REPLACE "\n" ";" files "${files}")
-foreach(file ${files})
-  message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
-  if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
-    exec_program(
-      "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
-      OUTPUT_VARIABLE rm_out
-      RETURN_VALUE rm_retval
-      )
-    if(NOT "${rm_retval}" STREQUAL 0)
-      message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
-    endif(NOT "${rm_retval}" STREQUAL 0)
-  else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
-    message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
-  endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
-endforeach(file)
diff --git a/third_party/gflags/cmake/config.cmake.in b/third_party/gflags/cmake/config.cmake.in
deleted file mode 100644
index a512c2a..0000000
--- a/third_party/gflags/cmake/config.cmake.in
+++ /dev/null
@@ -1,183 +0,0 @@
-## gflags CMake configuration file
-
-# library version information
-set (@PACKAGE_PREFIX@_VERSION_STRING "@PACKAGE_VERSION@")
-set (@PACKAGE_PREFIX@_VERSION_MAJOR  @PACKAGE_VERSION_MAJOR@)
-set (@PACKAGE_PREFIX@_VERSION_MINOR  @PACKAGE_VERSION_MINOR@)
-set (@PACKAGE_PREFIX@_VERSION_PATCH  @PACKAGE_VERSION_PATCH@)
-
-# import targets
-if (NOT DEFINED @PACKAGE_PREFIX@_USE_TARGET_NAMESPACE)
-  set (@PACKAGE_PREFIX@_USE_TARGET_NAMESPACE FALSE)
-endif ()
-if (@PACKAGE_PREFIX@_USE_TARGET_NAMESPACE)
-  include ("${CMAKE_CURRENT_LIST_DIR}/@EXPORT_NAME@.cmake")
-  set (@PACKAGE_PREFIX@_TARGET_NAMESPACE @PACKAGE_NAME@)
-else ()
-  include ("${CMAKE_CURRENT_LIST_DIR}/@PACKAGE_NAME@-nonamespace-targets.cmake")
-  set (@PACKAGE_PREFIX@_TARGET_NAMESPACE)
-endif ()
-if (@PACKAGE_PREFIX@_TARGET_NAMESPACE)
-  set (@PACKAGE_PREFIX@_TARGET_PREFIX ${@PACKAGE_PREFIX@_TARGET_NAMESPACE}::)
-else ()
-  set (@PACKAGE_PREFIX@_TARGET_PREFIX)
-endif ()
-
-# installation prefix
-get_filename_component (CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-get_filename_component (_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_PREFIX_REL2CONFIG_DIR@" ABSOLUTE)
-
-# include directory
-#
-# Newer versions of CMake set the INTERFACE_INCLUDE_DIRECTORIES property
-# of the imported targets. It is hence not necessary to add this path
-# manually to the include search path for targets which link to gflags.
-set (@PACKAGE_PREFIX@_INCLUDE_DIR "${_INSTALL_PREFIX}/@INCLUDE_INSTALL_DIR@")
-
-if (@PACKAGE_NAME@_FIND_COMPONENTS)
-  foreach (@PACKAGE_NAME@_FIND_COMPONENT IN LISTS @PACKAGE_NAME@_FIND_COMPONENTS)
-    if (@PACKAGE_NAME@_FIND_REQUIRED_${@PACKAGE_NAME@_FIND_COMPONENT} AND NOT TARGET @PACKAGE_NAME@_${@PACKAGE_NAME@_FIND_COMPONENT})
-      message (FATAL_ERROR "Package @PACKAGE_NAME@ was installed without required component ${@PACKAGE_NAME@_FIND_COMPONENT}!")
-    endif ()
-  endforeach ()
-  list (GET @PACKAGE_NAME@_FIND_COMPONENTS 0 @PACKAGE_NAME@_FIND_COMPONENT)
-else ()
-  set (@PACKAGE_NAME@_FIND_COMPONENT)
-endif ()
-
-# default settings of @PACKAGE_PREFIX@_SHARED and @PACKAGE_PREFIX@_NOTHREADS
-#
-# It is recommended to use either one of the following find_package commands
-# instead of setting the @PACKAGE_PREFIX@_(SHARED|NOTHREADS) variables:
-# - find_package(@PACKAGE_NAME@ REQUIRED)
-# - find_package(@PACKAGE_NAME@ COMPONENTS nothreads_static)
-# - find_package(@PACKAGE_NAME@ COMPONENTS nothreads_shared)
-# - find_package(@PACKAGE_NAME@ COMPONENTS static)
-# - find_package(@PACKAGE_NAME@ COMPONENTS shared)
-if (NOT DEFINED @PACKAGE_PREFIX@_SHARED)
-  if (DEFINED @PACKAGE_NAME@_SHARED)
-    set (@PACKAGE_PREFIX@_SHARED ${@PACKAGE_NAME@_SHARED})
-  elseif (@PACKAGE_NAME@_FIND_COMPONENT)
-    if (@PACKAGE_NAME@_FIND_COMPONENT MATCHES "shared")
-      set (@PACKAGE_PREFIX@_SHARED TRUE)
-    else ()
-      set (@PACKAGE_PREFIX@_SHARED FALSE)
-    endif ()
-  elseif (TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_shared OR TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_nothreads_shared)
-    set (@PACKAGE_PREFIX@_SHARED TRUE)
-  else ()
-    set (@PACKAGE_PREFIX@_SHARED FALSE)
-  endif ()
-endif ()
-if (NOT DEFINED @PACKAGE_PREFIX@_NOTHREADS)
-  if (DEFINED @PACKAGE_NAME@_NOTHREADS)
-    set (@PACKAGE_PREFIX@_NOTHREADS ${@PACKAGE_NAME@_NOTHREADS})
-  elseif (@PACKAGE_NAME@_FIND_COMPONENT)
-    if (@PACKAGE_NAME@_FIND_COMPONENT MATCHES "nothreads")
-      set (@PACKAGE_PREFIX@_NOTHREADS TRUE)
-    else ()
-      set (@PACKAGE_PREFIX@_NOTHREADS FALSE)
-    endif ()
-  elseif (TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}PACKAGE_NAME@_static OR TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_shared)
-    set (@PACKAGE_PREFIX@_NOTHREADS FALSE)
-  else ()
-    set (@PACKAGE_PREFIX@_NOTHREADS TRUE)
-  endif ()
-endif ()
-
-# choose imported library target
-if (NOT @PACKAGE_PREFIX@_TARGET)
-  if (@PACKAGE_NAME@_TARGET)
-    set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_NAME@_TARGET})
-  elseif (@PACKAGE_PREFIX@_SHARED)
-    if (@PACKAGE_PREFIX@_NOTHREADS)
-      set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_nothreads_shared)
-    else ()
-      set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_shared)
-    endif ()
-  else ()
-    if (@PACKAGE_PREFIX@_NOTHREADS)
-      set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_nothreads_static)
-    else ()
-      set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@_static)
-    endif ()
-  endif ()
-endif ()
-if (NOT TARGET ${@PACKAGE_PREFIX@_TARGET})
-  message (FATAL_ERROR "Your @PACKAGE_NAME@ installation does not contain a ${@PACKAGE_PREFIX@_TARGET} library target!"
-                       " Try a different combination of @PACKAGE_PREFIX@_SHARED and @PACKAGE_PREFIX@_NOTHREADS.")
-endif ()
-
-# add more convenient "${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@" import target
-if (NOT TARGET ${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@)
-  if (@PACKAGE_PREFIX@_SHARED)
-    add_library (${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ SHARED IMPORTED)
-  else ()
-    add_library (${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ STATIC IMPORTED)
-  endif ()
-  # copy INTERFACE_* properties
-  foreach (_@PACKAGE_PREFIX@_PROPERTY_NAME IN ITEMS
-    COMPILE_DEFINITIONS
-    COMPILE_FEATURES
-    COMPILE_OPTIONS
-    INCLUDE_DIRECTORIES
-    LINK_LIBRARIES
-    POSITION_INDEPENDENT_CODE
-  )
-    get_target_property (_@PACKAGE_PREFIX@_PROPERTY_VALUE ${@PACKAGE_PREFIX@_TARGET} INTERFACE_${_@PACKAGE_PREFIX@_PROPERTY_NAME})
-    if (_@PACKAGE_PREFIX@_PROPERTY_VALUE)
-      set_target_properties(${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ PROPERTIES
-        INTERFACE_${_@PACKAGE_PREFIX@_PROPERTY_NAME} "${_@PACKAGE_PREFIX@_PROPERTY_VALUE}"
-      )
-    endif ()
-  endforeach ()
-  # copy IMPORTED_*_<CONFIG> properties
-  get_target_property (_@PACKAGE_PREFIX@_CONFIGURATIONS ${@PACKAGE_PREFIX@_TARGET} IMPORTED_CONFIGURATIONS)
-  set_target_properties (${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ PROPERTIES IMPORTED_CONFIGURATIONS "${_@PACKAGE_PREFIX@_CONFIGURATIONS}")
-  foreach (_@PACKAGE_PREFIX@_PROPERTY_NAME IN ITEMS
-    IMPLIB
-    LOCATION
-    LINK_DEPENDENT_LIBRARIES
-    LINK_INTERFACE_LIBRARIES
-    LINK_INTERFACE_LANGUAGES
-    LINK_INTERFACE_MULTIPLICITY
-    NO_SONAME
-    SONAME
-  )
-    foreach (_@PACKAGE_PREFIX@_CONFIG IN LISTS _@PACKAGE_PREFIX@_CONFIGURATIONS)
-      get_target_property (_@PACKAGE_PREFIX@_PROPERTY_VALUE ${@PACKAGE_PREFIX@_TARGET} IMPORTED_${_@PACKAGE_PREFIX@_PROPERTY_NAME}_${_@PACKAGE_PREFIX@_CONFIG})
-      if (_@PACKAGE_PREFIX@_PROPERTY_VALUE)
-        set_target_properties(${@PACKAGE_PREFIX@_TARGET_PREFIX}@PACKAGE_NAME@ PROPERTIES
-          IMPORTED_${_@PACKAGE_PREFIX@_PROPERTY_NAME}_${_@PACKAGE_PREFIX@_CONFIG} "${_@PACKAGE_PREFIX@_PROPERTY_VALUE}"
-        )
-      endif ()
-    endforeach ()
-  endforeach ()
-  unset (_@PACKAGE_PREFIX@_CONFIGURATIONS)
-  unset (_@PACKAGE_PREFIX@_CONFIG)
-  unset (_@PACKAGE_PREFIX@_PROPERTY_NAME)
-  unset (_@PACKAGE_PREFIX@_PROPERTY_VALUE)
-endif ()
-
-# alias for default import target to be compatible with older CMake package configurations
-set (@PACKAGE_PREFIX@_LIBRARIES "${@PACKAGE_PREFIX@_TARGET}")
-
-# set @PACKAGE_NAME@_* variables for backwards compatibility
-if (NOT "^@PACKAGE_NAME@$" STREQUAL "^@PACKAGE_PREFIX@$")
-  foreach (_@PACKAGE_PREFIX@_VARIABLE IN ITEMS
-    VERSION_STRING
-    VERSION_MAJOR
-    VERSION_MINOR
-    VERSION_PATCH
-    INCLUDE_DIR
-    LIBRARIES
-    TARGET
-  )
-    set (@PACKAGE_NAME@_${_@PACKAGE_PREFIX@_VARIABLE} "${@PACKAGE_PREFIX@_${_@PACKAGE_PREFIX@_VARIABLE}}")
-  endforeach ()
-  unset (_@PACKAGE_PREFIX@_VARIABLE)
-endif ()
-
-# unset private variables
-unset (@PACKAGE_NAME@_FIND_COMPONENT)
-unset (_INSTALL_PREFIX)
diff --git a/third_party/gflags/cmake/execute_test.cmake b/third_party/gflags/cmake/execute_test.cmake
deleted file mode 100644
index df008cf..0000000
--- a/third_party/gflags/cmake/execute_test.cmake
+++ /dev/null
@@ -1,53 +0,0 @@
-# ----------------------------------------------------------------------------
-# sanitize string stored in variable for use in regular expression.
-macro (sanitize_for_regex STRVAR)
-  string (REGEX REPLACE "([.+*?^$()])" "\\\\\\1" ${STRVAR} "${${STRVAR}}")
-endmacro ()
-
-# ----------------------------------------------------------------------------
-# script arguments
-if (NOT COMMAND)
-  message (FATAL_ERROR "Test command not specified!")
-endif ()
-if (NOT DEFINED EXPECTED_RC)
-  set (EXPECTED_RC 0)
-endif ()
-if (EXPECTED_OUTPUT)
-  sanitize_for_regex(EXPECTED_OUTPUT)
-endif ()
-if (UNEXPECTED_OUTPUT)
-  sanitize_for_regex(UNEXPECTED_OUTPUT)
-endif ()
-
-# ----------------------------------------------------------------------------
-# set a few environment variables (useful for --tryfromenv)
-set (ENV{FLAGS_undefok} "foo,bar")
-set (ENV{FLAGS_weirdo}  "")
-set (ENV{FLAGS_version} "true")
-set (ENV{FLAGS_help}    "false")
-
-# ----------------------------------------------------------------------------
-# execute test command
-execute_process(
-  COMMAND ${COMMAND}
-  RESULT_VARIABLE RC
-  OUTPUT_VARIABLE OUTPUT
-  ERROR_VARIABLE  OUTPUT
-)
-
-if (OUTPUT)
-  message ("${OUTPUT}")
-endif ()
-
-# ----------------------------------------------------------------------------
-# check test result
-if (NOT RC EQUAL EXPECTED_RC)
-  string (REPLACE ";" " " COMMAND "${COMMAND}")
-  message (FATAL_ERROR "Command:\n\t${COMMAND}\nExit status is ${RC}, expected ${EXPECTED_RC}")
-endif ()
-if (EXPECTED_OUTPUT AND NOT OUTPUT MATCHES "${EXPECTED_OUTPUT}")
-  message (FATAL_ERROR "Test output does not match expected output: ${EXPECTED_OUTPUT}")
-endif ()
-if (UNEXPECTED_OUTPUT AND OUTPUT MATCHES "${UNEXPECTED_OUTPUT}")
-  message (FATAL_ERROR "Test output matches unexpected output: ${UNEXPECTED_OUTPUT}")
-endif ()
\ No newline at end of file
diff --git a/third_party/gflags/cmake/package.cmake.in b/third_party/gflags/cmake/package.cmake.in
deleted file mode 100644
index aaec792..0000000
--- a/third_party/gflags/cmake/package.cmake.in
+++ /dev/null
@@ -1,49 +0,0 @@
-# Per-generator CPack configuration file. See CPACK_PROJECT_CONFIG_FILE documented at
-# http://www.cmake.org/cmake/help/v2.8.12/cpack.html#variable:CPACK_PROJECT_CONFIG_FILE
-#
-# All common CPACK_* variables are set in CMakeLists.txt already. This file only
-# overrides some of these to provide package generator specific settings.
-
-# whether package contains all development files or only runtime files
-set (DEVEL @INSTALL_HEADERS@)
-
-# ------------------------------------------------------------------------------
-# Mac OS X package
-if (CPACK_GENERATOR MATCHES "PackageMaker|DragNDrop")
-
-  set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
-  if (DEVEL)
-    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-devel")
-  endif ()
-  set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_PACKAGE_VERSION}")
-
-# ------------------------------------------------------------------------------
-# Debian package
-elseif (CPACK_GENERATOR MATCHES "DEB")
-
-  set (CPACK_PACKAGE_FILE_NAME   "lib${CPACK_PACKAGE_NAME}")
-  if (DEVEL)
-    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-dev")
-  else ()
-    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}0")
-  endif ()
-  set (CPACK_PACKAGE_FILE_NAME   "${CPACK_PACKAGE_FILE_NAME}_${CPACK_PACKAGE_VERSION}-1_${CPACK_PACKAGE_ARCHITECTURE}")
-
-  set (CPACK_DEBIAN_PACKAGE_DEPENDS)
-  set (CPACK_DEBIAN_PACKAGE_SECTION      "devel")
-  set (CPACK_DEBIAN_PACKAGE_PRIORITY     "optional")
-  set (CPACK_DEBIAN_PACKAGE_HOMEPAGE     "${CPACK_RPM_PACKAGE_URL}")
-  set (CPACK_DEBIAN_PACKAGE_MAINTAINER   "${CPACK_PACKAGE_VENDOR}")
-  set (CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_PACKAGE_ARCHITECTURE}")
-
-# ------------------------------------------------------------------------------
-# RPM package
-elseif (CPACK_GENERATOR MATCHES "RPM")
-
-  set (CPACK_PACKAGE_FILE_NAME   "${CPACK_PACKAGE_NAME}")
-  if (DEVEL)
-    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-devel")
-  endif ()
-  set (CPACK_PACKAGE_FILE_NAME   "${CPACK_PACKAGE_FILE_NAME}-${CPACK_PACKAGE_VERSION}-1.${CPACK_PACKAGE_ARCHITECTURE}")
-
-endif ()
diff --git a/third_party/gflags/cmake/package.pc.in b/third_party/gflags/cmake/package.pc.in
deleted file mode 100644
index 80df818..0000000
--- a/third_party/gflags/cmake/package.pc.in
+++ /dev/null
@@ -1,14 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-bindir=${prefix}/@RUNTIME_INSTALL_DIR@
-libdir=${prefix}/@LIBRARY_INSTALL_DIR@
-includedir=${prefix}/@INCLUDE_INSTALL_DIR@
-
-Name: @PACKAGE_NAME@
-Version: @PACKAGE_VERSION@
-Description: @PACKAGE_DESCRIPTION@
-URL: @PACKAGE_URL@
-Requires:
-Libs: -L${libdir} -lgflags
-Libs.private: -lpthread 
-Cflags: -I${includedir}
diff --git a/third_party/gflags/cmake/utils.cmake b/third_party/gflags/cmake/utils.cmake
deleted file mode 100644
index d039e5c..0000000
--- a/third_party/gflags/cmake/utils.cmake
+++ /dev/null
@@ -1,205 +0,0 @@
-## Utility CMake functions.
-
-# ----------------------------------------------------------------------------
-## Convert boolean value to 0 or 1
-macro (bool_to_int VAR)
-  if (${VAR})
-    set (${VAR} 1)
-  else ()
-    set (${VAR} 0)
-  endif ()
-endmacro ()
-
-# ----------------------------------------------------------------------------
-## Extract version numbers from version string
-function (version_numbers version major minor patch)
-  if (version MATCHES "([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(rc[1-9][0-9]*|[a-z]+)?")
-    if (CMAKE_MATCH_1)
-      set (_major ${CMAKE_MATCH_1})
-    else ()
-      set (_major 0)
-    endif ()
-    if (CMAKE_MATCH_2)
-      set (_minor ${CMAKE_MATCH_2})
-      string (REGEX REPLACE "^\\." "" _minor "${_minor}")
-    else ()
-      set (_minor 0)
-    endif ()
-    if (CMAKE_MATCH_3)
-      set (_patch ${CMAKE_MATCH_3})
-      string (REGEX REPLACE "^\\." "" _patch "${_patch}")
-    else ()
-      set (_patch 0)
-    endif ()
-  else ()
-    set (_major 0)
-    set (_minor 0)
-    set (_patch 0)
-  endif ()
-  set ("${major}" "${_major}" PARENT_SCOPE)
-  set ("${minor}" "${_minor}" PARENT_SCOPE)
-  set ("${patch}" "${_patch}" PARENT_SCOPE)
-endfunction ()
-
-# ----------------------------------------------------------------------------
-## Determine if cache entry exists
-macro (gflags_is_cached retvar varname)
-  if (DEFINED ${varname})
-    get_property (${retvar} CACHE ${varname} PROPERTY TYPE SET)
-  else ()
-    set (${retvar} FALSE)
-  endif ()
-endmacro ()
-
-# ----------------------------------------------------------------------------
-## Add gflags configuration variable
-#
-# The default value of the (cached) configuration value can be overridden either
-# on the CMake command-line or the super-project by setting the GFLAGS_<varname>
-# variable. When gflags is a subproject of another project (GFLAGS_IS_SUBPROJECT),
-# the variable is not added to the CMake cache. Otherwise it is cached.
-macro (gflags_define type varname docstring default)
-  # note that ARGC must be expanded here, as it is not a "real" variable
-  # (see the CMake documentation for the macro command)
-  if ("${ARGC}" GREATER 5)
-    message (FATAL_ERROR "gflags_variable: Too many macro arguments")
-  endif ()
-  if (NOT DEFINED GFLAGS_${varname})
-    if (GFLAGS_IS_SUBPROJECT AND "${ARGC}" EQUAL 5)
-      set (GFLAGS_${varname} "${ARGV4}")
-    else ()
-      set (GFLAGS_${varname} "${default}")
-    endif ()
-  endif ()
-  if (GFLAGS_IS_SUBPROJECT)
-    if (NOT DEFINED ${varname})
-      set (${varname} "${GFLAGS_${varname}}")
-    endif ()
-  else ()
-    set (${varname} "${GFLAGS_${varname}}" CACHE ${type} "${docstring}")
-  endif ()
-endmacro ()
-
-# ----------------------------------------------------------------------------
-## Set property of cached gflags configuration variable
-macro (gflags_property varname property value)
-  gflags_is_cached (_cached ${varname})
-  if (_cached)
-    # note that property must be expanded here, as it is not a "real" variable
-    # (see the CMake documentation for the macro command)
-    if ("${property}" STREQUAL "ADVANCED")
-      if (${value})
-        mark_as_advanced (FORCE ${varname})
-      else ()
-        mark_as_advanced (CLEAR ${varname})
-      endif ()
-    else ()
-      set_property (CACHE ${varname} PROPERTY "${property}" "${value}")
-    endif ()
-  endif ()
-  unset (_cached)
-endmacro ()
-
-# ----------------------------------------------------------------------------
-## Modify value of gflags configuration variable
-macro (gflags_set varname value)
-  gflags_is_cached (_cached ${varname})
-  if (_cached)
-    set_property (CACHE ${varname} PROPERTY VALUE "${value}")
-  else ()
-    set (${varname} "${value}")
-  endif ()
-  unset (_cached)
-endmacro ()
-
-# ----------------------------------------------------------------------------
-## Configure public header files
-function (configure_headers out)
-  set (tmp)
-  foreach (src IN LISTS ARGN)
-    if (IS_ABSOLUTE "${src}")
-      list (APPEND tmp "${src}")
-    elseif (EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in")
-      configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" @ONLY)
-      list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}")
-    else ()
-	    configure_file ("${PROJECT_SOURCE_DIR}/src/${src}" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" COPYONLY)
-      list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}")
-    endif ()
-  endforeach ()
-  set (${out} "${tmp}" PARENT_SCOPE)
-endfunction ()
-
-# ----------------------------------------------------------------------------
-## Configure source files with .in suffix
-function (configure_sources out)
-  set (tmp)
-  foreach (src IN LISTS ARGN)
-    if (src MATCHES ".h$" AND EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in")
-      configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" @ONLY)
-      list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}")
-    else ()
-      list (APPEND tmp "${PROJECT_SOURCE_DIR}/src/${src}")
-    endif ()
-  endforeach ()
-  set (${out} "${tmp}" PARENT_SCOPE)
-endfunction ()
-
-# ----------------------------------------------------------------------------
-## Add usage test
-#
-# Using PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION would
-# do as well, but CMake/CTest does not allow us to specify an
-# expected exit status. Moreover, the execute_test.cmake script
-# sets environment variables needed by the --fromenv/--tryfromenv tests.
-macro (add_gflags_test name expected_rc expected_output unexpected_output cmd)
-  set (args "--test_tmpdir=${PROJECT_BINARY_DIR}/Testing/Temporary"
-            "--srcdir=${PROJECT_SOURCE_DIR}/test")
-  add_test (
-    NAME    ${name}
-    COMMAND "${CMAKE_COMMAND}" "-DCOMMAND:STRING=$<TARGET_FILE:${cmd}>;${args};${ARGN}"
-                               "-DEXPECTED_RC:STRING=${expected_rc}"
-                               "-DEXPECTED_OUTPUT:STRING=${expected_output}"
-                               "-DUNEXPECTED_OUTPUT:STRING=${unexpected_output}"
-                               -P "${PROJECT_SOURCE_DIR}/cmake/execute_test.cmake"
-    WORKING_DIRECTORY "${GFLAGS_FLAGFILES_DIR}"
-  )
-endmacro ()
-
-# ------------------------------------------------------------------------------
-## Register installed package with CMake
-#
-# This function adds an entry to the CMake registry for packages with the
-# path of the directory where the package configuration file of the installed
-# package is located in order to help CMake find the package in a custom
-# installation prefix. This differs from CMake's export(PACKAGE) command
-# which registers the build directory instead.
-function (register_gflags_package CONFIG_DIR)
-  if (NOT IS_ABSOLUTE "${CONFIG_DIR}")
-    set (CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_DIR}")
-  endif ()
-  string (MD5 REGISTRY_ENTRY "${CONFIG_DIR}")
-  if (WIN32)
-    install (CODE
-      "execute_process (
-         COMMAND reg add \"HKCU\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\" /v \"${REGISTRY_ENTRY}\" /d \"${CONFIG_DIR}\" /t REG_SZ /f
-         RESULT_VARIABLE RT
-         ERROR_VARIABLE  ERR
-         OUTPUT_QUIET
-       )
-       if (RT EQUAL 0)
-         message (STATUS \"Register:   Added HKEY_CURRENT_USER\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\\\\${REGISTRY_ENTRY}\")
-       else ()
-         string (STRIP \"\${ERR}\" ERR)
-         message (STATUS \"Register:   Failed to add registry entry: \${ERR}\")
-       endif ()"
-    )
-  elseif (IS_DIRECTORY "$ENV{HOME}")
-    file (WRITE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry" "${CONFIG_DIR}")
-    install (
-      FILES       "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry"
-      DESTINATION "$ENV{HOME}/.cmake/packages/${PACKAGE_NAME}"
-      RENAME      "${REGISTRY_ENTRY}"
-    )
-  endif ()
-endfunction ()
diff --git a/third_party/gflags/cmake/version.cmake.in b/third_party/gflags/cmake/version.cmake.in
deleted file mode 100644
index 1e1af05..0000000
--- a/third_party/gflags/cmake/version.cmake.in
+++ /dev/null
@@ -1,21 +0,0 @@
-## gflags CMake configuration version file
-
-# -----------------------------------------------------------------------------
-# library version
-set (PACKAGE_VERSION "@PACKAGE_VERSION@")
-
-# -----------------------------------------------------------------------------
-# check compatibility
-
-# Perform compatibility check here using the input CMake variables.
-# See example in http://www.cmake.org/Wiki/CMake_2.6_Notes.
-
-set (PACKAGE_VERSION_COMPATIBLE TRUE)
-set (PACKAGE_VERSION_UNSUITABLE FALSE)
-
-if ("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "@PACKAGE_VERSION_MAJOR@" AND
-    "${PACKAGE_FIND_VERSION_MINOR}" EQUAL "@PACKAGE_VERSION_MINOR@")
-  set (PACKAGE_VERSION_EXACT TRUE)
-else ()
-  set (PACKAGE_VERSION_EXACT FALSE)
-endif ()
diff --git a/third_party/gflags/doc b/third_party/gflags/doc
deleted file mode 160000
index 679df49..0000000
--- a/third_party/gflags/doc
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 679df49798e2d9766975399baf063446e0957bba
diff --git a/third_party/gflags/src/config.h b/third_party/gflags/src/config.h
deleted file mode 100644
index b90b7e6..0000000
--- a/third_party/gflags/src/config.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Note: This header file is only used internally. It is not part of public interface!
-
-#ifndef GFLAGS_CONFIG_H_
-#define GFLAGS_CONFIG_H_
-
-
-// ---------------------------------------------------------------------------
-// System checks
-
-// CMake build configuration is written to defines.h file, unused by Bazel build
-#if !defined(GFLAGS_BAZEL_BUILD)
-#  include "defines.h"
-#endif
-
-// gcc requires this to get PRId64, etc.
-#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
-#  define __STDC_FORMAT_MACROS 1
-#endif
-
-// ---------------------------------------------------------------------------
-// Path separator
-#ifndef PATH_SEPARATOR
-#  ifdef OS_WINDOWS
-#    define PATH_SEPARATOR  '\\'
-#  else
-#    define PATH_SEPARATOR  '/'
-#  endif
-#endif
-
-// ---------------------------------------------------------------------------
-// Windows
-
-// Always export symbols when compiling a shared library as this file is only
-// included by internal modules when building the gflags library itself.
-// The gflags_declare.h header file will set it to import these symbols otherwise.
-#ifndef GFLAGS_DLL_DECL
-#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
-#    define GFLAGS_DLL_DECL __declspec(dllexport)
-#  else
-#    define GFLAGS_DLL_DECL
-#  endif
-#endif
-// Flags defined by the gflags library itself must be exported
-#ifndef GFLAGS_DLL_DEFINE_FLAG
-#  define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
-#endif
-
-#ifdef OS_WINDOWS
-// The unittests import the symbols of the shared gflags library
-#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
-#    define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
-#  endif
-#  include "windows_port.h"
-#endif
-
-
-#endif // GFLAGS_CONFIG_H_
diff --git a/third_party/gflags/src/defines.h.in b/third_party/gflags/src/defines.h.in
deleted file mode 100644
index dfb214e..0000000
--- a/third_party/gflags/src/defines.h.in
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Generated from defines.h.in during build configuration using CMake. */
-
-// Note: This header file is only used internally. It is not part of public interface!
-//       Any cmakedefine is defined using the -D flag instead when Bazel is used.
-//       For Bazel, this file is thus not used to avoid a private file in $(GENDIR).
-
-#ifndef GFLAGS_DEFINES_H_
-#define GFLAGS_DEFINES_H_
-
-
-// Define if you build this library for a MS Windows OS.
-#cmakedefine OS_WINDOWS
-
-// Define if you have the <stdint.h> header file.
-#cmakedefine HAVE_STDINT_H
-
-// Define if you have the <sys/types.h> header file.
-#cmakedefine HAVE_SYS_TYPES_H
-
-// Define if you have the <inttypes.h> header file.
-#cmakedefine HAVE_INTTYPES_H
-
-// Define if you have the <sys/stat.h> header file.
-#cmakedefine HAVE_SYS_STAT_H
-
-// Define if you have the <unistd.h> header file.
-#cmakedefine HAVE_UNISTD_H
-
-// Define if you have the <fnmatch.h> header file.
-#cmakedefine HAVE_FNMATCH_H
-
-// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
-#cmakedefine HAVE_SHLWAPI_H
-
-// Define if you have the strtoll function.
-#cmakedefine HAVE_STRTOLL
-
-// Define if you have the strtoq function.
-#cmakedefine HAVE_STRTOQ
-
-// Define if you have the <pthread.h> header file.
-#cmakedefine HAVE_PTHREAD
-
-// Define if your pthread library defines the type pthread_rwlock_t
-#cmakedefine HAVE_RWLOCK
-
-
-#endif // GFLAGS_DEFINES_H_
diff --git a/third_party/gflags/src/gflags.cc b/third_party/gflags/src/gflags.cc
deleted file mode 100644
index e0171fe..0000000
--- a/third_party/gflags/src/gflags.cc
+++ /dev/null
@@ -1,2013 +0,0 @@
-// Copyright (c) 1999, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Revamped and reorganized by Craig Silverstein
-//
-// This file contains the implementation of all our command line flags
-// stuff.  Here's how everything fits together
-//
-// * FlagRegistry owns CommandLineFlags owns FlagValue.
-// * FlagSaver holds a FlagRegistry (saves it at construct time,
-//     restores it at destroy time).
-// * CommandLineFlagParser lives outside that hierarchy, but works on
-//     CommandLineFlags (modifying the FlagValues).
-// * Free functions like SetCommandLineOption() work via one of the
-//     above (such as CommandLineFlagParser).
-//
-// In more detail:
-//
-// -- The main classes that hold flag data:
-//
-// FlagValue holds the current value of a flag.  It's
-// pseudo-templatized: every operation on a FlagValue is typed.  It
-// also deals with storage-lifetime issues (so flag values don't go
-// away in a destructor), which is why we need a whole class to hold a
-// variable's value.
-//
-// CommandLineFlag is all the information about a single command-line
-// flag.  It has a FlagValue for the flag's current value, but also
-// the flag's name, type, etc.
-//
-// FlagRegistry is a collection of CommandLineFlags.  There's the
-// global registry, which is where flags defined via DEFINE_foo()
-// live.  But it's possible to define your own flag, manually, in a
-// different registry you create.  (In practice, multiple registries
-// are used only by FlagSaver).
-//
-// A given FlagValue is owned by exactly one CommandLineFlag.  A given
-// CommandLineFlag is owned by exactly one FlagRegistry.  FlagRegistry
-// has a lock; any operation that writes to a FlagValue or
-// CommandLineFlag owned by that registry must acquire the
-// FlagRegistry lock before doing so.
-//
-// --- Some other classes and free functions:
-//
-// CommandLineFlagInfo is a client-exposed version of CommandLineFlag.
-// Once it's instantiated, it has no dependencies or relationships
-// with any other part of this file.
-//
-// FlagRegisterer is the helper class used by the DEFINE_* macros to
-// allow work to be done at global initialization time.
-//
-// CommandLineFlagParser is the class that reads from the commandline
-// and instantiates flag values based on that.  It needs to poke into
-// the innards of the FlagValue->CommandLineFlag->FlagRegistry class
-// hierarchy to do that.  It's careful to acquire the FlagRegistry
-// lock before doing any writing or other non-const actions.
-//
-// GetCommandLineOption is just a hook into registry routines to
-// retrieve a flag based on its name.  SetCommandLineOption, on the
-// other hand, hooks into CommandLineFlagParser.  Other API functions
-// are, similarly, mostly hooks into the functionality described above.
-
-#include "config.h"
-#include "gflags/gflags.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#if defined(HAVE_FNMATCH_H)
-#  include <fnmatch.h>
-#elif defined(HAVE_SHLWAPI_H)
-#  define NO_SHLWAPI_ISOS
-#  include <shlwapi.h>
-#endif
-#include <stdarg.h> // For va_list and related operations
-#include <stdio.h>
-#include <string.h>
-
-#include <algorithm>
-#include <map>
-#include <string>
-#include <utility>     // for pair<>
-#include <vector>
-
-#include "mutex.h"
-#include "util.h"
-
-using namespace MUTEX_NAMESPACE;
-
-
-// Special flags, type 1: the 'recursive' flags.  They set another flag's val.
-DEFINE_string(flagfile,   "", "load flags from file");
-DEFINE_string(fromenv,    "", "set flags from the environment"
-                              " [use 'export FLAGS_flag1=value']");
-DEFINE_string(tryfromenv, "", "set flags from the environment if present");
-
-// Special flags, type 2: the 'parsing' flags.  They modify how we parse.
-DEFINE_string(undefok, "", "comma-separated list of flag names that it is okay to specify "
-                           "on the command line even if the program does not define a flag "
-                           "with that name.  IMPORTANT: flags in this list that have "
-                           "arguments MUST use the flag=value format");
-
-namespace GFLAGS_NAMESPACE {
-
-using std::map;
-using std::pair;
-using std::sort;
-using std::string;
-using std::vector;
-
-// This is used by the unittest to test error-exit code
-void GFLAGS_DLL_DECL (*gflags_exitfunc)(int) = &exit;  // from stdlib.h
-
-
-// The help message indicating that the commandline flag has been
-// 'stripped'. It will not show up when doing "-help" and its
-// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
-// before including base/gflags.h
-
-// This is used by this file, and also in gflags_reporting.cc
-const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
-
-namespace {
-
-// There are also 'reporting' flags, in gflags_reporting.cc.
-
-static const char kError[] = "ERROR: ";
-
-// Indicates that undefined options are to be ignored.
-// Enables deferred processing of flags in dynamically loaded libraries.
-static bool allow_command_line_reparsing = false;
-
-static bool logging_is_probably_set_up = false;
-
-// This is a 'prototype' validate-function.  'Real' validate
-// functions, take a flag-value as an argument: ValidateFn(bool) or
-// ValidateFn(uint64).  However, for easier storage, we strip off this
-// argument and then restore it when actually calling the function on
-// a flag value.
-typedef bool (*ValidateFnProto)();
-
-// Whether we should die when reporting an error.
-enum DieWhenReporting { DIE, DO_NOT_DIE };
-
-// Report Error and exit if requested.
-static void ReportError(DieWhenReporting should_die, const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  vfprintf(stderr, format, ap);
-  va_end(ap);
-  fflush(stderr);   // should be unnecessary, but cygwin's rxvt buffers stderr
-  if (should_die == DIE) gflags_exitfunc(1);
-}
-
-
-// --------------------------------------------------------------------
-// FlagValue
-//    This represent the value a single flag might have.  The major
-//    functionality is to convert from a string to an object of a
-//    given type, and back.  Thread-compatible.
-// --------------------------------------------------------------------
-
-class CommandLineFlag;
-class FlagValue {
- public:
-  enum ValueType {
-    FV_BOOL = 0,
-    FV_INT32 = 1,
-    FV_UINT32 = 2,
-    FV_INT64 = 3,
-    FV_UINT64 = 4,
-    FV_DOUBLE = 5,
-    FV_STRING = 6,
-    FV_MAX_INDEX = 6,
-  };
-
-  template <typename FlagType>
-  FlagValue(FlagType* valbuf, bool transfer_ownership_of_value);
-  ~FlagValue();
-
-  bool ParseFrom(const char* spec);
-  string ToString() const;
-
-  ValueType Type() const { return static_cast<ValueType>(type_); }
-
- private:
-  friend class CommandLineFlag;  // for many things, including Validate()
-  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // calls New()
-  friend class FlagRegistry;     // checks value_buffer_ for flags_by_ptr_ map
-  template <typename T> friend T GetFromEnv(const char*, T);
-  friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
-                             const char*, string*);  // for New(), CopyFrom()
-
-  template <typename FlagType>
-  struct FlagValueTraits;
-
-  const char* TypeName() const;
-  bool Equal(const FlagValue& x) const;
-  FlagValue* New() const;   // creates a new one with default value
-  void CopyFrom(const FlagValue& x);
-
-  // Calls the given validate-fn on value_buffer_, and returns
-  // whatever it returns.  But first casts validate_fn_proto to a
-  // function that takes our value as an argument (eg void
-  // (*validate_fn)(bool) for a bool flag).
-  bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
-
-  void* const value_buffer_;          // points to the buffer holding our data
-  const int8 type_;                   // how to interpret value_
-  const bool owns_value_;             // whether to free value on destruct
-
-  FlagValue(const FlagValue&);   // no copying!
-  void operator=(const FlagValue&);
-};
-
-// Map the given C++ type to a value of the ValueType enum at compile time.
-#define DEFINE_FLAG_TRAITS(type, value)        \
-  template <>                                  \
-  struct FlagValue::FlagValueTraits<type> {    \
-    static const ValueType kValueType = value; \
-  }
-
-// Define full template specializations of the FlagValueTraits template
-// for all supported flag types.
-DEFINE_FLAG_TRAITS(bool, FV_BOOL);
-DEFINE_FLAG_TRAITS(int32, FV_INT32);
-DEFINE_FLAG_TRAITS(uint32, FV_UINT32);
-DEFINE_FLAG_TRAITS(int64, FV_INT64);
-DEFINE_FLAG_TRAITS(uint64, FV_UINT64);
-DEFINE_FLAG_TRAITS(double, FV_DOUBLE);
-DEFINE_FLAG_TRAITS(std::string, FV_STRING);
-
-#undef DEFINE_FLAG_TRAITS
-
-
-// This could be a templated method of FlagValue, but doing so adds to the
-// size of the .o.  Since there's no type-safety here anyway, macro is ok.
-#define VALUE_AS(type)  *reinterpret_cast<type*>(value_buffer_)
-#define OTHER_VALUE_AS(fv, type)  *reinterpret_cast<type*>(fv.value_buffer_)
-#define SET_VALUE_AS(type, value)  VALUE_AS(type) = (value)
-
-template <typename FlagType>
-FlagValue::FlagValue(FlagType* valbuf,
-                     bool transfer_ownership_of_value)
-    : value_buffer_(valbuf),
-      type_(FlagValueTraits<FlagType>::kValueType),
-      owns_value_(transfer_ownership_of_value) {
-}
-
-FlagValue::~FlagValue() {
-  if (!owns_value_) {
-    return;
-  }
-  switch (type_) {
-    case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break;
-    case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break;
-    case FV_UINT32: delete reinterpret_cast<uint32*>(value_buffer_); break;
-    case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break;
-    case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break;
-    case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break;
-    case FV_STRING: delete reinterpret_cast<string*>(value_buffer_); break;
-  }
-}
-
-bool FlagValue::ParseFrom(const char* value) {
-  if (type_ == FV_BOOL) {
-    const char* kTrue[] = { "1", "t", "true", "y", "yes" };
-    const char* kFalse[] = { "0", "f", "false", "n", "no" };
-    COMPILE_ASSERT(sizeof(kTrue) == sizeof(kFalse), true_false_equal);
-    for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
-      if (strcasecmp(value, kTrue[i]) == 0) {
-        SET_VALUE_AS(bool, true);
-        return true;
-      } else if (strcasecmp(value, kFalse[i]) == 0) {
-        SET_VALUE_AS(bool, false);
-        return true;
-      }
-    }
-    return false;   // didn't match a legal input
-
-  } else if (type_ == FV_STRING) {
-    SET_VALUE_AS(string, value);
-    return true;
-  }
-
-  // OK, it's likely to be numeric, and we'll be using a strtoXXX method.
-  if (value[0] == '\0')   // empty-string is only allowed for string type.
-    return false;
-  char* end;
-  // Leading 0x puts us in base 16.  But leading 0 does not put us in base 8!
-  // It caused too many bugs when we had that behavior.
-  int base = 10;    // by default
-  if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
-    base = 16;
-  errno = 0;
-
-  switch (type_) {
-    case FV_INT32: {
-      const int64 r = strto64(value, &end, base);
-      if (errno || end != value + strlen(value))  return false;  // bad parse
-      if (static_cast<int32>(r) != r)  // worked, but number out of range
-        return false;
-      SET_VALUE_AS(int32, static_cast<int32>(r));
-      return true;
-    }
-    case FV_UINT32: {
-      while (*value == ' ') value++;
-      if (*value == '-') return false;  // negative number
-      const uint64 r = strtou64(value, &end, base);
-      if (errno || end != value + strlen(value))  return false;  // bad parse
-        if (static_cast<uint32>(r) != r)  // worked, but number out of range
-        return false;
-      SET_VALUE_AS(uint32, static_cast<uint32>(r));
-      return true;
-    }
-    case FV_INT64: {
-      const int64 r = strto64(value, &end, base);
-      if (errno || end != value + strlen(value))  return false;  // bad parse
-      SET_VALUE_AS(int64, r);
-      return true;
-    }
-    case FV_UINT64: {
-      while (*value == ' ') value++;
-      if (*value == '-') return false;  // negative number
-      const uint64 r = strtou64(value, &end, base);
-      if (errno || end != value + strlen(value))  return false;  // bad parse
-      SET_VALUE_AS(uint64, r);
-      return true;
-    }
-    case FV_DOUBLE: {
-      const double r = strtod(value, &end);
-      if (errno || end != value + strlen(value))  return false;  // bad parse
-      SET_VALUE_AS(double, r);
-      return true;
-    }
-    default: {
-      assert(false);  // unknown type
-      return false;
-    }
-  }
-}
-
-string FlagValue::ToString() const {
-  char intbuf[64];    // enough to hold even the biggest number
-  switch (type_) {
-    case FV_BOOL:
-      return VALUE_AS(bool) ? "true" : "false";
-    case FV_INT32:
-      snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32));
-      return intbuf;
-    case FV_UINT32:
-      snprintf(intbuf, sizeof(intbuf), "%" PRIu32, VALUE_AS(uint32));
-      return intbuf;
-    case FV_INT64:
-      snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64));
-      return intbuf;
-    case FV_UINT64:
-      snprintf(intbuf, sizeof(intbuf), "%" PRIu64, VALUE_AS(uint64));
-      return intbuf;
-    case FV_DOUBLE:
-      snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
-      return intbuf;
-    case FV_STRING:
-      return VALUE_AS(string);
-    default:
-      assert(false);
-      return "";  // unknown type
-  }
-}
-
-bool FlagValue::Validate(const char* flagname,
-                         ValidateFnProto validate_fn_proto) const {
-  switch (type_) {
-    case FV_BOOL:
-      return reinterpret_cast<bool (*)(const char*, bool)>(
-          validate_fn_proto)(flagname, VALUE_AS(bool));
-    case FV_INT32:
-      return reinterpret_cast<bool (*)(const char*, int32)>(
-          validate_fn_proto)(flagname, VALUE_AS(int32));
-    case FV_UINT32:
-      return reinterpret_cast<bool (*)(const char*, uint32)>(
-          validate_fn_proto)(flagname, VALUE_AS(uint32));
-    case FV_INT64:
-      return reinterpret_cast<bool (*)(const char*, int64)>(
-          validate_fn_proto)(flagname, VALUE_AS(int64));
-    case FV_UINT64:
-      return reinterpret_cast<bool (*)(const char*, uint64)>(
-          validate_fn_proto)(flagname, VALUE_AS(uint64));
-    case FV_DOUBLE:
-      return reinterpret_cast<bool (*)(const char*, double)>(
-          validate_fn_proto)(flagname, VALUE_AS(double));
-    case FV_STRING:
-      return reinterpret_cast<bool (*)(const char*, const string&)>(
-          validate_fn_proto)(flagname, VALUE_AS(string));
-    default:
-      assert(false);  // unknown type
-      return false;
-  }
-}
-
-const char* FlagValue::TypeName() const {
-  static const char types[] =
-      "bool\0xx"
-      "int32\0x"
-      "uint32\0"
-      "int64\0x"
-      "uint64\0"
-      "double\0"
-      "string";
-  if (type_ > FV_MAX_INDEX) {
-    assert(false);
-    return "";
-  }
-  // Directly indexing the strings in the 'types' string, each of them is 7 bytes long.
-  return &types[type_ * 7];
-}
-
-bool FlagValue::Equal(const FlagValue& x) const {
-  if (type_ != x.type_)
-    return false;
-  switch (type_) {
-    case FV_BOOL:   return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool);
-    case FV_INT32:  return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32);
-    case FV_UINT32: return VALUE_AS(uint32) == OTHER_VALUE_AS(x, uint32);
-    case FV_INT64:  return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64);
-    case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
-    case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
-    case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string);
-    default: assert(false); return false;  // unknown type
-  }
-}
-
-FlagValue* FlagValue::New() const {
-  switch (type_) {
-    case FV_BOOL:   return new FlagValue(new bool(false), true);
-    case FV_INT32:  return new FlagValue(new int32(0), true);
-    case FV_UINT32: return new FlagValue(new uint32(0), true);
-    case FV_INT64:  return new FlagValue(new int64(0), true);
-    case FV_UINT64: return new FlagValue(new uint64(0), true);
-    case FV_DOUBLE: return new FlagValue(new double(0.0), true);
-    case FV_STRING: return new FlagValue(new string, true);
-    default: assert(false); return NULL;  // unknown type
-  }
-}
-
-void FlagValue::CopyFrom(const FlagValue& x) {
-  assert(type_ == x.type_);
-  switch (type_) {
-    case FV_BOOL:   SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool));      break;
-    case FV_INT32:  SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32));    break;
-    case FV_UINT32: SET_VALUE_AS(uint32, OTHER_VALUE_AS(x, uint32));  break;
-    case FV_INT64:  SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64));    break;
-    case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64));  break;
-    case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double));  break;
-    case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string));  break;
-    default: assert(false);  // unknown type
-  }
-}
-
-// --------------------------------------------------------------------
-// CommandLineFlag
-//    This represents a single flag, including its name, description,
-//    default value, and current value.  Mostly this serves as a
-//    struct, though it also knows how to register itself.
-//       All CommandLineFlags are owned by a (exactly one)
-//    FlagRegistry.  If you wish to modify fields in this class, you
-//    should acquire the FlagRegistry lock for the registry that owns
-//    this flag.
-// --------------------------------------------------------------------
-
-class CommandLineFlag {
- public:
-  // Note: we take over memory-ownership of current_val and default_val.
-  CommandLineFlag(const char* name, const char* help, const char* filename,
-                  FlagValue* current_val, FlagValue* default_val);
-  ~CommandLineFlag();
-
-  const char* name() const { return name_; }
-  const char* help() const { return help_; }
-  const char* filename() const { return file_; }
-  const char* CleanFileName() const;  // nixes irrelevant prefix such as homedir
-  string current_value() const { return current_->ToString(); }
-  string default_value() const { return defvalue_->ToString(); }
-  const char* type_name() const { return defvalue_->TypeName(); }
-  ValidateFnProto validate_function() const { return validate_fn_proto_; }
-  const void* flag_ptr() const { return current_->value_buffer_; }
-
-  FlagValue::ValueType Type() const { return defvalue_->Type(); }
-
-  void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
-
-  // If validate_fn_proto_ is non-NULL, calls it on value, returns result.
-  bool Validate(const FlagValue& value) const;
-  bool ValidateCurrent() const { return Validate(*current_); }
-  bool Modified() const { return modified_; }
-
- private:
-  // for SetFlagLocked() and setting flags_by_ptr_
-  friend class FlagRegistry;
-  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // for cloning the values
-  // set validate_fn
-  friend bool AddFlagValidator(const void*, ValidateFnProto);
-
-  // This copies all the non-const members: modified, processed, defvalue, etc.
-  void CopyFrom(const CommandLineFlag& src);
-
-  void UpdateModifiedBit();
-
-  const char* const name_;     // Flag name
-  const char* const help_;     // Help message
-  const char* const file_;     // Which file did this come from?
-  bool modified_;              // Set after default assignment?
-  FlagValue* defvalue_;        // Default value for flag
-  FlagValue* current_;         // Current value for flag
-  // This is a casted, 'generic' version of validate_fn, which actually
-  // takes a flag-value as an arg (void (*validate_fn)(bool), say).
-  // When we pass this to current_->Validate(), it will cast it back to
-  // the proper type.  This may be NULL to mean we have no validate_fn.
-  ValidateFnProto validate_fn_proto_;
-
-  CommandLineFlag(const CommandLineFlag&);   // no copying!
-  void operator=(const CommandLineFlag&);
-};
-
-CommandLineFlag::CommandLineFlag(const char* name, const char* help,
-                                 const char* filename,
-                                 FlagValue* current_val, FlagValue* default_val)
-    : name_(name), help_(help), file_(filename), modified_(false),
-      defvalue_(default_val), current_(current_val), validate_fn_proto_(NULL) {
-}
-
-CommandLineFlag::~CommandLineFlag() {
-  delete current_;
-  delete defvalue_;
-}
-
-const char* CommandLineFlag::CleanFileName() const {
-  // This function has been used to strip off a common prefix from
-  // flag source file names. Because flags can be defined in different
-  // shared libraries, there may not be a single common prefix.
-  // Further, this functionality hasn't been active for many years.
-  // Need a better way to produce more user friendly help output or
-  // "anonymize" file paths in help output, respectively.
-  // Follow issue at: https://github.com/gflags/gflags/issues/86
-  return filename();
-}
-
-void CommandLineFlag::FillCommandLineFlagInfo(
-    CommandLineFlagInfo* result) {
-  result->name = name();
-  result->type = type_name();
-  result->description = help();
-  result->current_value = current_value();
-  result->default_value = default_value();
-  result->filename = CleanFileName();
-  UpdateModifiedBit();
-  result->is_default = !modified_;
-  result->has_validator_fn = validate_function() != NULL;
-  result->flag_ptr = flag_ptr();
-}
-
-void CommandLineFlag::UpdateModifiedBit() {
-  // Update the "modified" bit in case somebody bypassed the
-  // Flags API and wrote directly through the FLAGS_name variable.
-  if (!modified_ && !current_->Equal(*defvalue_)) {
-    modified_ = true;
-  }
-}
-
-void CommandLineFlag::CopyFrom(const CommandLineFlag& src) {
-  // Note we only copy the non-const members; others are fixed at construct time
-  if (modified_ != src.modified_) modified_ = src.modified_;
-  if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_);
-  if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_);
-  if (validate_fn_proto_ != src.validate_fn_proto_)
-    validate_fn_proto_ = src.validate_fn_proto_;
-}
-
-bool CommandLineFlag::Validate(const FlagValue& value) const {
-
-  if (validate_function() == NULL)
-    return true;
-  else
-    return value.Validate(name(), validate_function());
-}
-
-
-// --------------------------------------------------------------------
-// FlagRegistry
-//    A FlagRegistry singleton object holds all flag objects indexed
-//    by their names so that if you know a flag's name (as a C
-//    string), you can access or set it.  If the function is named
-//    FooLocked(), you must own the registry lock before calling
-//    the function; otherwise, you should *not* hold the lock, and
-//    the function will acquire it itself if needed.
-// --------------------------------------------------------------------
-
-struct StringCmp {  // Used by the FlagRegistry map class to compare char*'s
-  bool operator() (const char* s1, const char* s2) const {
-    return (strcmp(s1, s2) < 0);
-  }
-};
-
-
-class FlagRegistry {
- public:
-  FlagRegistry() {
-  }
-  ~FlagRegistry() {
-    // Not using STLDeleteElements as that resides in util and this
-    // class is base.
-    for (FlagMap::iterator p = flags_.begin(), e = flags_.end(); p != e; ++p) {
-      CommandLineFlag* flag = p->second;
-      delete flag;
-    }
-  }
-
-  static void DeleteGlobalRegistry() {
-    delete global_registry_;
-    global_registry_ = NULL;
-  }
-
-  // Store a flag in this registry.  Takes ownership of the given pointer.
-  void RegisterFlag(CommandLineFlag* flag);
-
-  void Lock() { lock_.Lock(); }
-  void Unlock() { lock_.Unlock(); }
-
-  // Returns the flag object for the specified name, or NULL if not found.
-  CommandLineFlag* FindFlagLocked(const char* name);
-
-  // Returns the flag object whose current-value is stored at flag_ptr.
-  // That is, for whom current_->value_buffer_ == flag_ptr
-  CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr);
-
-  // A fancier form of FindFlag that works correctly if name is of the
-  // form flag=value.  In that case, we set key to point to flag, and
-  // modify v to point to the value (if present), and return the flag
-  // with the given name.  If the flag does not exist, returns NULL
-  // and sets error_message.
-  CommandLineFlag* SplitArgumentLocked(const char* argument,
-                                       string* key, const char** v,
-                                       string* error_message);
-
-  // Set the value of a flag.  If the flag was successfully set to
-  // value, set msg to indicate the new flag-value, and return true.
-  // Otherwise, set msg to indicate the error, leave flag unchanged,
-  // and return false.  msg can be NULL.
-  bool SetFlagLocked(CommandLineFlag* flag, const char* value,
-                     FlagSettingMode set_mode, string* msg);
-
-  static FlagRegistry* GlobalRegistry();   // returns a singleton registry
-
- private:
-  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // reads all the flags in order to copy them
-  friend class CommandLineFlagParser;    // for ValidateUnmodifiedFlags
-  friend void GFLAGS_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
-
-  // The map from name to flag, for FindFlagLocked().
-  typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
-  typedef FlagMap::iterator FlagIterator;
-  typedef FlagMap::const_iterator FlagConstIterator;
-  FlagMap flags_;
-
-  // The map from current-value pointer to flag, fo FindFlagViaPtrLocked().
-  typedef map<const void*, CommandLineFlag*> FlagPtrMap;
-  FlagPtrMap flags_by_ptr_;
-
-  static FlagRegistry* global_registry_;   // a singleton registry
-
-  Mutex lock_;
-
-  static void InitGlobalRegistry();
-
-  // Disallow
-  FlagRegistry(const FlagRegistry&);
-  FlagRegistry& operator=(const FlagRegistry&);
-};
-
-class FlagRegistryLock {
- public:
-  explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
-  ~FlagRegistryLock() { fr_->Unlock(); }
- private:
-  FlagRegistry *const fr_;
-};
-
-
-void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
-  Lock();
-  pair<FlagIterator, bool> ins =
-    flags_.insert(pair<const char*, CommandLineFlag*>(flag->name(), flag));
-  if (ins.second == false) {   // means the name was already in the map
-    if (strcmp(ins.first->second->filename(), flag->filename()) != 0) {
-      ReportError(DIE, "ERROR: flag '%s' was defined more than once "
-                  "(in files '%s' and '%s').\n",
-                  flag->name(),
-                  ins.first->second->filename(),
-                  flag->filename());
-    } else {
-      ReportError(DIE, "ERROR: something wrong with flag '%s' in file '%s'.  "
-                  "One possibility: file '%s' is being linked both statically "
-                  "and dynamically into this executable.\n",
-                  flag->name(),
-                  flag->filename(), flag->filename());
-    }
-  }
-  // Also add to the flags_by_ptr_ map.
-  flags_by_ptr_[flag->current_->value_buffer_] = flag;
-  Unlock();
-}
-
-CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) {
-  FlagConstIterator i = flags_.find(name);
-  if (i == flags_.end()) {
-    // If the name has dashes in it, try again after replacing with
-    // underscores.
-    if (strchr(name, '-') == NULL) return NULL;
-    string name_rep = name;
-    std::replace(name_rep.begin(), name_rep.end(), '-', '_');
-    return FindFlagLocked(name_rep.c_str());
-  } else {
-    return i->second;
-  }
-}
-
-CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) {
-  FlagPtrMap::const_iterator i = flags_by_ptr_.find(flag_ptr);
-  if (i == flags_by_ptr_.end()) {
-    return NULL;
-  } else {
-    return i->second;
-  }
-}
-
-CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
-                                                   string* key,
-                                                   const char** v,
-                                                   string* error_message) {
-  // Find the flag object for this option
-  const char* flag_name;
-  const char* value = strchr(arg, '=');
-  if (value == NULL) {
-    key->assign(arg);
-    *v = NULL;
-  } else {
-    // Strip out the "=value" portion from arg
-    key->assign(arg, value-arg);
-    *v = ++value;    // advance past the '='
-  }
-  flag_name = key->c_str();
-
-  CommandLineFlag* flag = FindFlagLocked(flag_name);
-
-  if (flag == NULL) {
-    // If we can't find the flag-name, then we should return an error.
-    // The one exception is if 1) the flag-name is 'nox', 2) there
-    // exists a flag named 'x', and 3) 'x' is a boolean flag.
-    // In that case, we want to return flag 'x'.
-    if (!(flag_name[0] == 'n' && flag_name[1] == 'o')) {
-      // flag-name is not 'nox', so we're not in the exception case.
-      *error_message = StringPrintf("%sunknown command line flag '%s'\n",
-                                    kError, key->c_str());
-      return NULL;
-    }
-    flag = FindFlagLocked(flag_name+2);
-    if (flag == NULL) {
-      // No flag named 'x' exists, so we're not in the exception case.
-      *error_message = StringPrintf("%sunknown command line flag '%s'\n",
-                                    kError, key->c_str());
-      return NULL;
-    }
-    if (flag->Type() != FlagValue::FV_BOOL) {
-      // 'x' exists but is not boolean, so we're not in the exception case.
-      *error_message = StringPrintf(
-          "%sboolean value (%s) specified for %s command line flag\n",
-          kError, key->c_str(), flag->type_name());
-      return NULL;
-    }
-    // We're in the exception case!
-    // Make up a fake value to replace the "no" we stripped out
-    key->assign(flag_name+2);   // the name without the "no"
-    *v = "0";
-  }
-
-  // Assign a value if this is a boolean flag
-  if (*v == NULL && flag->Type() == FlagValue::FV_BOOL) {
-    *v = "1";    // the --nox case was already handled, so this is the --x case
-  }
-
-  return flag;
-}
-
-bool TryParseLocked(const CommandLineFlag* flag, FlagValue* flag_value,
-                    const char* value, string* msg) {
-  // Use tenative_value, not flag_value, until we know value is valid.
-  FlagValue* tentative_value = flag_value->New();
-  if (!tentative_value->ParseFrom(value)) {
-    if (msg) {
-      StringAppendF(msg,
-                    "%sillegal value '%s' specified for %s flag '%s'\n",
-                    kError, value,
-                    flag->type_name(), flag->name());
-    }
-    delete tentative_value;
-    return false;
-  } else if (!flag->Validate(*tentative_value)) {
-    if (msg) {
-      StringAppendF(msg,
-          "%sfailed validation of new value '%s' for flag '%s'\n",
-          kError, tentative_value->ToString().c_str(),
-          flag->name());
-    }
-    delete tentative_value;
-    return false;
-  } else {
-    flag_value->CopyFrom(*tentative_value);
-    if (msg) {
-      StringAppendF(msg, "%s set to %s\n",
-                    flag->name(), flag_value->ToString().c_str());
-    }
-    delete tentative_value;
-    return true;
-  }
-}
-
-bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag,
-                                 const char* value,
-                                 FlagSettingMode set_mode,
-                                 string* msg) {
-  flag->UpdateModifiedBit();
-  switch (set_mode) {
-    case SET_FLAGS_VALUE: {
-      // set or modify the flag's value
-      if (!TryParseLocked(flag, flag->current_, value, msg))
-        return false;
-      flag->modified_ = true;
-      break;
-    }
-    case SET_FLAG_IF_DEFAULT: {
-      // set the flag's value, but only if it hasn't been set by someone else
-      if (!flag->modified_) {
-        if (!TryParseLocked(flag, flag->current_, value, msg))
-          return false;
-        flag->modified_ = true;
-      } else {
-        *msg = StringPrintf("%s set to %s",
-                            flag->name(), flag->current_value().c_str());
-      }
-      break;
-    }
-    case SET_FLAGS_DEFAULT: {
-      // modify the flag's default-value
-      if (!TryParseLocked(flag, flag->defvalue_, value, msg))
-        return false;
-      if (!flag->modified_) {
-        // Need to set both defvalue *and* current, in this case
-        TryParseLocked(flag, flag->current_, value, NULL);
-      }
-      break;
-    }
-    default: {
-      // unknown set_mode
-      assert(false);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-// Get the singleton FlagRegistry object
-FlagRegistry* FlagRegistry::global_registry_ = NULL;
-
-FlagRegistry* FlagRegistry::GlobalRegistry() {
-  static Mutex lock(Mutex::LINKER_INITIALIZED);
-  MutexLock acquire_lock(&lock);
-  if (!global_registry_) {
-    global_registry_ = new FlagRegistry;
-  }
-  return global_registry_;
-}
-
-// --------------------------------------------------------------------
-// CommandLineFlagParser
-//    Parsing is done in two stages.  In the first, we go through
-//    argv.  For every flag-like arg we can make sense of, we parse
-//    it and set the appropriate FLAGS_* variable.  For every flag-
-//    like arg we can't make sense of, we store it in a vector,
-//    along with an explanation of the trouble.  In stage 2, we
-//    handle the 'reporting' flags like --help and --mpm_version.
-//    (This is via a call to HandleCommandLineHelpFlags(), in
-//    gflags_reporting.cc.)
-//    An optional stage 3 prints out the error messages.
-//       This is a bit of a simplification.  For instance, --flagfile
-//    is handled as soon as it's seen in stage 1, not in stage 2.
-// --------------------------------------------------------------------
-
-class CommandLineFlagParser {
- public:
-  // The argument is the flag-registry to register the parsed flags in
-  explicit CommandLineFlagParser(FlagRegistry* reg) : registry_(reg) {}
-  ~CommandLineFlagParser() {}
-
-  // Stage 1: Every time this is called, it reads all flags in argv.
-  // However, it ignores all flags that have been successfully set
-  // before.  Typically this is only called once, so this 'reparsing'
-  // behavior isn't important.  It can be useful when trying to
-  // reparse after loading a dll, though.
-  uint32 ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags);
-
-  // Stage 2: print reporting info and exit, if requested.
-  // In gflags_reporting.cc:HandleCommandLineHelpFlags().
-
-  // Stage 3: validate all the commandline flags that have validators
-  // registered and were not set/modified by ParseNewCommandLineFlags.
-  void ValidateFlags(bool all);
-  void ValidateUnmodifiedFlags();
-
-  // Stage 4: report any errors and return true if any were found.
-  bool ReportErrors();
-
-  // Set a particular command line option.  "newval" is a string
-  // describing the new value that the option has been set to.  If
-  // option_name does not specify a valid option name, or value is not
-  // a valid value for option_name, newval is empty.  Does recursive
-  // processing for --flagfile and --fromenv.  Returns the new value
-  // if everything went ok, or empty-string if not.  (Actually, the
-  // return-string could hold many flag/value pairs due to --flagfile.)
-  // NB: Must have called registry_->Lock() before calling this function.
-  string ProcessSingleOptionLocked(CommandLineFlag* flag,
-                                   const char* value,
-                                   FlagSettingMode set_mode);
-
-  // Set a whole batch of command line options as specified by contentdata,
-  // which is in flagfile format (and probably has been read from a flagfile).
-  // Returns the new value if everything went ok, or empty-string if
-  // not.  (Actually, the return-string could hold many flag/value
-  // pairs due to --flagfile.)
-  // NB: Must have called registry_->Lock() before calling this function.
-  string ProcessOptionsFromStringLocked(const string& contentdata,
-                                        FlagSettingMode set_mode);
-
-  // These are the 'recursive' flags, defined at the top of this file.
-  // Whenever we see these flags on the commandline, we must take action.
-  // These are called by ProcessSingleOptionLocked and, similarly, return
-  // new values if everything went ok, or the empty-string if not.
-  string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode);
-  // diff fromenv/tryfromenv
-  string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode,
-                              bool errors_are_fatal);
-
- private:
-  FlagRegistry* const registry_;
-  map<string, string> error_flags_;      // map from name to error message
-  // This could be a set<string>, but we reuse the map to minimize the .o size
-  map<string, string> undefined_names_;  // --[flag] name was not registered
-};
-
-
-// Parse a list of (comma-separated) flags.
-static void ParseFlagList(const char* value, vector<string>* flags) {
-  for (const char *p = value; p && *p; value = p) {
-    p = strchr(value, ',');
-    size_t len;
-    if (p) {
-      len = p - value;
-      p++;
-    } else {
-      len = strlen(value);
-    }
-
-    if (len == 0)
-      ReportError(DIE, "ERROR: empty flaglist entry\n");
-    if (value[0] == '-')
-      ReportError(DIE, "ERROR: flag \"%*s\" begins with '-'\n", len, value);
-
-    flags->push_back(string(value, len));
-  }
-}
-
-// Snarf an entire file into a C++ string.  This is just so that we
-// can do all the I/O in one place and not worry about it everywhere.
-// Plus, it's convenient to have the whole file contents at hand.
-// Adds a newline at the end of the file.
-#define PFATAL(s)  do { perror(s); gflags_exitfunc(1); } while (0)
-
-static string ReadFileIntoString(const char* filename) {
-  const int kBufSize = 8092;
-  char buffer[kBufSize];
-  string s;
-  FILE* fp;
-  if ((errno = SafeFOpen(&fp, filename, "r")) != 0) PFATAL(filename);
-  size_t n;
-  while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
-    if (ferror(fp))  PFATAL(filename);
-    s.append(buffer, n);
-  }
-  fclose(fp);
-  return s;
-}
-
-uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
-                                                       bool remove_flags) {
-  int first_nonopt = *argc;        // for non-options moved to the end
-
-  registry_->Lock();
-  for (int i = 1; i < first_nonopt; i++) {
-    char* arg = (*argv)[i];
-
-    // Like getopt(), we permute non-option flags to be at the end.
-    if (arg[0] != '-' || arg[1] == '\0') {	// must be a program argument: "-" is an argument, not a flag
-      memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i]));
-      (*argv)[*argc-1] = arg;      // we go last
-      first_nonopt--;              // we've been pushed onto the stack
-      i--;                         // to undo the i++ in the loop
-      continue;
-    }
-    arg++;                     // skip leading '-'
-    if (arg[0] == '-') arg++;  // or leading '--'
-
-    // -- alone means what it does for GNU: stop options parsing
-    if (*arg == '\0') {
-      first_nonopt = i+1;
-      break;
-    }
-
-    // Find the flag object for this option
-    string key;
-    const char* value;
-    string error_message;
-    CommandLineFlag* flag = registry_->SplitArgumentLocked(arg, &key, &value,
-                                                           &error_message);
-    if (flag == NULL) {
-      undefined_names_[key] = "";    // value isn't actually used
-      error_flags_[key] = error_message;
-      continue;
-    }
-
-    if (value == NULL) {
-      // Boolean options are always assigned a value by SplitArgumentLocked()
-      assert(flag->Type() != FlagValue::FV_BOOL);
-      if (i+1 >= first_nonopt) {
-        // This flag needs a value, but there is nothing available
-        error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
-                             + " is missing its argument");
-        if (flag->help() && flag->help()[0] > '\001') {
-          // Be useful in case we have a non-stripped description.
-          error_flags_[key] += string("; flag description: ") + flag->help();
-        }
-        error_flags_[key] += "\n";
-        break;    // we treat this as an unrecoverable error
-      } else {
-        value = (*argv)[++i];                   // read next arg for value
-
-        // Heuristic to detect the case where someone treats a string arg
-        // like a bool:
-        // --my_string_var --foo=bar
-        // We look for a flag of string type, whose value begins with a
-        // dash, and where the flag-name and value are separated by a
-        // space rather than an '='.
-        // To avoid false positives, we also require the word "true"
-        // or "false" in the help string.  Without this, a valid usage
-        // "-lat -30.5" would trigger the warning.  The common cases we
-        // want to solve talk about true and false as values.
-        if (value[0] == '-'
-            && flag->Type() == FlagValue::FV_STRING
-            && (strstr(flag->help(), "true")
-                || strstr(flag->help(), "false"))) {
-          LOG(WARNING) << "Did you really mean to set flag '"
-                       << flag->name() << "' to the value '"
-                       << value << "'?";
-        }
-      }
-    }
-
-    // TODO(csilvers): only set a flag if we hadn't set it before here
-    ProcessSingleOptionLocked(flag, value, SET_FLAGS_VALUE);
-  }
-  registry_->Unlock();
-
-  if (remove_flags) {   // Fix up argc and argv by removing command line flags
-    (*argv)[first_nonopt-1] = (*argv)[0];
-    (*argv) += (first_nonopt-1);
-    (*argc) -= (first_nonopt-1);
-    first_nonopt = 1;   // because we still don't count argv[0]
-  }
-
-  logging_is_probably_set_up = true;   // because we've parsed --logdir, etc.
-
-  return first_nonopt;
-}
-
-string CommandLineFlagParser::ProcessFlagfileLocked(const string& flagval,
-                                                    FlagSettingMode set_mode) {
-  if (flagval.empty())
-    return "";
-
-  string msg;
-  vector<string> filename_list;
-  ParseFlagList(flagval.c_str(), &filename_list);  // take a list of filenames
-  for (size_t i = 0; i < filename_list.size(); ++i) {
-    const char* file = filename_list[i].c_str();
-    msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode);
-  }
-  return msg;
-}
-
-string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
-                                                   FlagSettingMode set_mode,
-                                                   bool errors_are_fatal) {
-  if (flagval.empty())
-    return "";
-
-  string msg;
-  vector<string> flaglist;
-  ParseFlagList(flagval.c_str(), &flaglist);
-
-  for (size_t i = 0; i < flaglist.size(); ++i) {
-    const char* flagname = flaglist[i].c_str();
-    CommandLineFlag* flag = registry_->FindFlagLocked(flagname);
-    if (flag == NULL) {
-      error_flags_[flagname] =
-          StringPrintf("%sunknown command line flag '%s' "
-                       "(via --fromenv or --tryfromenv)\n",
-                       kError, flagname);
-      undefined_names_[flagname] = "";
-      continue;
-    }
-
-    const string envname = string("FLAGS_") + string(flagname);
-    string envval;
-    if (!SafeGetEnv(envname.c_str(), envval)) {
-      if (errors_are_fatal) {
-        error_flags_[flagname] = (string(kError) + envname +
-                                  " not found in environment\n");
-      }
-      continue;
-    }
-
-    // Avoid infinite recursion.
-    if (envval == "fromenv" || envval == "tryfromenv") {
-      error_flags_[flagname] =
-          StringPrintf("%sinfinite recursion on environment flag '%s'\n",
-                       kError, envval.c_str());
-      continue;
-    }
-
-    msg += ProcessSingleOptionLocked(flag, envval.c_str(), set_mode);
-  }
-  return msg;
-}
-
-string CommandLineFlagParser::ProcessSingleOptionLocked(
-    CommandLineFlag* flag, const char* value, FlagSettingMode set_mode) {
-  string msg;
-  if (value && !registry_->SetFlagLocked(flag, value, set_mode, &msg)) {
-    error_flags_[flag->name()] = msg;
-    return "";
-  }
-
-  // The recursive flags, --flagfile and --fromenv and --tryfromenv,
-  // must be dealt with as soon as they're seen.  They will emit
-  // messages of their own.
-  if (strcmp(flag->name(), "flagfile") == 0) {
-    msg += ProcessFlagfileLocked(FLAGS_flagfile, set_mode);
-
-  } else if (strcmp(flag->name(), "fromenv") == 0) {
-    // last arg indicates envval-not-found is fatal (unlike in --tryfromenv)
-    msg += ProcessFromenvLocked(FLAGS_fromenv, set_mode, true);
-
-  } else if (strcmp(flag->name(), "tryfromenv") == 0) {
-    msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false);
-  }
-
-  return msg;
-}
-
-void CommandLineFlagParser::ValidateFlags(bool all) {
-  FlagRegistryLock frl(registry_);
-  for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin();
-       i != registry_->flags_.end(); ++i) {
-    if ((all || !i->second->Modified()) && !i->second->ValidateCurrent()) {
-      // only set a message if one isn't already there.  (If there's
-      // an error message, our job is done, even if it's not exactly
-      // the same error.)
-      if (error_flags_[i->second->name()].empty()) {
-        error_flags_[i->second->name()] =
-            string(kError) + "--" + i->second->name() +
-            " must be set on the commandline";
-        if (!i->second->Modified()) {
-          error_flags_[i->second->name()] += " (default value fails validation)";
-        }
-        error_flags_[i->second->name()] += "\n";
-      }
-    }
-  }
-}
-
-void CommandLineFlagParser::ValidateUnmodifiedFlags() {
-  ValidateFlags(false);
-}
-
-bool CommandLineFlagParser::ReportErrors() {
-  // error_flags_ indicates errors we saw while parsing.
-  // But we ignore undefined-names if ok'ed by --undef_ok
-  if (!FLAGS_undefok.empty()) {
-    vector<string> flaglist;
-    ParseFlagList(FLAGS_undefok.c_str(), &flaglist);
-    for (size_t i = 0; i < flaglist.size(); ++i) {
-      // We also deal with --no<flag>, in case the flagname was boolean
-      const string no_version = string("no") + flaglist[i];
-      if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) {
-        error_flags_[flaglist[i]] = "";    // clear the error message
-      } else if (undefined_names_.find(no_version) != undefined_names_.end()) {
-        error_flags_[no_version] = "";
-      }
-    }
-  }
-  // Likewise, if they decided to allow reparsing, all undefined-names
-  // are ok; we just silently ignore them now, and hope that a future
-  // parse will pick them up somehow.
-  if (allow_command_line_reparsing) {
-    for (map<string, string>::const_iterator it = undefined_names_.begin();
-         it != undefined_names_.end();  ++it)
-      error_flags_[it->first] = "";      // clear the error message
-  }
-
-  bool found_error = false;
-  string error_message;
-  for (map<string, string>::const_iterator it = error_flags_.begin();
-       it != error_flags_.end(); ++it) {
-    if (!it->second.empty()) {
-      error_message.append(it->second.data(), it->second.size());
-      found_error = true;
-    }
-  }
-  if (found_error)
-    ReportError(DO_NOT_DIE, "%s", error_message.c_str());
-  return found_error;
-}
-
-string CommandLineFlagParser::ProcessOptionsFromStringLocked(
-    const string& contentdata, FlagSettingMode set_mode) {
-  string retval;
-  const char* flagfile_contents = contentdata.c_str();
-  bool flags_are_relevant = true;   // set to false when filenames don't match
-  bool in_filename_section = false;
-
-  const char* line_end = flagfile_contents;
-  // We read this file a line at a time.
-  for (; line_end; flagfile_contents = line_end + 1) {
-    while (*flagfile_contents && isspace(*flagfile_contents))
-      ++flagfile_contents;
-    // Windows uses "\r\n"
-    line_end = strchr(flagfile_contents, '\r');
-    if (line_end == NULL)
-        line_end = strchr(flagfile_contents, '\n');
-
-    size_t len = line_end ? line_end - flagfile_contents
-                          : strlen(flagfile_contents);
-    string line(flagfile_contents, len);
-
-    // Each line can be one of four things:
-    // 1) A comment line -- we skip it
-    // 2) An empty line -- we skip it
-    // 3) A list of filenames -- starts a new filenames+flags section
-    // 4) A --flag=value line -- apply if previous filenames match
-    if (line.empty() || line[0] == '#') {
-      // comment or empty line; just ignore
-
-    } else if (line[0] == '-') {    // flag
-      in_filename_section = false;  // instead, it was a flag-line
-      if (!flags_are_relevant)      // skip this flag; applies to someone else
-        continue;
-
-      const char* name_and_val = line.c_str() + 1;    // skip the leading -
-      if (*name_and_val == '-')
-        name_and_val++;                               // skip second - too
-      string key;
-      const char* value;
-      string error_message;
-      CommandLineFlag* flag = registry_->SplitArgumentLocked(name_and_val,
-                                                             &key, &value,
-                                                             &error_message);
-      // By API, errors parsing flagfile lines are silently ignored.
-      if (flag == NULL) {
-        // "WARNING: flagname '" + key + "' not found\n"
-      } else if (value == NULL) {
-        // "WARNING: flagname '" + key + "' missing a value\n"
-      } else {
-        retval += ProcessSingleOptionLocked(flag, value, set_mode);
-      }
-
-    } else {                        // a filename!
-      if (!in_filename_section) {   // start over: assume filenames don't match
-        in_filename_section = true;
-        flags_are_relevant = false;
-      }
-
-      // Split the line up at spaces into glob-patterns
-      const char* space = line.c_str();   // just has to be non-NULL
-      for (const char* word = line.c_str(); *space; word = space+1) {
-        if (flags_are_relevant)     // we can stop as soon as we match
-          break;
-        space = strchr(word, ' ');
-        if (space == NULL)
-          space = word + strlen(word);
-        const string glob(word, space - word);
-        // We try matching both against the full argv0 and basename(argv0)
-        if (glob == ProgramInvocationName()       // small optimization
-            || glob == ProgramInvocationShortName()
-#if defined(HAVE_FNMATCH_H)
-            || fnmatch(glob.c_str(), ProgramInvocationName(),      FNM_PATHNAME) == 0
-            || fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0
-#elif defined(HAVE_SHLWAPI_H)
-            || PathMatchSpec(glob.c_str(), ProgramInvocationName())
-            || PathMatchSpec(glob.c_str(), ProgramInvocationShortName())
-#endif
-            ) {
-          flags_are_relevant = true;
-        }
-      }
-    }
-  }
-  return retval;
-}
-
-// --------------------------------------------------------------------
-// GetFromEnv()
-// AddFlagValidator()
-//    These are helper functions for routines like BoolFromEnv() and
-//    RegisterFlagValidator, defined below.  They're defined here so
-//    they can live in the unnamed namespace (which makes friendship
-//    declarations for these classes possible).
-// --------------------------------------------------------------------
-
-template<typename T>
-T GetFromEnv(const char *varname, T dflt) {
-  std::string valstr;
-  if (SafeGetEnv(varname, valstr)) {
-    FlagValue ifv(new T, true);
-    if (!ifv.ParseFrom(valstr.c_str())) {
-      ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
-                  varname, valstr.c_str());
-    }
-    return OTHER_VALUE_AS(ifv, T);
-  } else return dflt;
-}
-
-bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
-  // We want a lock around this routine, in case two threads try to
-  // add a validator (hopefully the same one!) at once.  We could use
-  // our own thread, but we need to loook at the registry anyway, so
-  // we just steal that one.
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-  // First, find the flag whose current-flag storage is 'flag'.
-  // This is the CommandLineFlag whose current_->value_buffer_ == flag
-  CommandLineFlag* flag = registry->FindFlagViaPtrLocked(flag_ptr);
-  if (!flag) {
-    LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag pointer "
-                 << flag_ptr << ": no flag found at that address";
-    return false;
-  } else if (validate_fn_proto == flag->validate_function()) {
-    return true;    // ok to register the same function over and over again
-  } else if (validate_fn_proto != NULL && flag->validate_function() != NULL) {
-    LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag '"
-                 << flag->name() << "': validate-fn already registered";
-    return false;
-  } else {
-    flag->validate_fn_proto_ = validate_fn_proto;
-    return true;
-  }
-}
-
-}  // end unnamed namespaces
-
-
-// Now define the functions that are exported via the .h file
-
-// --------------------------------------------------------------------
-// FlagRegisterer
-//    This class exists merely to have a global constructor (the
-//    kind that runs before main(), that goes an initializes each
-//    flag that's been declared.  Note that it's very important we
-//    don't have a destructor that deletes flag_, because that would
-//    cause us to delete current_storage/defvalue_storage as well,
-//    which can cause a crash if anything tries to access the flag
-//    values in a global destructor.
-// --------------------------------------------------------------------
-
-namespace {
-void RegisterCommandLineFlag(const char* name,
-                             const char* help,
-                             const char* filename,
-                             FlagValue* current,
-                             FlagValue* defvalue) {
-  if (help == NULL)
-    help = "";
-  // Importantly, flag_ will never be deleted, so storage is always good.
-  CommandLineFlag* flag =
-      new CommandLineFlag(name, help, filename, current, defvalue);
-  FlagRegistry::GlobalRegistry()->RegisterFlag(flag);  // default registry
-}
-}
-
-template <typename FlagType>
-FlagRegisterer::FlagRegisterer(const char* name,
-                               const char* help,
-                               const char* filename,
-                               FlagType* current_storage,
-                               FlagType* defvalue_storage) {
-  FlagValue* const current = new FlagValue(current_storage, false);
-  FlagValue* const defvalue = new FlagValue(defvalue_storage, false);
-  RegisterCommandLineFlag(name, help, filename, current, defvalue);
-}
-
-// Force compiler to generate code for the given template specialization.
-#define INSTANTIATE_FLAG_REGISTERER_CTOR(type)                  \
-  template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer(      \
-      const char* name, const char* help, const char* filename, \
-      type* current_storage, type* defvalue_storage)
-
-// Do this for all supported flag types.
-INSTANTIATE_FLAG_REGISTERER_CTOR(bool);
-INSTANTIATE_FLAG_REGISTERER_CTOR(int32);
-INSTANTIATE_FLAG_REGISTERER_CTOR(uint32);
-INSTANTIATE_FLAG_REGISTERER_CTOR(int64);
-INSTANTIATE_FLAG_REGISTERER_CTOR(uint64);
-INSTANTIATE_FLAG_REGISTERER_CTOR(double);
-INSTANTIATE_FLAG_REGISTERER_CTOR(std::string);
-
-#undef INSTANTIATE_FLAG_REGISTERER_CTOR
-
-// --------------------------------------------------------------------
-// GetAllFlags()
-//    The main way the FlagRegistry class exposes its data.  This
-//    returns, as strings, all the info about all the flags in
-//    the main registry, sorted first by filename they are defined
-//    in, and then by flagname.
-// --------------------------------------------------------------------
-
-struct FilenameFlagnameCmp {
-  bool operator()(const CommandLineFlagInfo& a,
-                  const CommandLineFlagInfo& b) const {
-    int cmp = strcmp(a.filename.c_str(), b.filename.c_str());
-    if (cmp == 0)
-      cmp = strcmp(a.name.c_str(), b.name.c_str());  // secondary sort key
-    return cmp < 0;
-  }
-};
-
-void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  registry->Lock();
-  for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
-       i != registry->flags_.end(); ++i) {
-    CommandLineFlagInfo fi;
-    i->second->FillCommandLineFlagInfo(&fi);
-    OUTPUT->push_back(fi);
-  }
-  registry->Unlock();
-  // Now sort the flags, first by filename they occur in, then alphabetically
-  sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameCmp());
-}
-
-// --------------------------------------------------------------------
-// SetArgv()
-// GetArgvs()
-// GetArgv()
-// GetArgv0()
-// ProgramInvocationName()
-// ProgramInvocationShortName()
-// SetUsageMessage()
-// ProgramUsage()
-//    Functions to set and get argv.  Typically the setter is called
-//    by ParseCommandLineFlags.  Also can get the ProgramUsage string,
-//    set by SetUsageMessage.
-// --------------------------------------------------------------------
-
-// These values are not protected by a Mutex because they are normally
-// set only once during program startup.
-static string argv0("UNKNOWN");  // just the program name
-static string cmdline;           // the entire command-line
-static string program_usage;
-static vector<string> argvs;
-static uint32 argv_sum = 0;
-
-void SetArgv(int argc, const char** argv) {
-  static bool called_set_argv = false;
-  if (called_set_argv) return;
-  called_set_argv = true;
-
-  assert(argc > 0); // every program has at least a name
-  argv0 = argv[0];
-
-  cmdline.clear();
-  for (int i = 0; i < argc; i++) {
-    if (i != 0) cmdline += " ";
-    cmdline += argv[i];
-    argvs.push_back(argv[i]);
-  }
-
-  // Compute a simple sum of all the chars in argv
-  argv_sum = 0;
-  for (string::const_iterator c = cmdline.begin(); c != cmdline.end(); ++c) {
-    argv_sum += *c;
-  }
-}
-
-const vector<string>& GetArgvs() { return argvs; }
-const char* GetArgv()            { return cmdline.c_str(); }
-const char* GetArgv0()           { return argv0.c_str(); }
-uint32 GetArgvSum()              { return argv_sum; }
-const char* ProgramInvocationName() {             // like the GNU libc fn
-  return GetArgv0();
-}
-const char* ProgramInvocationShortName() {        // like the GNU libc fn
-  size_t pos = argv0.rfind('/');
-#ifdef OS_WINDOWS
-  if (pos == string::npos) pos = argv0.rfind('\\');
-#endif
-  return (pos == string::npos ? argv0.c_str() : (argv0.c_str() + pos + 1));
-}
-
-void SetUsageMessage(const string& usage) {
-  program_usage = usage;
-}
-
-const char* ProgramUsage() {
-  if (program_usage.empty()) {
-    return "Warning: SetUsageMessage() never called";
-  }
-  return program_usage.c_str();
-}
-
-// --------------------------------------------------------------------
-// SetVersionString()
-// VersionString()
-// --------------------------------------------------------------------
-
-static string version_string;
-
-void SetVersionString(const string& version) {
-  version_string = version;
-}
-
-const char* VersionString() {
-  return version_string.c_str();
-}
-
-
-// --------------------------------------------------------------------
-// GetCommandLineOption()
-// GetCommandLineFlagInfo()
-// GetCommandLineFlagInfoOrDie()
-// SetCommandLineOption()
-// SetCommandLineOptionWithMode()
-//    The programmatic way to set a flag's value, using a string
-//    for its name rather than the variable itself (that is,
-//    SetCommandLineOption("foo", x) rather than FLAGS_foo = x).
-//    There's also a bit more flexibility here due to the various
-//    set-modes, but typically these are used when you only have
-//    that flag's name as a string, perhaps at runtime.
-//    All of these work on the default, global registry.
-//       For GetCommandLineOption, return false if no such flag
-//    is known, true otherwise.  We clear "value" if a suitable
-//    flag is found.
-// --------------------------------------------------------------------
-
-
-bool GetCommandLineOption(const char* name, string* value) {
-  if (NULL == name)
-    return false;
-  assert(value);
-
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-  CommandLineFlag* flag = registry->FindFlagLocked(name);
-  if (flag == NULL) {
-    return false;
-  } else {
-    *value = flag->current_value();
-    return true;
-  }
-}
-
-bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT) {
-  if (NULL == name) return false;
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-  CommandLineFlag* flag = registry->FindFlagLocked(name);
-  if (flag == NULL) {
-    return false;
-  } else {
-    assert(OUTPUT);
-    flag->FillCommandLineFlagInfo(OUTPUT);
-    return true;
-  }
-}
-
-CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) {
-  CommandLineFlagInfo info;
-  if (!GetCommandLineFlagInfo(name, &info)) {
-    fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exist\n", name);
-    gflags_exitfunc(1);    // almost certainly gflags_exitfunc()
-  }
-  return info;
-}
-
-string SetCommandLineOptionWithMode(const char* name, const char* value,
-                                    FlagSettingMode set_mode) {
-  string result;
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-  CommandLineFlag* flag = registry->FindFlagLocked(name);
-  if (flag) {
-    CommandLineFlagParser parser(registry);
-    result = parser.ProcessSingleOptionLocked(flag, value, set_mode);
-    if (!result.empty()) {   // in the error case, we've already logged
-      // Could consider logging this change
-    }
-  }
-  // The API of this function is that we return empty string on error
-  return result;
-}
-
-string SetCommandLineOption(const char* name, const char* value) {
-  return SetCommandLineOptionWithMode(name, value, SET_FLAGS_VALUE);
-}
-
-// --------------------------------------------------------------------
-// FlagSaver
-// FlagSaverImpl
-//    This class stores the states of all flags at construct time,
-//    and restores all flags to that state at destruct time.
-//    Its major implementation challenge is that it never modifies
-//    pointers in the 'main' registry, so global FLAG_* vars always
-//    point to the right place.
-// --------------------------------------------------------------------
-
-class FlagSaverImpl {
- public:
-  // Constructs an empty FlagSaverImpl object.
-  explicit FlagSaverImpl(FlagRegistry* main_registry)
-      : main_registry_(main_registry) { }
-  ~FlagSaverImpl() {
-    // reclaim memory from each of our CommandLineFlags
-    vector<CommandLineFlag*>::const_iterator it;
-    for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it)
-      delete *it;
-  }
-
-  // Saves the flag states from the flag registry into this object.
-  // It's an error to call this more than once.
-  // Must be called when the registry mutex is not held.
-  void SaveFromRegistry() {
-    FlagRegistryLock frl(main_registry_);
-    assert(backup_registry_.empty());   // call only once!
-    for (FlagRegistry::FlagConstIterator it = main_registry_->flags_.begin();
-         it != main_registry_->flags_.end();
-         ++it) {
-      const CommandLineFlag* main = it->second;
-      // Sets up all the const variables in backup correctly
-      CommandLineFlag* backup = new CommandLineFlag(
-          main->name(), main->help(), main->filename(),
-          main->current_->New(), main->defvalue_->New());
-      // Sets up all the non-const variables in backup correctly
-      backup->CopyFrom(*main);
-      backup_registry_.push_back(backup);   // add it to a convenient list
-    }
-  }
-
-  // Restores the saved flag states into the flag registry.  We
-  // assume no flags were added or deleted from the registry since
-  // the SaveFromRegistry; if they were, that's trouble!  Must be
-  // called when the registry mutex is not held.
-  void RestoreToRegistry() {
-    FlagRegistryLock frl(main_registry_);
-    vector<CommandLineFlag*>::const_iterator it;
-    for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) {
-      CommandLineFlag* main = main_registry_->FindFlagLocked((*it)->name());
-      if (main != NULL) {       // if NULL, flag got deleted from registry(!)
-        main->CopyFrom(**it);
-      }
-    }
-  }
-
- private:
-  FlagRegistry* const main_registry_;
-  vector<CommandLineFlag*> backup_registry_;
-
-  FlagSaverImpl(const FlagSaverImpl&);  // no copying!
-  void operator=(const FlagSaverImpl&);
-};
-
-FlagSaver::FlagSaver()
-    : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
-  impl_->SaveFromRegistry();
-}
-
-FlagSaver::~FlagSaver() {
-  impl_->RestoreToRegistry();
-  delete impl_;
-}
-
-
-// --------------------------------------------------------------------
-// CommandlineFlagsIntoString()
-// ReadFlagsFromString()
-// AppendFlagsIntoFile()
-// ReadFromFlagsFile()
-//    These are mostly-deprecated routines that stick the
-//    commandline flags into a file/string and read them back
-//    out again.  I can see a use for CommandlineFlagsIntoString,
-//    for creating a flagfile, but the rest don't seem that useful
-//    -- some, I think, are a poor-man's attempt at FlagSaver --
-//    and are included only until we can delete them from callers.
-//    Note they don't save --flagfile flags (though they do save
-//    the result of having called the flagfile, of course).
-// --------------------------------------------------------------------
-
-static string TheseCommandlineFlagsIntoString(
-    const vector<CommandLineFlagInfo>& flags) {
-  vector<CommandLineFlagInfo>::const_iterator i;
-
-  size_t retval_space = 0;
-  for (i = flags.begin(); i != flags.end(); ++i) {
-    // An (over)estimate of how much space it will take to print this flag
-    retval_space += i->name.length() + i->current_value.length() + 5;
-  }
-
-  string retval;
-  retval.reserve(retval_space);
-  for (i = flags.begin(); i != flags.end(); ++i) {
-    retval += "--";
-    retval += i->name;
-    retval += "=";
-    retval += i->current_value;
-    retval += "\n";
-  }
-  return retval;
-}
-
-string CommandlineFlagsIntoString() {
-  vector<CommandLineFlagInfo> sorted_flags;
-  GetAllFlags(&sorted_flags);
-  return TheseCommandlineFlagsIntoString(sorted_flags);
-}
-
-bool ReadFlagsFromString(const string& flagfilecontents,
-                         const char* /*prog_name*/,  // TODO(csilvers): nix this
-                         bool errors_are_fatal) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagSaverImpl saved_states(registry);
-  saved_states.SaveFromRegistry();
-
-  CommandLineFlagParser parser(registry);
-  registry->Lock();
-  parser.ProcessOptionsFromStringLocked(flagfilecontents, SET_FLAGS_VALUE);
-  registry->Unlock();
-  // Should we handle --help and such when reading flags from a string?  Sure.
-  HandleCommandLineHelpFlags();
-  if (parser.ReportErrors()) {
-    // Error.  Restore all global flags to their previous values.
-    if (errors_are_fatal)
-      gflags_exitfunc(1);
-    saved_states.RestoreToRegistry();
-    return false;
-  }
-  return true;
-}
-
-// TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
-bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
-  FILE *fp;
-  if (SafeFOpen(&fp, filename.c_str(), "a") != 0) {
-    return false;
-  }
-
-  if (prog_name)
-    fprintf(fp, "%s\n", prog_name);
-
-  vector<CommandLineFlagInfo> flags;
-  GetAllFlags(&flags);
-  // But we don't want --flagfile, which leads to weird recursion issues
-  vector<CommandLineFlagInfo>::iterator i;
-  for (i = flags.begin(); i != flags.end(); ++i) {
-    if (strcmp(i->name.c_str(), "flagfile") == 0) {
-      flags.erase(i);
-      break;
-    }
-  }
-  fprintf(fp, "%s", TheseCommandlineFlagsIntoString(flags).c_str());
-
-  fclose(fp);
-  return true;
-}
-
-bool ReadFromFlagsFile(const string& filename, const char* prog_name,
-                       bool errors_are_fatal) {
-  return ReadFlagsFromString(ReadFileIntoString(filename.c_str()),
-                             prog_name, errors_are_fatal);
-}
-
-
-// --------------------------------------------------------------------
-// BoolFromEnv()
-// Int32FromEnv()
-// Uint32FromEnv()
-// Int64FromEnv()
-// Uint64FromEnv()
-// DoubleFromEnv()
-// StringFromEnv()
-//    Reads the value from the environment and returns it.
-//    We use an FlagValue to make the parsing easy.
-//    Example usage:
-//       DEFINE_bool(myflag, BoolFromEnv("MYFLAG_DEFAULT", false), "whatever");
-// --------------------------------------------------------------------
-
-bool BoolFromEnv(const char *v, bool dflt) {
-  return GetFromEnv(v, dflt);
-}
-int32 Int32FromEnv(const char *v, int32 dflt) {
-  return GetFromEnv(v, dflt);
-}
-uint32 Uint32FromEnv(const char *v, uint32 dflt) {
-  return GetFromEnv(v, dflt);
-}
-int64 Int64FromEnv(const char *v, int64 dflt)    {
-  return GetFromEnv(v, dflt);
-}
-uint64 Uint64FromEnv(const char *v, uint64 dflt) {
-  return GetFromEnv(v, dflt);
-}
-double DoubleFromEnv(const char *v, double dflt) {
-  return GetFromEnv(v, dflt);
-}
-
-#ifdef _MSC_VER
-#  pragma warning(push)
-#  pragma warning(disable: 4996) // ignore getenv security warning
-#endif
-const char *StringFromEnv(const char *varname, const char *dflt) {
-  const char* const val = getenv(varname);
-  return val ? val : dflt;
-}
-#ifdef _MSC_VER
-#  pragma warning(pop)
-#endif
-
-
-// --------------------------------------------------------------------
-// RegisterFlagValidator()
-//    RegisterFlagValidator() is the function that clients use to
-//    'decorate' a flag with a validation function.  Once this is
-//    done, every time the flag is set (including when the flag
-//    is parsed from argv), the validator-function is called.
-//       These functions return true if the validator was added
-//    successfully, or false if not: the flag already has a validator,
-//    (only one allowed per flag), the 1st arg isn't a flag, etc.
-//       This function is not thread-safe.
-// --------------------------------------------------------------------
-
-bool RegisterFlagValidator(const bool* flag,
-                           bool (*validate_fn)(const char*, bool)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-bool RegisterFlagValidator(const int32* flag,
-                           bool (*validate_fn)(const char*, int32)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-bool RegisterFlagValidator(const uint32* flag,
-                           bool (*validate_fn)(const char*, uint32)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-bool RegisterFlagValidator(const int64* flag,
-                           bool (*validate_fn)(const char*, int64)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-bool RegisterFlagValidator(const uint64* flag,
-                           bool (*validate_fn)(const char*, uint64)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-bool RegisterFlagValidator(const double* flag,
-                           bool (*validate_fn)(const char*, double)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-bool RegisterFlagValidator(const string* flag,
-                           bool (*validate_fn)(const char*, const string&)) {
-  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
-}
-
-
-// --------------------------------------------------------------------
-// ParseCommandLineFlags()
-// ParseCommandLineNonHelpFlags()
-// HandleCommandLineHelpFlags()
-//    This is the main function called from main(), to actually
-//    parse the commandline.  It modifies argc and argv as described
-//    at the top of gflags.h.  You can also divide this
-//    function into two parts, if you want to do work between
-//    the parsing of the flags and the printing of any help output.
-// --------------------------------------------------------------------
-
-static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv,
-                                            bool remove_flags, bool do_report) {
-  SetArgv(*argc, const_cast<const char**>(*argv));    // save it for later
-
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  CommandLineFlagParser parser(registry);
-
-  // When we parse the commandline flags, we'll handle --flagfile,
-  // --tryfromenv, etc. as we see them (since flag-evaluation order
-  // may be important).  But sometimes apps set FLAGS_tryfromenv/etc.
-  // manually before calling ParseCommandLineFlags.  We want to evaluate
-  // those too, as if they were the first flags on the commandline.
-  registry->Lock();
-  parser.ProcessFlagfileLocked(FLAGS_flagfile, SET_FLAGS_VALUE);
-  // Last arg here indicates whether flag-not-found is a fatal error or not
-  parser.ProcessFromenvLocked(FLAGS_fromenv, SET_FLAGS_VALUE, true);
-  parser.ProcessFromenvLocked(FLAGS_tryfromenv, SET_FLAGS_VALUE, false);
-  registry->Unlock();
-
-  // Now get the flags specified on the commandline
-  const int r = parser.ParseNewCommandLineFlags(argc, argv, remove_flags);
-
-  if (do_report)
-    HandleCommandLineHelpFlags();   // may cause us to exit on --help, etc.
-
-  // See if any of the unset flags fail their validation checks
-  parser.ValidateUnmodifiedFlags();
-
-  if (parser.ReportErrors())        // may cause us to exit on illegal flags
-    gflags_exitfunc(1);
-  return r;
-}
-
-uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags) {
-  return ParseCommandLineFlagsInternal(argc, argv, remove_flags, true);
-}
-
-uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv,
-                                    bool remove_flags) {
-  return ParseCommandLineFlagsInternal(argc, argv, remove_flags, false);
-}
-
-// --------------------------------------------------------------------
-// AllowCommandLineReparsing()
-// ReparseCommandLineNonHelpFlags()
-//    This is most useful for shared libraries.  The idea is if
-//    a flag is defined in a shared library that is dlopen'ed
-//    sometime after main(), you can ParseCommandLineFlags before
-//    the dlopen, then ReparseCommandLineNonHelpFlags() after the
-//    dlopen, to get the new flags.  But you have to explicitly
-//    Allow() it; otherwise, you get the normal default behavior
-//    of unrecognized flags calling a fatal error.
-// TODO(csilvers): this isn't used.  Just delete it?
-// --------------------------------------------------------------------
-
-void AllowCommandLineReparsing() {
-  allow_command_line_reparsing = true;
-}
-
-void ReparseCommandLineNonHelpFlags() {
-  // We make a copy of argc and argv to pass in
-  const vector<string>& argvs = GetArgvs();
-  int tmp_argc = static_cast<int>(argvs.size());
-  char** tmp_argv = new char* [tmp_argc + 1];
-  for (int i = 0; i < tmp_argc; ++i)
-    tmp_argv[i] = strdup(argvs[i].c_str());   // TODO(csilvers): don't dup
-
-  ParseCommandLineNonHelpFlags(&tmp_argc, &tmp_argv, false);
-
-  for (int i = 0; i < tmp_argc; ++i)
-    free(tmp_argv[i]);
-  delete[] tmp_argv;
-}
-
-void ShutDownCommandLineFlags() {
-  FlagRegistry::DeleteGlobalRegistry();
-}
-
-
-} // namespace GFLAGS_NAMESPACE
diff --git a/third_party/gflags/src/gflags.h.in b/third_party/gflags/src/gflags.h.in
deleted file mode 100644
index 7b218b9..0000000
--- a/third_party/gflags/src/gflags.h.in
+++ /dev/null
@@ -1,626 +0,0 @@
-// 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.
-
-// ---
-// Revamped and reorganized by Craig Silverstein
-//
-// This is the file that should be included by any file which declares
-// or defines a command line flag or wants to parse command line flags
-// or print a program usage message (which will include information about
-// flags).  Executive summary, in the form of an example foo.cc file:
-//
-//    #include "foo.h"         // foo.h has a line "DECLARE_int32(start);"
-//    #include "validators.h"  // hypothetical file defining ValidateIsFile()
-//
-//    DEFINE_int32(end, 1000, "The last record to read");
-//
-//    DEFINE_string(filename, "my_file.txt", "The file to read");
-//    // Crash if the specified file does not exist.
-//    static bool dummy = RegisterFlagValidator(&FLAGS_filename,
-//                                              &ValidateIsFile);
-//
-//    DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
-//
-//    void MyFunc() {
-//      if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
-//    }
-//
-//    Then, at the command-line:
-//       ./foo --noverbose --start=5 --end=100
-//
-// For more details, see
-//    doc/gflags.html
-//
-// --- A note about thread-safety:
-//
-// We describe many functions in this routine as being thread-hostile,
-// thread-compatible, or thread-safe.  Here are the meanings we use:
-//
-// thread-safe: it is safe for multiple threads to call this routine
-//   (or, when referring to a class, methods of this class)
-//   concurrently.
-// thread-hostile: it is not safe for multiple threads to call this
-//   routine (or methods of this class) concurrently.  In gflags,
-//   most thread-hostile routines are intended to be called early in,
-//   or even before, main() -- that is, before threads are spawned.
-// thread-compatible: it is safe for multiple threads to read from
-//   this variable (when applied to variables), or to call const
-//   methods of this class (when applied to classes), as long as no
-//   other thread is writing to the variable or calling non-const
-//   methods of this class.
-
-#ifndef GFLAGS_GFLAGS_H_
-#define GFLAGS_GFLAGS_H_
-
-#include <string>
-#include <vector>
-
-#include "gflags/gflags_declare.h" // IWYU pragma: export
-
-
-// We always want to export variables defined in user code
-#ifndef GFLAGS_DLL_DEFINE_FLAG
-#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
-#    define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
-#  else
-#    define GFLAGS_DLL_DEFINE_FLAG
-#  endif
-#endif
-
-
-namespace GFLAGS_NAMESPACE {
-
-
-// --------------------------------------------------------------------
-// To actually define a flag in a file, use DEFINE_bool,
-// DEFINE_string, etc. at the bottom of this file.  You may also find
-// it useful to register a validator with the flag.  This ensures that
-// when the flag is parsed from the commandline, or is later set via
-// SetCommandLineOption, we call the validation function. It is _not_
-// called when you assign the value to the flag directly using the = operator.
-//
-// The validation function should return true if the flag value is valid, and
-// false otherwise. If the function returns false for the new setting of the
-// flag, the flag will retain its current value. If it returns false for the
-// default value, ParseCommandLineFlags() will die.
-//
-// This function is safe to call at global construct time (as in the
-// example below).
-//
-// Example use:
-//    static bool ValidatePort(const char* flagname, int32 value) {
-//       if (value > 0 && value < 32768)   // value is ok
-//         return true;
-//       printf("Invalid value for --%s: %d\n", flagname, (int)value);
-//       return false;
-//    }
-//    DEFINE_int32(port, 0, "What port to listen on");
-//    static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
-
-// Returns true if successfully registered, false if not (because the
-// first argument doesn't point to a command-line flag, or because a
-// validator is already registered for this flag).
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool*        flag, bool (*validate_fn)(const char*, bool));
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32*       flag, bool (*validate_fn)(const char*, int32));
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32*      flag, bool (*validate_fn)(const char*, uint32));
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64*       flag, bool (*validate_fn)(const char*, int64));
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64*      flag, bool (*validate_fn)(const char*, uint64));
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double*      flag, bool (*validate_fn)(const char*, double));
-extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
-
-// Convenience macro for the registration of a flag validator
-#define DEFINE_validator(name, validator) \
-    static const bool name##_validator_registered = \
-            GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
-
-
-// --------------------------------------------------------------------
-// These methods are the best way to get access to info about the
-// list of commandline flags.  Note that these routines are pretty slow.
-//   GetAllFlags: mostly-complete info about the list, sorted by file.
-//   ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
-//   ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
-//
-// In addition to accessing flags, you can also access argv[0] (the program
-// name) and argv (the entire commandline), which we sock away a copy of.
-// These variables are static, so you should only set them once.
-//
-// No need to export this data only structure from DLL, avoiding VS warning 4251.
-struct CommandLineFlagInfo {
-  std::string name;            // the name of the flag
-  std::string type;            // the type of the flag: int32, etc
-  std::string description;     // the "help text" associated with the flag
-  std::string current_value;   // the current value, as a string
-  std::string default_value;   // the default value, as a string
-  std::string filename;        // 'cleaned' version of filename holding the flag
-  bool has_validator_fn;       // true if RegisterFlagValidator called on this flag
-  bool is_default;             // true if the flag has the default value and
-                               // has not been set explicitly from the cmdline
-                               // or via SetCommandLineOption
-  const void* flag_ptr;        // pointer to the flag's current value (i.e. FLAGS_foo)
-};
-
-// Using this inside of a validator is a recipe for a deadlock.
-// TODO(user) Fix locking when validators are running, to make it safe to
-// call validators during ParseAllFlags.
-// Also make sure then to uncomment the corresponding unit test in
-// gflags_unittest.sh
-extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
-// These two are actually defined in gflags_reporting.cc.
-extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0);  // what --help does
-extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
-
-// Create a descriptive string for a flag.
-// Goes to some trouble to make pretty line breaks.
-extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
-
-// Thread-hostile; meant to be called before any threads are spawned.
-extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
-
-// The following functions are thread-safe as long as SetArgv() is
-// only called before any threads start.
-extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
-extern GFLAGS_DLL_DECL const char* GetArgv();                      // all of argv as a string
-extern GFLAGS_DLL_DECL const char* GetArgv0();                     // only argv0
-extern GFLAGS_DLL_DECL uint32 GetArgvSum();                        // simple checksum of argv
-extern GFLAGS_DLL_DECL const char* ProgramInvocationName();        // argv0, or "UNKNOWN" if not set
-extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName();   // basename(argv0)
-
-// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
-// called before any threads start.
-extern GFLAGS_DLL_DECL const char* ProgramUsage();                 // string set by SetUsageMessage()
-
-// VersionString() is thread-safe as long as SetVersionString() is only
-// called before any threads start.
-extern GFLAGS_DLL_DECL const char* VersionString();                // string set by SetVersionString()
-
-
-
-// --------------------------------------------------------------------
-// Normally you access commandline flags by just saying "if (FLAGS_foo)"
-// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
-// commonly, via the DEFINE_foo macro).  But if you need a bit more
-// control, we have programmatic ways to get/set the flags as well.
-// These programmatic ways to access flags are thread-safe, but direct
-// access is only thread-compatible.
-
-// Return true iff the flagname was found.
-// OUTPUT is set to the flag's value, or unchanged if we return false.
-extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
-
-// Return true iff the flagname was found. OUTPUT is set to the flag's
-// CommandLineFlagInfo or unchanged if we return false.
-extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
-
-// Return the CommandLineFlagInfo of the flagname.  exit() if name not found.
-// Example usage, to check if a flag's value is currently the default value:
-//   if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
-extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
-
-enum GFLAGS_DLL_DECL FlagSettingMode {
-  // update the flag's value (can call this multiple times).
-  SET_FLAGS_VALUE,
-  // update the flag's value, but *only if* it has not yet been updated
-  // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
-  SET_FLAG_IF_DEFAULT,
-  // set the flag's default value to this.  If the flag has not yet updated
-  // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
-  // change the flag's current value to the new default value as well.
-  SET_FLAGS_DEFAULT
-};
-
-// Set a particular flag ("command line option").  Returns a string
-// describing the new value that the option has been set to.  The
-// return value API is not well-specified, so basically just depend on
-// it to be empty if the setting failed for some reason -- the name is
-// not a valid flag name, or the value is not a valid value -- and
-// non-empty else.
-
-// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
-extern GFLAGS_DLL_DECL std::string SetCommandLineOption        (const char* name, const char* value);
-extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
-
-
-// --------------------------------------------------------------------
-// Saves the states (value, default value, whether the user has set
-// the flag, registered validators, etc) of all flags, and restores
-// them when the FlagSaver is destroyed.  This is very useful in
-// tests, say, when you want to let your tests change the flags, but
-// make sure that they get reverted to the original states when your
-// test is complete.
-//
-// Example usage:
-//   void TestFoo() {
-//     FlagSaver s1;
-//     FLAG_foo = false;
-//     FLAG_bar = "some value";
-//
-//     // test happens here.  You can return at any time
-//     // without worrying about restoring the FLAG values.
-//   }
-//
-// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
-// the work is done in the constructor and destructor, so in the standard
-// usage example above, the compiler would complain that it's an
-// unused variable.
-//
-// This class is thread-safe.  However, its destructor writes to
-// exactly the set of flags that have changed value during its
-// lifetime, so concurrent _direct_ access to those flags
-// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
-
-class GFLAGS_DLL_DECL FlagSaver {
- public:
-  FlagSaver();
-  ~FlagSaver();
-
- private:
-  class FlagSaverImpl* impl_;   // we use pimpl here to keep API steady
-
-  FlagSaver(const FlagSaver&);  // no copying!
-  void operator=(const FlagSaver&);
-}@GFLAGS_ATTRIBUTE_UNUSED@;
-
-// --------------------------------------------------------------------
-// Some deprecated or hopefully-soon-to-be-deprecated functions.
-
-// This is often used for logging.  TODO(csilvers): figure out a better way
-extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
-// Usually where this is used, a FlagSaver should be used instead.
-extern GFLAGS_DLL_DECL
-bool ReadFlagsFromString(const std::string& flagfilecontents,
-                         const char* prog_name,
-                         bool errors_are_fatal);  // uses SET_FLAGS_VALUE
-
-// These let you manually implement --flagfile functionality.
-// DEPRECATED.
-extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
-extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal);   // uses SET_FLAGS_VALUE
-
-
-// --------------------------------------------------------------------
-// Useful routines for initializing flags from the environment.
-// In each case, if 'varname' does not exist in the environment
-// return defval.  If 'varname' does exist but is not valid
-// (e.g., not a number for an int32 flag), abort with an error.
-// Otherwise, return the value.  NOTE: for booleans, for true use
-// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
-
-extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
-extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
-extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval);
-extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
-extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
-extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
-extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
-
-
-// --------------------------------------------------------------------
-// The next two functions parse gflags from main():
-
-// Set the "usage" message for this program.  For example:
-//   string usage("This program does nothing.  Sample usage:\n");
-//   usage += argv[0] + " <uselessarg1> <uselessarg2>";
-//   SetUsageMessage(usage);
-// Do not include commandline flags in the usage: we do that for you!
-// Thread-hostile; meant to be called before any threads are spawned.
-extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
-
-// Sets the version string, which is emitted with --version.
-// For instance: SetVersionString("1.3");
-// Thread-hostile; meant to be called before any threads are spawned.
-extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
-
-
-// Looks for flags in argv and parses them.  Rearranges argv to put
-// flags first, or removes them entirely if remove_flags is true.
-// If a flag is defined more than once in the command line or flag
-// file, the last definition is used.  Returns the index (into argv)
-// of the first non-flag argument.
-// See top-of-file for more details on this function.
-#ifndef SWIG   // In swig, use ParseCommandLineFlagsScript() instead.
-extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
-#endif
-
-
-// Calls to ParseCommandLineNonHelpFlags and then to
-// HandleCommandLineHelpFlags can be used instead of a call to
-// ParseCommandLineFlags during initialization, in order to allow for
-// changing default values for some FLAGS (via
-// e.g. SetCommandLineOptionWithMode calls) between the time of
-// command line parsing and the time of dumping help information for
-// the flags as a result of command line parsing.  If a flag is
-// defined more than once in the command line or flag file, the last
-// definition is used.  Returns the index (into argv) of the first
-// non-flag argument.  (If remove_flags is true, will always return 1.)
-extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
-
-// This is actually defined in gflags_reporting.cc.
-// This function is misnamed (it also handles --version, etc.), but
-// it's too late to change that now. :-(
-extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags();   // in gflags_reporting.cc
-
-// Allow command line reparsing.  Disables the error normally
-// generated when an unknown flag is found, since it may be found in a
-// later parse.  Thread-hostile; meant to be called before any threads
-// are spawned.
-extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
-
-// Reparse the flags that have not yet been recognized.  Only flags
-// registered since the last parse will be recognized.  Any flag value
-// must be provided as part of the argument using "=", not as a
-// separate command line argument that follows the flag argument.
-// Intended for handling flags from dynamically loaded libraries,
-// since their flags are not registered until they are loaded.
-extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
-
-// Clean up memory allocated by flags.  This is only needed to reduce
-// the quantity of "potentially leaked" reports emitted by memory
-// debugging tools such as valgrind.  It is not required for normal
-// operation, or for the google perftools heap-checker.  It must only
-// be called when the process is about to exit, and all threads that
-// might access flags are quiescent.  Referencing flags after this is
-// called will have unexpected consequences.  This is not safe to run
-// when multiple threads might be running: the function is
-// thread-hostile.
-extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
-
-
-// --------------------------------------------------------------------
-// Now come the command line flag declaration/definition macros that
-// will actually be used.  They're kind of hairy.  A major reason
-// for this is initialization: we want people to be able to access
-// variables in global constructors and have that not crash, even if
-// their global constructor runs before the global constructor here.
-// (Obviously, we can't guarantee the flags will have the correct
-// default value in that case, but at least accessing them is safe.)
-// The only way to do that is have flags point to a static buffer.
-// So we make one, using a union to ensure proper alignment, and
-// then use placement-new to actually set up the flag with the
-// correct default value.  In the same vein, we have to worry about
-// flag access in global destructors, so FlagRegisterer has to be
-// careful never to destroy the flag-values it constructs.
-//
-// Note that when we define a flag variable FLAGS_<name>, we also
-// preemptively define a junk variable, FLAGS_no<name>.  This is to
-// cause a link-time error if someone tries to define 2 flags with
-// names like "logging" and "nologging".  We do this because a bool
-// flag FLAG can be set from the command line to true with a "-FLAG"
-// argument, and to false with a "-noFLAG" argument, and so this can
-// potentially avert confusion.
-//
-// We also 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 GFLAGS_DLL_DECL bool FLAGS_whatever;"
-// 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.
-
-class GFLAGS_DLL_DECL FlagRegisterer {
- public:
-  // We instantiate this template ctor for all supported types,
-  // so it is possible to place implementation of the FlagRegisterer ctor in
-  // .cc file.
-  // Calling this constructor with unsupported type will produce linker error.
-  template <typename FlagType>
-  FlagRegisterer(const char* name,
-                 const char* help, const char* filename,
-                 FlagType* current_storage, FlagType* defvalue_storage);
-};
-
-// Force compiler to not generate code for the given template specialization.
-#if defined(_MSC_VER) && _MSC_VER < 1800 // Visual Studio 2013 version 12.0
-  #define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type)
-#else
-  #define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type)                  \
-    extern template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer(  \
-        const char* name, const char* help, const char* filename,    \
-        type* current_storage, type* defvalue_storage)
-#endif
-
-// Do this for all supported flag types.
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(bool);
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int32);
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint32);
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int64);
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint64);
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(double);
-GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(std::string);
-
-#undef GFLAGS_DECLARE_FLAG_REGISTERER_CTOR
-
-// If your application #defines STRIP_FLAG_HELP to a non-zero value
-// before #including this file, we remove the help message from the
-// binary file. This can reduce the size of the resulting binary
-// somewhat, and may also be useful for security reasons.
-
-extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
-
-
-} // namespace GFLAGS_NAMESPACE
-
-
-#ifndef SWIG  // In swig, ignore the main flag declarations
-
-#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
-// Need this construct to avoid the 'defined but not used' warning.
-#define MAYBE_STRIPPED_HELP(txt) \
-   (false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
-#else
-#define MAYBE_STRIPPED_HELP(txt) txt
-#endif
-
-// Each command-line flag has two variables associated with it: one
-// with the current value, and one with the default value.  However,
-// we have a third variable, which is where value is assigned; it's a
-// constant.  This guarantees that FLAG_##value is initialized at
-// static initialization time (e.g. before program-start) rather than
-// than global construction time (which is after program-start but
-// before main), at least when 'value' is a compile-time constant.  We
-// use a small trick for the "default value" variable, and call it
-// FLAGS_no<name>.  This serves the second purpose of assuring a
-// compile error if someone tries to define a flag named no<name>
-// which is illegal (--foo and --nofoo both affect the "foo" flag).
-#define DEFINE_VARIABLE(type, shorttype, name, value, help)             \
-  namespace fL##shorttype {                                             \
-    static const type FLAGS_nono##name = value;                         \
-    /* We always want to export defined variables, dll or no */         \
-    GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name;        \
-    static type FLAGS_no##name = FLAGS_nono##name;                      \
-    static GFLAGS_NAMESPACE::FlagRegisterer o_##name(                   \
-      #name, MAYBE_STRIPPED_HELP(help), __FILE__,                       \
-      &FLAGS_##name, &FLAGS_no##name);                                  \
-  }                                                                     \
-  using fL##shorttype::FLAGS_##name
-
-// For DEFINE_bool, we want to do the extra check that the passed-in
-// value is actually a bool, and not a string or something that can be
-// coerced to a bool.  These declarations (no definition needed!) will
-// help us do that, and never evaluate From, which is important.
-// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
-// that the compiler have different sizes for bool & double. Since
-// this is not guaranteed by the standard, we check it with a
-// COMPILE_ASSERT.
-namespace fLB {
-struct CompileAssert {};
-typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
-                      (sizeof(double) != sizeof(bool)) ? 1 : -1];
-template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
-GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
-}  // namespace fLB
-
-// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
-// are in a separate include, gflags_declare.h, for reducing
-// the physical transitive size for DECLARE use.
-#define DEFINE_bool(name, val, txt)                                     \
-  namespace fLB {                                                       \
-    typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[     \
-            (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
-  }                                                                     \
-  DEFINE_VARIABLE(bool, B, name, val, txt)
-
-#define DEFINE_int32(name, val, txt) \
-   DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
-                   name, val, txt)
-
-#define DEFINE_uint32(name,val, txt) \
-   DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \
-                   name, val, txt)
-
-#define DEFINE_int64(name, val, txt) \
-   DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
-                   name, val, txt)
-
-#define DEFINE_uint64(name,val, txt) \
-   DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
-                   name, val, txt)
-
-#define DEFINE_double(name, val, txt) \
-   DEFINE_VARIABLE(double, D, name, val, txt)
-
-// Strings are trickier, because they're not a POD, so we can't
-// construct them at static-initialization time (instead they get
-// constructed at global-constructor time, which is much later).  To
-// try to avoid crashes in that case, we use a char buffer to store
-// the string, which we can static-initialize, and then placement-new
-// into it later.  It's not perfect, but the best we can do.
-
-namespace fLS {
-
-inline clstring* dont_pass0toDEFINE_string(char *stringspot,
-                                           const char *value) {
-  return new(stringspot) clstring(value);
-}
-inline clstring* dont_pass0toDEFINE_string(char *stringspot,
-                                           const clstring &value) {
-  return new(stringspot) clstring(value);
-}
-inline clstring* dont_pass0toDEFINE_string(char *stringspot,
-                                           int value);
-
-// Auxiliary class used to explicitly call destructor of string objects
-// allocated using placement new during static program deinitialization.
-// The destructor MUST be an inline function such that the explicit
-// destruction occurs in the same compilation unit as the placement new.
-class StringFlagDestructor {
-  void *current_storage_;
-  void *defvalue_storage_;
-
-public: 
-
-  StringFlagDestructor(void *current, void *defvalue)
-  : current_storage_(current), defvalue_storage_(defvalue) {}
-
-  ~StringFlagDestructor() {
-    reinterpret_cast<clstring*>(current_storage_ )->~clstring();
-    reinterpret_cast<clstring*>(defvalue_storage_)->~clstring();
-  }
-};
-
-}  // namespace fLS
-
-// We need to define a var named FLAGS_no##name so people don't define
-// --string and --nostring.  And we need a temporary place to put val
-// so we don't have to evaluate it twice.  Two great needs that go
-// great together!
-// The weird 'using' + 'extern' inside the fLS namespace is to work around
-// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10.  See
-//    http://code.google.com/p/google-gflags/issues/detail?id=20
-#define DEFINE_string(name, val, txt)                                       \
-  namespace fLS {                                                           \
-    using ::fLS::clstring;                                                  \
-    using ::fLS::StringFlagDestructor;                                      \
-    static union { void* align; char s[sizeof(clstring)]; } s_##name[2];    \
-    clstring* const FLAGS_no##name = ::fLS::                                \
-                                   dont_pass0toDEFINE_string(s_##name[0].s, \
-                                                             val);          \
-    static GFLAGS_NAMESPACE::FlagRegisterer o_##name(                       \
-        #name, MAYBE_STRIPPED_HELP(txt), __FILE__,                          \
-        FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name));     \
-    static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s);     \
-    extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name;                   \
-    using fLS::FLAGS_##name;                                                \
-    clstring& FLAGS_##name = *FLAGS_no##name;                               \
-  }                                                                         \
-  using fLS::FLAGS_##name
-
-#endif  // SWIG
-
-
-@INCLUDE_GFLAGS_NS_H@
-
-
-#endif  // GFLAGS_GFLAGS_H_
diff --git a/third_party/gflags/src/gflags_completions.cc b/third_party/gflags/src/gflags_completions.cc
deleted file mode 100644
index 4f33b38..0000000
--- a/third_party/gflags/src/gflags_completions.cc
+++ /dev/null
@@ -1,777 +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.
-//
-// ---
-
-// Bash-style command line flag completion for C++ binaries
-//
-// This module implements bash-style completions.  It achieves this
-// goal in the following broad chunks:
-//
-//  1) Take a to-be-completed word, and examine it for search hints
-//  2) Identify all potentially matching flags
-//     2a) If there are no matching flags, do nothing.
-//     2b) If all matching flags share a common prefix longer than the
-//         completion word, output just that matching prefix
-//  3) Categorize those flags to produce a rough ordering of relevence.
-//  4) Potentially trim the set of flags returned to a smaller number
-//     that bash is happier with
-//  5) Output the matching flags in groups ordered by relevence.
-//     5a) Force bash to place most-relevent groups at the top of the list
-//     5b) Trim most flag's descriptions to fit on a single terminal line
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>   // for strlen
-
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "config.h"
-#include "gflags/gflags.h"
-#include "gflags/gflags_completions.h"
-#include "util.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-
-DEFINE_string(tab_completion_word, "",
-              "If non-empty, HandleCommandLineCompletions() will hijack the "
-              "process and attempt to do bash-style command line flag "
-              "completion on this value.");
-DEFINE_int32(tab_completion_columns, 80,
-             "Number of columns to use in output for tab completion");
-
-
-namespace GFLAGS_NAMESPACE {
-
-
-namespace {
-// Function prototypes and Type forward declarations.  Code may be
-// more easily understood if it is roughly ordered according to
-// control flow, rather than by C's "declare before use" ordering
-struct CompletionOptions;
-struct NotableFlags;
-
-// The entry point if flag completion is to be used.
-static void PrintFlagCompletionInfo(void);
-
-
-// 1) Examine search word
-static void CanonicalizeCursorWordAndSearchOptions(
-    const string &cursor_word,
-    string *canonical_search_token,
-    CompletionOptions *options);
-
-static bool RemoveTrailingChar(string *str, char c);
-
-
-// 2) Find all matches
-static void FindMatchingFlags(
-    const vector<CommandLineFlagInfo> &all_flags,
-    const CompletionOptions &options,
-    const string &match_token,
-    set<const CommandLineFlagInfo *> *all_matches,
-    string *longest_common_prefix);
-
-static bool DoesSingleFlagMatch(
-    const CommandLineFlagInfo &flag,
-    const CompletionOptions &options,
-    const string &match_token);
-
-
-// 3) Categorize matches
-static void CategorizeAllMatchingFlags(
-    const set<const CommandLineFlagInfo *> &all_matches,
-    const string &search_token,
-    const string &module,
-    const string &package_dir,
-    NotableFlags *notable_flags);
-
-static void TryFindModuleAndPackageDir(
-    const vector<CommandLineFlagInfo> &all_flags,
-    string *module,
-    string *package_dir);
-
-
-// 4) Decide which flags to use
-static void FinalizeCompletionOutput(
-    const set<const CommandLineFlagInfo *> &matching_flags,
-    CompletionOptions *options,
-    NotableFlags *notable_flags,
-    vector<string> *completions);
-
-static void RetrieveUnusedFlags(
-    const set<const CommandLineFlagInfo *> &matching_flags,
-    const NotableFlags &notable_flags,
-    set<const CommandLineFlagInfo *> *unused_flags);
-
-
-// 5) Output matches
-static void OutputSingleGroupWithLimit(
-    const set<const CommandLineFlagInfo *> &group,
-    const string &line_indentation,
-    const string &header,
-    const string &footer,
-    bool long_output_format,
-    int *remaining_line_limit,
-    size_t *completion_elements_added,
-    vector<string> *completions);
-
-// (helpers for #5)
-static string GetShortFlagLine(
-    const string &line_indentation,
-    const CommandLineFlagInfo &info);
-
-static string GetLongFlagLine(
-    const string &line_indentation,
-    const CommandLineFlagInfo &info);
-
-
-//
-// Useful types
-
-// Try to deduce the intentions behind this completion attempt.  Return the
-// canonical search term in 'canonical_search_token'.  Binary search options
-// are returned in the various booleans, which should all have intuitive
-// semantics, possibly except:
-//  - return_all_matching_flags: Generally, we'll trim the number of
-//    returned candidates to some small number, showing those that are
-//    most likely to be useful first.  If this is set, however, the user
-//    really does want us to return every single flag as an option.
-//  - force_no_update: Any time we output lines, all of which share a
-//    common prefix, bash will 'helpfully' not even bother to show the
-//    output, instead changing the current word to be that common prefix.
-//    If it's clear this shouldn't happen, we'll set this boolean
-struct CompletionOptions {
-  bool flag_name_substring_search;
-  bool flag_location_substring_search;
-  bool flag_description_substring_search;
-  bool return_all_matching_flags;
-  bool force_no_update;
-  CompletionOptions(): flag_name_substring_search(false),
-                       flag_location_substring_search(false),
-                       flag_description_substring_search(false),
-                       return_all_matching_flags(false),
-                       force_no_update(false) { }
-};
-
-// Notable flags are flags that are special or preferred for some
-// reason.  For example, flags that are defined in the binary's module
-// are expected to be much more relevent than flags defined in some
-// other random location.  These sets are specified roughly in precedence
-// order.  Once a flag is placed in one of these 'higher' sets, it won't
-// be placed in any of the 'lower' sets.
-struct NotableFlags {
-  typedef set<const CommandLineFlagInfo *> FlagSet;
-  FlagSet perfect_match_flag;
-  FlagSet module_flags;       // Found in module file
-  FlagSet package_flags;      // Found in same directory as module file
-  FlagSet most_common_flags;  // One of the XXX most commonly supplied flags
-  FlagSet subpackage_flags;   // Found in subdirectories of package
-};
-
-
-//
-// Tab completion implementation - entry point
-static void PrintFlagCompletionInfo(void) {
-  string cursor_word = FLAGS_tab_completion_word;
-  string canonical_token;
-  CompletionOptions options = CompletionOptions();
-  CanonicalizeCursorWordAndSearchOptions(
-      cursor_word,
-      &canonical_token,
-      &options);
-
-  DVLOG(1) << "Identified canonical_token: '" << canonical_token << "'";
-
-  vector<CommandLineFlagInfo> all_flags;
-  set<const CommandLineFlagInfo *> matching_flags;
-  GetAllFlags(&all_flags);
-  DVLOG(2) << "Found " << all_flags.size() << " flags overall";
-
-  string longest_common_prefix;
-  FindMatchingFlags(
-      all_flags,
-      options,
-      canonical_token,
-      &matching_flags,
-      &longest_common_prefix);
-  DVLOG(1) << "Identified " << matching_flags.size() << " matching flags";
-  DVLOG(1) << "Identified " << longest_common_prefix
-          << " as longest common prefix.";
-  if (longest_common_prefix.size() > canonical_token.size()) {
-    // There's actually a shared common prefix to all matching flags,
-    // so may as well output that and quit quickly.
-    DVLOG(1) << "The common prefix '" << longest_common_prefix
-            << "' was longer than the token '" << canonical_token
-            << "'.  Returning just this prefix for completion.";
-    fprintf(stdout, "--%s", longest_common_prefix.c_str());
-    return;
-  }
-  if (matching_flags.empty()) {
-    VLOG(1) << "There were no matching flags, returning nothing.";
-    return;
-  }
-
-  string module;
-  string package_dir;
-  TryFindModuleAndPackageDir(all_flags, &module, &package_dir);
-  DVLOG(1) << "Identified module: '" << module << "'";
-  DVLOG(1) << "Identified package_dir: '" << package_dir << "'";
-
-  NotableFlags notable_flags;
-  CategorizeAllMatchingFlags(
-      matching_flags,
-      canonical_token,
-      module,
-      package_dir,
-      &notable_flags);
-  DVLOG(2) << "Categorized matching flags:";
-  DVLOG(2) << " perfect_match: " << notable_flags.perfect_match_flag.size();
-  DVLOG(2) << " module: " << notable_flags.module_flags.size();
-  DVLOG(2) << " package: " << notable_flags.package_flags.size();
-  DVLOG(2) << " most common: " << notable_flags.most_common_flags.size();
-  DVLOG(2) << " subpackage: " << notable_flags.subpackage_flags.size();
-
-  vector<string> completions;
-  FinalizeCompletionOutput(
-      matching_flags,
-      &options,
-      &notable_flags,
-      &completions);
-
-  if (options.force_no_update)
-    completions.push_back("~");
-
-  DVLOG(1) << "Finalized with " << completions.size()
-          << " chosen completions";
-
-  for (vector<string>::const_iterator it = completions.begin();
-      it != completions.end();
-      ++it) {
-    DVLOG(9) << "  Completion entry: '" << *it << "'";
-    fprintf(stdout, "%s\n", it->c_str());
-  }
-}
-
-
-// 1) Examine search word (and helper method)
-static void CanonicalizeCursorWordAndSearchOptions(
-    const string &cursor_word,
-    string *canonical_search_token,
-    CompletionOptions *options) {
-  *canonical_search_token = cursor_word;
-  if (canonical_search_token->empty()) return;
-
-  // Get rid of leading quotes and dashes in the search term
-  if ((*canonical_search_token)[0] == '"')
-    *canonical_search_token = canonical_search_token->substr(1);
-  while ((*canonical_search_token)[0] == '-')
-    *canonical_search_token = canonical_search_token->substr(1);
-
-  options->flag_name_substring_search = false;
-  options->flag_location_substring_search = false;
-  options->flag_description_substring_search = false;
-  options->return_all_matching_flags = false;
-  options->force_no_update = false;
-
-  // Look for all search options we can deduce now.  Do this by walking
-  // backwards through the term, looking for up to three '?' and up to
-  // one '+' as suffixed characters.  Consume them if found, and remove
-  // them from the canonical search token.
-  int found_question_marks = 0;
-  int found_plusses = 0;
-  while (true) {
-    if (found_question_marks < 3 &&
-        RemoveTrailingChar(canonical_search_token, '?')) {
-      ++found_question_marks;
-      continue;
-    }
-    if (found_plusses < 1 &&
-        RemoveTrailingChar(canonical_search_token, '+')) {
-      ++found_plusses;
-      continue;
-    }
-    break;
-  }
-
-  switch (found_question_marks) {  // all fallthroughs
-    case 3:
-      options->flag_description_substring_search = true;
-      [[fallthrough]];
-    case 2:
-      options->flag_location_substring_search = true;
-      [[fallthrough]];
-    case 1:
-      options->flag_name_substring_search = true;
-  };
-
-  options->return_all_matching_flags = (found_plusses > 0);
-}
-
-// Returns true if a char was removed
-static bool RemoveTrailingChar(string *str, char c) {
-  if (str->empty()) return false;
-  if ((*str)[str->size() - 1] == c) {
-    *str = str->substr(0, str->size() - 1);
-    return true;
-  }
-  return false;
-}
-
-
-// 2) Find all matches (and helper methods)
-static void FindMatchingFlags(
-    const vector<CommandLineFlagInfo> &all_flags,
-    const CompletionOptions &options,
-    const string &match_token,
-    set<const CommandLineFlagInfo *> *all_matches,
-    string *longest_common_prefix) {
-  all_matches->clear();
-  bool first_match = true;
-  for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
-      it != all_flags.end();
-      ++it) {
-    if (DoesSingleFlagMatch(*it, options, match_token)) {
-      all_matches->insert(&*it);
-      if (first_match) {
-        first_match = false;
-        *longest_common_prefix = it->name;
-      } else {
-        if (longest_common_prefix->empty() || it->name.empty()) {
-          longest_common_prefix->clear();
-          continue;
-        }
-        string::size_type pos = 0;
-        while (pos < longest_common_prefix->size() &&
-            pos < it->name.size() &&
-            (*longest_common_prefix)[pos] == it->name[pos])
-          ++pos;
-        longest_common_prefix->erase(pos);
-      }
-    }
-  }
-}
-
-// Given the set of all flags, the parsed match options, and the
-// canonical search token, produce the set of all candidate matching
-// flags for subsequent analysis or filtering.
-static bool DoesSingleFlagMatch(
-    const CommandLineFlagInfo &flag,
-    const CompletionOptions &options,
-    const string &match_token) {
-  // Is there a prefix match?
-  string::size_type pos = flag.name.find(match_token);
-  if (pos == 0) return true;
-
-  // Is there a substring match if we want it?
-  if (options.flag_name_substring_search &&
-      pos != string::npos)
-    return true;
-
-  // Is there a location match if we want it?
-  if (options.flag_location_substring_search &&
-      flag.filename.find(match_token) != string::npos)
-    return true;
-
-  // TODO(user): All searches should probably be case-insensitive
-  // (especially this one...)
-  if (options.flag_description_substring_search &&
-      flag.description.find(match_token) != string::npos)
-    return true;
-
-  return false;
-}
-
-// 3) Categorize matches (and helper method)
-
-// Given a set of matching flags, categorize them by
-// likely relevence to this specific binary
-static void CategorizeAllMatchingFlags(
-    const set<const CommandLineFlagInfo *> &all_matches,
-    const string &search_token,
-    const string &module,  // empty if we couldn't find any
-    const string &package_dir,  // empty if we couldn't find any
-    NotableFlags *notable_flags) {
-  notable_flags->perfect_match_flag.clear();
-  notable_flags->module_flags.clear();
-  notable_flags->package_flags.clear();
-  notable_flags->most_common_flags.clear();
-  notable_flags->subpackage_flags.clear();
-
-  for (set<const CommandLineFlagInfo *>::const_iterator it =
-        all_matches.begin();
-      it != all_matches.end();
-      ++it) {
-    DVLOG(2) << "Examining match '" << (*it)->name << "'";
-    DVLOG(7) << "  filename: '" << (*it)->filename << "'";
-    string::size_type pos = string::npos;
-    if (!package_dir.empty())
-      pos = (*it)->filename.find(package_dir);
-    string::size_type slash = string::npos;
-    if (pos != string::npos)  // candidate for package or subpackage match
-      slash = (*it)->filename.find(
-          PATH_SEPARATOR,
-          pos + package_dir.size() + 1);
-
-    if ((*it)->name == search_token) {
-      // Exact match on some flag's name
-      notable_flags->perfect_match_flag.insert(*it);
-      DVLOG(3) << "Result: perfect match";
-    } else if (!module.empty() && (*it)->filename == module) {
-      // Exact match on module filename
-      notable_flags->module_flags.insert(*it);
-      DVLOG(3) << "Result: module match";
-    } else if (!package_dir.empty() &&
-        pos != string::npos && slash == string::npos) {
-      // In the package, since there was no slash after the package portion
-      notable_flags->package_flags.insert(*it);
-      DVLOG(3) << "Result: package match";
-    } else if (false) {
-      // In the list of the XXX most commonly supplied flags overall
-      // TODO(user): Compile this list.
-      DVLOG(3) << "Result: most-common match";
-    } else if (!package_dir.empty() &&
-        pos != string::npos && slash != string::npos) {
-      // In a subdirectory of the package
-      notable_flags->subpackage_flags.insert(*it);
-      DVLOG(3) << "Result: subpackage match";
-    }
-
-    DVLOG(3) << "Result: not special match";
-  }
-}
-
-static void PushNameWithSuffix(vector<string>* suffixes, const char* suffix) {
-  suffixes->push_back(
-      StringPrintf("/%s%s", ProgramInvocationShortName(), suffix));
-}
-
-static void TryFindModuleAndPackageDir(
-    const vector<CommandLineFlagInfo> &all_flags,
-    string *module,
-    string *package_dir) {
-  module->clear();
-  package_dir->clear();
-
-  vector<string> suffixes;
-  // TODO(user): There's some inherant ambiguity here - multiple directories
-  // could share the same trailing folder and file structure (and even worse,
-  // same file names), causing us to be unsure as to which of the two is the
-  // actual package for this binary.  In this case, we'll arbitrarily choose.
-  PushNameWithSuffix(&suffixes, ".");
-  PushNameWithSuffix(&suffixes, "-main.");
-  PushNameWithSuffix(&suffixes, "_main.");
-  // These four are new but probably merited?
-  PushNameWithSuffix(&suffixes, "-test.");
-  PushNameWithSuffix(&suffixes, "_test.");
-  PushNameWithSuffix(&suffixes, "-unittest.");
-  PushNameWithSuffix(&suffixes, "_unittest.");
-
-  for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
-      it != all_flags.end();
-      ++it) {
-    for (vector<string>::const_iterator suffix = suffixes.begin();
-        suffix != suffixes.end();
-        ++suffix) {
-      // TODO(user): Make sure the match is near the end of the string
-      if (it->filename.find(*suffix) != string::npos) {
-        *module = it->filename;
-        string::size_type sep = it->filename.rfind(PATH_SEPARATOR);
-        *package_dir = it->filename.substr(0, (sep == string::npos) ? 0 : sep);
-        return;
-      }
-    }
-  }
-}
-
-// Can't specialize template type on a locally defined type.  Silly C++...
-struct DisplayInfoGroup {
-  const char* header;
-  const char* footer;
-  set<const CommandLineFlagInfo *> *group;
-
-  int SizeInLines() const {
-    int size_in_lines = static_cast<int>(group->size()) + 1;
-    if (strlen(header) > 0) {
-      size_in_lines++;
-    }
-    if (strlen(footer) > 0) {
-      size_in_lines++;
-    }
-    return size_in_lines;
-  }
-};
-
-// 4) Finalize and trim output flag set
-static void FinalizeCompletionOutput(
-    const set<const CommandLineFlagInfo *> &matching_flags,
-    CompletionOptions *options,
-    NotableFlags *notable_flags,
-    vector<string> *completions) {
-
-  // We want to output lines in groups.  Each group needs to be indented
-  // the same to keep its lines together.  Unless otherwise required,
-  // only 99 lines should be output to prevent bash from harassing the
-  // user.
-
-  // First, figure out which output groups we'll actually use.  For each
-  // nonempty group, there will be ~3 lines of header & footer, plus all
-  // output lines themselves.
-  int max_desired_lines =  // "999999 flags should be enough for anyone.  -dave"
-    (options->return_all_matching_flags ? 999999 : 98);
-  int lines_so_far = 0;
-
-  vector<DisplayInfoGroup> output_groups;
-  bool perfect_match_found = false;
-  if (!notable_flags->perfect_match_flag.empty()) {
-    perfect_match_found = true;
-    DisplayInfoGroup group =
-        { "",
-          "==========",
-          &notable_flags->perfect_match_flag };
-    lines_so_far += group.SizeInLines();
-    output_groups.push_back(group);
-  }
-  if (lines_so_far < max_desired_lines &&
-      !notable_flags->module_flags.empty()) {
-    DisplayInfoGroup group = {
-        "-* Matching module flags *-",
-        "===========================",
-        &notable_flags->module_flags };
-    lines_so_far += group.SizeInLines();
-    output_groups.push_back(group);
-  }
-  if (lines_so_far < max_desired_lines &&
-      !notable_flags->package_flags.empty()) {
-    DisplayInfoGroup group = {
-        "-* Matching package flags *-",
-        "============================",
-        &notable_flags->package_flags };
-    lines_so_far += group.SizeInLines();
-    output_groups.push_back(group);
-  }
-  if (lines_so_far < max_desired_lines &&
-      !notable_flags->most_common_flags.empty()) {
-    DisplayInfoGroup group = {
-        "-* Commonly used flags *-",
-        "=========================",
-        &notable_flags->most_common_flags };
-    lines_so_far += group.SizeInLines();
-    output_groups.push_back(group);
-  }
-  if (lines_so_far < max_desired_lines &&
-      !notable_flags->subpackage_flags.empty()) {
-    DisplayInfoGroup group = {
-        "-* Matching sub-package flags *-",
-        "================================",
-        &notable_flags->subpackage_flags };
-    lines_so_far += group.SizeInLines();
-    output_groups.push_back(group);
-  }
-
-  set<const CommandLineFlagInfo *> obscure_flags;  // flags not notable
-  if (lines_so_far < max_desired_lines) {
-    RetrieveUnusedFlags(matching_flags, *notable_flags, &obscure_flags);
-    if (!obscure_flags.empty()) {
-      DisplayInfoGroup group = {
-          "-* Other flags *-",
-          "",
-          &obscure_flags };
-      lines_so_far += group.SizeInLines();
-      output_groups.push_back(group);
-    }
-  }
-
-  // Second, go through each of the chosen output groups and output
-  // as many of those flags as we can, while remaining below our limit
-  int remaining_lines = max_desired_lines;
-  size_t completions_output = 0;
-  int indent = static_cast<int>(output_groups.size()) - 1;
-  for (vector<DisplayInfoGroup>::const_iterator it =
-        output_groups.begin();
-      it != output_groups.end();
-      ++it, --indent) {
-    OutputSingleGroupWithLimit(
-        *it->group,  // group
-        string(indent, ' '),  // line indentation
-        string(it->header),  // header
-        string(it->footer),  // footer
-        perfect_match_found,  // long format
-        &remaining_lines,  // line limit - reduces this by number printed
-        &completions_output,  // completions (not lines) added
-        completions);  // produced completions
-    perfect_match_found = false;
-  }
-
-  if (completions_output != matching_flags.size()) {
-    options->force_no_update = false;
-    completions->push_back("~ (Remaining flags hidden) ~");
-  } else {
-    options->force_no_update = true;
-  }
-}
-
-static void RetrieveUnusedFlags(
-    const set<const CommandLineFlagInfo *> &matching_flags,
-    const NotableFlags &notable_flags,
-    set<const CommandLineFlagInfo *> *unused_flags) {
-  // Remove from 'matching_flags' set all members of the sets of
-  // flags we've already printed (specifically, those in notable_flags)
-  for (set<const CommandLineFlagInfo *>::const_iterator it =
-        matching_flags.begin();
-      it != matching_flags.end();
-      ++it) {
-    if (notable_flags.perfect_match_flag.count(*it) ||
-        notable_flags.module_flags.count(*it) ||
-        notable_flags.package_flags.count(*it) ||
-        notable_flags.most_common_flags.count(*it) ||
-        notable_flags.subpackage_flags.count(*it))
-      continue;
-    unused_flags->insert(*it);
-  }
-}
-
-// 5) Output matches (and helper methods)
-
-static void OutputSingleGroupWithLimit(
-    const set<const CommandLineFlagInfo *> &group,
-    const string &line_indentation,
-    const string &header,
-    const string &footer,
-    bool long_output_format,
-    int *remaining_line_limit,
-    size_t *completion_elements_output,
-    vector<string> *completions) {
-  if (group.empty()) return;
-  if (!header.empty()) {
-    if (*remaining_line_limit < 2) return;
-    *remaining_line_limit -= 2;
-    completions->push_back(line_indentation + header);
-    completions->push_back(line_indentation + string(header.size(), '-'));
-  }
-  for (set<const CommandLineFlagInfo *>::const_iterator it = group.begin();
-      it != group.end() && *remaining_line_limit > 0;
-      ++it) {
-    --*remaining_line_limit;
-    ++*completion_elements_output;
-    completions->push_back(
-        (long_output_format
-          ? GetLongFlagLine(line_indentation, **it)
-          : GetShortFlagLine(line_indentation, **it)));
-  }
-  if (!footer.empty()) {
-    if (*remaining_line_limit < 1) return;
-    --*remaining_line_limit;
-    completions->push_back(line_indentation + footer);
-  }
-}
-
-static string GetShortFlagLine(
-    const string &line_indentation,
-    const CommandLineFlagInfo &info) {
-  string prefix;
-  bool is_string = (info.type == "string");
-  SStringPrintf(&prefix, "%s--%s [%s%s%s] ",
-                line_indentation.c_str(),
-                info.name.c_str(),
-                (is_string ? "'" : ""),
-                info.default_value.c_str(),
-                (is_string ? "'" : ""));
-  int remainder =
-      FLAGS_tab_completion_columns - static_cast<int>(prefix.size());
-  string suffix;
-  if (remainder > 0)
-    suffix =
-        (static_cast<int>(info.description.size()) > remainder ?
-         (info.description.substr(0, remainder - 3) + "...").c_str() :
-         info.description.c_str());
-  return prefix + suffix;
-}
-
-static string GetLongFlagLine(
-    const string &line_indentation,
-    const CommandLineFlagInfo &info) {
-
-  string output = DescribeOneFlag(info);
-
-  // Replace '-' with '--', and remove trailing newline before appending
-  // the module definition location.
-  string old_flagname = "-" + info.name;
-  output.replace(
-      output.find(old_flagname),
-      old_flagname.size(),
-      "-" + old_flagname);
-  // Stick a newline and indentation in front of the type and default
-  // portions of DescribeOneFlag()s description
-  static const char kNewlineWithIndent[] = "\n    ";
-  output.replace(output.find(" type:"), 1, string(kNewlineWithIndent));
-  output.replace(output.find(" default:"), 1, string(kNewlineWithIndent));
-  output = StringPrintf("%s Details for '--%s':\n"
-                        "%s    defined: %s",
-                        line_indentation.c_str(),
-                        info.name.c_str(),
-                        output.c_str(),
-                        info.filename.c_str());
-
-  // Eliminate any doubled newlines that crept in.  Specifically, if
-  // DescribeOneFlag() decided to break the line just before "type"
-  // or "default", we don't want to introduce an extra blank line
-  static const string line_of_spaces(FLAGS_tab_completion_columns, ' ');
-  static const char kDoubledNewlines[] = "\n     \n";
-  for (string::size_type newlines = output.find(kDoubledNewlines);
-      newlines != string::npos;
-      newlines = output.find(kDoubledNewlines))
-    // Replace each 'doubled newline' with a single newline
-    output.replace(newlines, sizeof(kDoubledNewlines) - 1, string("\n"));
-
-  for (string::size_type newline = output.find('\n');
-      newline != string::npos;
-      newline = output.find('\n')) {
-    int newline_pos = static_cast<int>(newline) % FLAGS_tab_completion_columns;
-    int missing_spaces = FLAGS_tab_completion_columns - newline_pos;
-    output.replace(newline, 1, line_of_spaces, 1, missing_spaces);
-  }
-  return output;
-}
-}  // anonymous
-
-void HandleCommandLineCompletions(void) {
-  if (FLAGS_tab_completion_word.empty()) return;
-  PrintFlagCompletionInfo();
-  gflags_exitfunc(0);
-}
-
-
-} // namespace GFLAGS_NAMESPACE
diff --git a/third_party/gflags/src/gflags_completions.h.in b/third_party/gflags/src/gflags_completions.h.in
deleted file mode 100644
index b27e5fd..0000000
--- a/third_party/gflags/src/gflags_completions.h.in
+++ /dev/null
@@ -1,121 +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.
-//
-// ---
-
-//
-// Implement helpful bash-style command line flag completions
-//
-// ** Functional API:
-// HandleCommandLineCompletions() should be called early during
-// program startup, but after command line flag code has been
-// initialized, such as the beginning of HandleCommandLineHelpFlags().
-// It checks the value of the flag --tab_completion_word.  If this
-// flag is empty, nothing happens here.  If it contains a string,
-// however, then HandleCommandLineCompletions() will hijack the
-// process, attempting to identify the intention behind this
-// completion.  Regardless of the outcome of this deduction, the
-// process will be terminated, similar to --helpshort flag
-// handling.
-//
-// ** Overview of Bash completions:
-// Bash can be told to programatically determine completions for the
-// current 'cursor word'.  It does this by (in this case) invoking a
-// command with some additional arguments identifying the command
-// being executed, the word being completed, and the previous word
-// (if any).  Bash then expects a sequence of output lines to be
-// printed to stdout.  If these lines all contain a common prefix
-// longer than the cursor word, bash will replace the cursor word
-// with that common prefix, and display nothing.  If there isn't such
-// a common prefix, bash will display the lines in pages using 'more'.
-//
-// ** Strategy taken for command line completions:
-// If we can deduce either the exact flag intended, or a common flag
-// prefix, we'll output exactly that.  Otherwise, if information
-// must be displayed to the user, we'll take the opportunity to add
-// some helpful information beyond just the flag name (specifically,
-// we'll include the default flag value and as much of the flag's
-// description as can fit on a single terminal line width, as specified
-// by the flag --tab_completion_columns).  Furthermore, we'll try to
-// make bash order the output such that the most useful or relevent
-// flags are the most likely to be shown at the top.
-//
-// ** Additional features:
-// To assist in finding that one really useful flag, substring matching
-// was implemented.  Before pressing a <TAB> to get completion for the
-// current word, you can append one or more '?' to the flag to do
-// substring matching.  Here's the semantics:
-//   --foo<TAB>     Show me all flags with names prefixed by 'foo'
-//   --foo?<TAB>    Show me all flags with 'foo' somewhere in the name
-//   --foo??<TAB>   Same as prior case, but also search in module
-//                  definition path for 'foo'
-//   --foo???<TAB>  Same as prior case, but also search in flag
-//                  descriptions for 'foo'
-// Finally, we'll trim the output to a relatively small number of
-// flags to keep bash quiet about the verbosity of output.  If one
-// really wanted to see all possible matches, appending a '+' to the
-// search word will force the exhaustive list of matches to be printed.
-//
-// ** How to have bash accept completions from a binary:
-// Bash requires that it be informed about each command that programmatic
-// completion should be enabled for.  Example addition to a .bashrc
-// file would be (your path to gflags_completions.sh file may differ):
-
-/*
-$ complete -o bashdefault -o default -o nospace -C                            \
- '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
-  time  env  binary_name  another_binary  [...]
-*/
-
-// This would allow the following to work:
-//   $ /path/to/binary_name --vmodule<TAB>
-// Or:
-//   $ ./bin/path/another_binary --gfs_u<TAB>
-// (etc)
-//
-// Sadly, it appears that bash gives no easy way to force this behavior for
-// all commands.  That's where the "time" in the above example comes in.
-// If you haven't specifically added a command to the list of completion
-// supported commands, you can still get completions by prefixing the
-// entire command with "env".
-//   $ env /some/brand/new/binary --vmod<TAB>
-// Assuming that "binary" is a newly compiled binary, this should still
-// produce the expected completion output.
-
-
-#ifndef GFLAGS_COMPLETIONS_H_
-#define GFLAGS_COMPLETIONS_H_
-
-namespace @GFLAGS_NAMESPACE@ {
-
-extern void HandleCommandLineCompletions(void);
-
-}
-
-#endif  // GFLAGS_COMPLETIONS_H_
diff --git a/third_party/gflags/src/gflags_completions.sh b/third_party/gflags/src/gflags_completions.sh
deleted file mode 100755
index c5fb7e6..0000000
--- a/third_party/gflags/src/gflags_completions.sh
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/bin/bash
-
-# 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: Dave Nicponski
-#
-# This script is invoked by bash in response to a matching compspec.  When
-# this happens, bash calls this script using the command shown in the -C
-# block of the complete entry, but also appends 3 arguments.  They are:
-#   - The command being used for completion
-#   - The word being completed
-#   - The word preceding the completion word.
-#
-# Here's an example of how you might use this script:
-# $ complete -o bashdefault -o default -o nospace -C                         \
-#   '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
-#   time  env  binary_name  another_binary  [...]
-
-# completion_word_index gets the index of the (N-1)th argument for
-# this command line.  completion_word gets the actual argument from
-# this command line at the (N-1)th position
-completion_word_index="$(($# - 1))"
-completion_word="${!completion_word_index}"
-
-# TODO(user): Replace this once gflags_completions.cc has
-# a bool parameter indicating unambiguously to hijack the process for
-# completion purposes.
-if [ -z "$completion_word" ]; then
-  # Until an empty value for the completion word stops being misunderstood
-  # by binaries, don't actually execute the binary or the process
-  # won't be hijacked!
-  exit 0
-fi
-
-# binary_index gets the index of the command being completed (which bash
-# places in the (N-2)nd position.  binary gets the actual command from
-# this command line at that (N-2)nd position
-binary_index="$(($# - 2))"
-binary="${!binary_index}"
-
-# For completions to be universal, we may have setup the compspec to
-# trigger on 'harmless pass-through' commands, like 'time' or 'env'.
-# If the command being completed is one of those two, we'll need to
-# identify the actual command being executed.  To do this, we need
-# the actual command line that the <TAB> was pressed on.  Bash helpfully
-# places this in the $COMP_LINE variable.
-if [ "$binary" == "time" ] || [ "$binary" == "env" ]; then
-  # we'll assume that the first 'argument' is actually the
-  # binary
-
-
-  # TODO(user): This is not perfect - the 'env' command, for instance,
-  #   is allowed to have options between the 'env' and 'the command to
-  #   be executed'.  For example, consider:
-  # $ env FOO="bar"  bin/do_something  --help<TAB>
-  # In this case, we'll mistake the FOO="bar" portion as the binary.
-  #   Perhaps we should continuing consuming leading words until we
-  #   either run out of words, or find a word that is a valid file
-  #   marked as executable.  I can't think of any reason this wouldn't
-  #   work.
-
-  # Break up the 'original command line' (not this script's command line,
-  # rather the one the <TAB> was pressed on) and find the second word.
-  parts=( ${COMP_LINE} )
-  binary=${parts[1]}
-fi
-
-# Build the command line to use for completion.  Basically it involves
-# passing through all the arguments given to this script (except the 3
-# that bash added), and appending a '--tab_completion_word "WORD"' to
-# the arguments.
-params=""
-for ((i=1; i<=$(($# - 3)); ++i)); do 
-  params="$params \"${!i}\"";
-done
-params="$params --tab_completion_word \"$completion_word\""
-
-# TODO(user): Perhaps stash the output in a temporary file somewhere
-# in /tmp, and only cat it to stdout if the command returned a success
-# code, to prevent false positives
-
-# If we think we have a reasonable command to execute, then execute it
-# and hope for the best.
-candidate=$(type -p "$binary")
-if [ ! -z "$candidate" ]; then
-  eval "$candidate 2>/dev/null $params"
-elif [ -f "$binary" ] && [ -x "$binary" ]; then
-  eval "$binary 2>/dev/null $params"
-fi
diff --git a/third_party/gflags/src/gflags_declare.h.in b/third_party/gflags/src/gflags_declare.h.in
deleted file mode 100644
index 752a34d..0000000
--- a/third_party/gflags/src/gflags_declare.h.in
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 1999, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-//
-// Revamped and reorganized by Craig Silverstein
-//
-// This is the file that should be included by any file which declares
-// command line flag.
-
-#ifndef GFLAGS_DECLARE_H_
-#define GFLAGS_DECLARE_H_
-
-
-// ---------------------------------------------------------------------------
-// Namespace of gflags library symbols.
-#define GFLAGS_NAMESPACE @GFLAGS_NAMESPACE@
-
-// ---------------------------------------------------------------------------
-// Windows DLL import/export.
-
-// Whether gflags library is a DLL.
-//
-// Set to 1 by default when the shared gflags library was built on Windows.
-// Must be overwritten when this header file is used with the optionally also
-// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS.
-#ifndef GFLAGS_IS_A_DLL
-#  define GFLAGS_IS_A_DLL @GFLAGS_IS_A_DLL@
-#endif
-
-// We always want to import the symbols of the gflags library.
-#ifndef GFLAGS_DLL_DECL
-#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
-#    define GFLAGS_DLL_DECL __declspec(dllimport)
-#  else
-#    define GFLAGS_DLL_DECL
-#  endif
-#endif
-
-// We always want to import variables declared in user code.
-#ifndef GFLAGS_DLL_DECLARE_FLAG
-#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
-#    define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
-#  else
-#    define GFLAGS_DLL_DECLARE_FLAG
-#  endif
-#endif
-
-// ---------------------------------------------------------------------------
-// Flag types
-#include <string>
-#if @HAVE_STDINT_H@
-#  include <stdint.h>                   // the normal place uint32_t is defined
-#elif @HAVE_SYS_TYPES_H@
-#  include <sys/types.h>                // the normal place u_int32_t is defined
-#elif @HAVE_INTTYPES_H@
-#  include <inttypes.h>                 // a third place for uint32_t or u_int32_t
-#endif
-
-namespace GFLAGS_NAMESPACE {
-
-#if @GFLAGS_INTTYPES_FORMAT_C99@ // C99
-typedef int32_t          int32;
-typedef uint32_t         uint32;
-typedef int64_t          int64;
-typedef uint64_t         uint64;
-#elif @GFLAGS_INTTYPES_FORMAT_BSD@ // BSD
-typedef int32_t          int32;
-typedef u_int32_t        uint32;
-typedef int64_t          int64;
-typedef u_int64_t        uint64;
-#elif @GFLAGS_INTTYPES_FORMAT_VC7@ // Windows
-typedef __int32          int32;
-typedef unsigned __int32 uint32;
-typedef __int64          int64;
-typedef unsigned __int64 uint64;
-#else
-#  error Do not know how to define a 32-bit integer quantity on your system
-#endif
-
-} // namespace GFLAGS_NAMESPACE
-
-
-namespace fLS {
-
-// The meaning of "string" might be different between now and when the
-// macros below get invoked (e.g., if someone is experimenting with
-// other string implementations that get defined after this file is
-// included).  Save the current meaning now and use it in the macros.
-typedef std::string clstring;
-
-} // namespace fLS
-
-
-#define DECLARE_VARIABLE(type, shorttype, name) \
-  /* We always want to import declared variables, dll or no */ \
-  namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
-  using fL##shorttype::FLAGS_##name
-
-#define DECLARE_bool(name) \
-  DECLARE_VARIABLE(bool, B, name)
-
-#define DECLARE_int32(name) \
-  DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
-
-#define DECLARE_uint32(name) \
-  DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name)
-
-#define DECLARE_int64(name) \
-  DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
-
-#define DECLARE_uint64(name) \
-  DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
-
-#define DECLARE_double(name) \
-  DECLARE_VARIABLE(double, D, name)
-
-#define DECLARE_string(name) \
-  /* We always want to import declared variables, dll or no */ \
-  namespace fLS { \
-  extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
-  } \
-  using fLS::FLAGS_##name
-
-
-#endif  // GFLAGS_DECLARE_H_
diff --git a/third_party/gflags/src/gflags_ns.h.in b/third_party/gflags/src/gflags_ns.h.in
deleted file mode 100644
index ef6ac29..0000000
--- a/third_party/gflags/src/gflags_ns.h.in
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2014, Andreas Schuh
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// -----------------------------------------------------------------------------
-// Imports the gflags library symbols into an alternative/deprecated namespace.
-
-#ifndef GFLAGS_GFLAGS_H_
-#  error The internal header gflags_@ns@.h may only be included by gflags.h
-#endif
-
-#ifndef GFLAGS_NS_@NS@_H_
-#define GFLAGS_NS_@NS@_H_
-
-
-namespace @ns@ {
-
-
-using GFLAGS_NAMESPACE::int32;
-using GFLAGS_NAMESPACE::uint32;
-using GFLAGS_NAMESPACE::int64;
-using GFLAGS_NAMESPACE::uint64;
-
-using GFLAGS_NAMESPACE::RegisterFlagValidator;
-using GFLAGS_NAMESPACE::CommandLineFlagInfo;
-using GFLAGS_NAMESPACE::GetAllFlags;
-using GFLAGS_NAMESPACE::ShowUsageWithFlags;
-using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict;
-using GFLAGS_NAMESPACE::DescribeOneFlag;
-using GFLAGS_NAMESPACE::SetArgv;
-using GFLAGS_NAMESPACE::GetArgvs;
-using GFLAGS_NAMESPACE::GetArgv;
-using GFLAGS_NAMESPACE::GetArgv0;
-using GFLAGS_NAMESPACE::GetArgvSum;
-using GFLAGS_NAMESPACE::ProgramInvocationName;
-using GFLAGS_NAMESPACE::ProgramInvocationShortName;
-using GFLAGS_NAMESPACE::ProgramUsage;
-using GFLAGS_NAMESPACE::VersionString;
-using GFLAGS_NAMESPACE::GetCommandLineOption;
-using GFLAGS_NAMESPACE::GetCommandLineFlagInfo;
-using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie;
-using GFLAGS_NAMESPACE::FlagSettingMode;
-using GFLAGS_NAMESPACE::SET_FLAGS_VALUE;
-using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT;
-using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT;
-using GFLAGS_NAMESPACE::SetCommandLineOption;
-using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode;
-using GFLAGS_NAMESPACE::FlagSaver;
-using GFLAGS_NAMESPACE::CommandlineFlagsIntoString;
-using GFLAGS_NAMESPACE::ReadFlagsFromString;
-using GFLAGS_NAMESPACE::AppendFlagsIntoFile;
-using GFLAGS_NAMESPACE::ReadFromFlagsFile;
-using GFLAGS_NAMESPACE::BoolFromEnv;
-using GFLAGS_NAMESPACE::Int32FromEnv;
-using GFLAGS_NAMESPACE::Uint32FromEnv;
-using GFLAGS_NAMESPACE::Int64FromEnv;
-using GFLAGS_NAMESPACE::Uint64FromEnv;
-using GFLAGS_NAMESPACE::DoubleFromEnv;
-using GFLAGS_NAMESPACE::StringFromEnv;
-using GFLAGS_NAMESPACE::SetUsageMessage;
-using GFLAGS_NAMESPACE::SetVersionString;
-using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags;
-using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags;
-using GFLAGS_NAMESPACE::AllowCommandLineReparsing;
-using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags;
-using GFLAGS_NAMESPACE::ShutDownCommandLineFlags;
-using GFLAGS_NAMESPACE::FlagRegisterer;
-
-#ifndef SWIG
-using GFLAGS_NAMESPACE::ParseCommandLineFlags;
-#endif
-
-
-} // namespace @ns@
-
-
-#endif  // GFLAGS_NS_@NS@_H_
diff --git a/third_party/gflags/src/gflags_reporting.cc b/third_party/gflags/src/gflags_reporting.cc
deleted file mode 100644
index 29be922..0000000
--- a/third_party/gflags/src/gflags_reporting.cc
+++ /dev/null
@@ -1,442 +0,0 @@
-// Copyright (c) 1999, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-//
-// Revamped and reorganized by Craig Silverstein
-//
-// This file contains code for handling the 'reporting' flags.  These
-// are flags that, when present, cause the program to report some
-// information and then exit.  --help and --version are the canonical
-// reporting flags, but we also have flags like --helpxml, etc.
-//
-// There's only one function that's meant to be called externally:
-// HandleCommandLineHelpFlags().  (Well, actually, ShowUsageWithFlags(),
-// ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called
-// externally too, but there's little need for it.)  These are all
-// declared in the main gflags.h header file.
-//
-// HandleCommandLineHelpFlags() will check what 'reporting' flags have
-// been defined, if any -- the "help" part of the function name is a
-// bit misleading -- and do the relevant reporting.  It should be
-// called after all flag-values have been assigned, that is, after
-// parsing the command-line.
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-#include <string>
-#include <vector>
-
-#include "config.h"
-#include "gflags/gflags.h"
-#include "gflags/gflags_completions.h"
-#include "util.h"
-
-
-// The 'reporting' flags.  They all call gflags_exitfunc().
-DEFINE_bool  (help,        false, "show help on all flags [tip: all flags can have two dashes]");
-DEFINE_bool  (helpfull,    false, "show help on all flags -- same as -help");
-DEFINE_bool  (helpshort,   false, "show help on only the main module for this program");
-DEFINE_string(helpon,      "",    "show help on the modules named by this flag value");
-DEFINE_string(helpmatch,   "",    "show help on modules whose name contains the specified substr");
-DEFINE_bool  (helppackage, false, "show help on all modules in the main package");
-DEFINE_bool  (helpxml,     false, "produce an xml version of help");
-DEFINE_bool  (version,     false, "show version and build info and exit");
-
-
-namespace GFLAGS_NAMESPACE {
-
-
-using std::string;
-using std::vector;
-
-
-// --------------------------------------------------------------------
-// DescribeOneFlag()
-// DescribeOneFlagInXML()
-//    Routines that pretty-print info about a flag.  These use
-//    a CommandLineFlagInfo, which is the way the gflags
-//    API exposes static info about a flag.
-// --------------------------------------------------------------------
-
-static const int kLineLength = 80;
-
-static void AddString(const string& s,
-                      string* final_string, int* chars_in_line) {
-  const int slen = static_cast<int>(s.length());
-  if (*chars_in_line + 1 + slen >= kLineLength) {  // < 80 chars/line
-    *final_string += "\n      ";
-    *chars_in_line = 6;
-  } else {
-    *final_string += " ";
-    *chars_in_line += 1;
-  }
-  *final_string += s;
-  *chars_in_line += slen;
-}
-
-static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag,
-                                         const string& text, bool current) {
-  const char* c_string = (current ? flag.current_value.c_str() :
-                          flag.default_value.c_str());
-  if (strcmp(flag.type.c_str(), "string") == 0) {  // add quotes for strings
-    return StringPrintf("%s: \"%s\"", text.c_str(), c_string);
-  } else {
-    return StringPrintf("%s: %s", text.c_str(), c_string);
-  }
-}
-
-// Create a descriptive string for a flag.
-// Goes to some trouble to make pretty line breaks.
-string DescribeOneFlag(const CommandLineFlagInfo& flag) {
-  string main_part;
-  SStringPrintf(&main_part, "    -%s (%s)",
-                flag.name.c_str(),
-                flag.description.c_str());
-  const char* c_string = main_part.c_str();
-  int chars_left = static_cast<int>(main_part.length());
-  string final_string = "";
-  int chars_in_line = 0;  // how many chars in current line so far?
-  while (1) {
-    assert(static_cast<size_t>(chars_left)
-            == strlen(c_string));  // Unless there's a \0 in there?
-    const char* newline = strchr(c_string, '\n');
-    if (newline == NULL && chars_in_line+chars_left < kLineLength) {
-      // The whole remainder of the string fits on this line
-      final_string += c_string;
-      chars_in_line += chars_left;
-      break;
-    }
-    if (newline != NULL && newline - c_string < kLineLength - chars_in_line) {
-      int n = static_cast<int>(newline - c_string);
-      final_string.append(c_string, n);
-      chars_left -= n + 1;
-      c_string += n + 1;
-    } else {
-      // Find the last whitespace on this 80-char line
-      int whitespace = kLineLength-chars_in_line-1;  // < 80 chars/line
-      while ( whitespace > 0 && !isspace(c_string[whitespace]) ) {
-        --whitespace;
-      }
-      if (whitespace <= 0) {
-        // Couldn't find any whitespace to make a line break.  Just dump the
-        // rest out!
-        final_string += c_string;
-        chars_in_line = kLineLength;  // next part gets its own line for sure!
-        break;
-      }
-      final_string += string(c_string, whitespace);
-      chars_in_line += whitespace;
-      while (isspace(c_string[whitespace]))  ++whitespace;
-      c_string += whitespace;
-      chars_left -= whitespace;
-    }
-    if (*c_string == '\0')
-      break;
-    StringAppendF(&final_string, "\n      ");
-    chars_in_line = 6;
-  }
-
-  // Append data type
-  AddString(string("type: ") + flag.type, &final_string, &chars_in_line);
-  // The listed default value will be the actual default from the flag
-  // definition in the originating source file, unless the value has
-  // subsequently been modified using SetCommandLineOptionWithMode() with mode
-  // SET_FLAGS_DEFAULT, or by setting FLAGS_foo = bar before ParseCommandLineFlags().
-  AddString(PrintStringFlagsWithQuotes(flag, "default", false), &final_string,
-            &chars_in_line);
-  if (!flag.is_default) {
-    AddString(PrintStringFlagsWithQuotes(flag, "currently", true),
-              &final_string, &chars_in_line);
-  }
-
-  StringAppendF(&final_string, "\n");
-  return final_string;
-}
-
-// Simple routine to xml-escape a string: escape & and < only.
-static string XMLText(const string& txt) {
-  string ans = txt;
-  for (string::size_type pos = 0; (pos = ans.find("&", pos)) != string::npos; )
-    ans.replace(pos++, 1, "&amp;");
-  for (string::size_type pos = 0; (pos = ans.find("<", pos)) != string::npos; )
-    ans.replace(pos++, 1, "&lt;");
-  return ans;
-}
-
-static void AddXMLTag(string* r, const char* tag, const string& txt) {
-  StringAppendF(r, "<%s>%s</%s>", tag, XMLText(txt).c_str(), tag);
-}
-
-
-static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) {
-  // The file and flagname could have been attributes, but default
-  // and meaning need to avoid attribute normalization.  This way it
-  // can be parsed by simple programs, in addition to xml parsers.
-  string r("<flag>");
-  AddXMLTag(&r, "file", flag.filename);
-  AddXMLTag(&r, "name", flag.name);
-  AddXMLTag(&r, "meaning", flag.description);
-  AddXMLTag(&r, "default", flag.default_value);
-  AddXMLTag(&r, "current", flag.current_value);
-  AddXMLTag(&r, "type", flag.type);
-  r += "</flag>";
-  return r;
-}
-
-// --------------------------------------------------------------------
-// ShowUsageWithFlags()
-// ShowUsageWithFlagsRestrict()
-// ShowXMLOfFlags()
-//    These routines variously expose the registry's list of flag
-//    values.  ShowUsage*() prints the flag-value information
-//    to stdout in a user-readable format (that's what --help uses).
-//    The Restrict() version limits what flags are shown.
-//    ShowXMLOfFlags() prints the flag-value information to stdout
-//    in a machine-readable format.  In all cases, the flags are
-//    sorted: first by filename they are defined in, then by flagname.
-// --------------------------------------------------------------------
-
-static const char* Basename(const char* filename) {
-  const char* sep = strrchr(filename, PATH_SEPARATOR);
-  return sep ? sep + 1 : filename;
-}
-
-static string Dirname(const string& filename) {
-  string::size_type sep = filename.rfind(PATH_SEPARATOR);
-  return filename.substr(0, (sep == string::npos) ? 0 : sep);
-}
-
-// Test whether a filename contains at least one of the substrings.
-static bool FileMatchesSubstring(const string& filename,
-                                 const vector<string>& substrings) {
-  for (vector<string>::const_iterator target = substrings.begin();
-       target != substrings.end();
-       ++target) {
-    if (strstr(filename.c_str(), target->c_str()) != NULL)
-      return true;
-    // If the substring starts with a '/', that means that we want
-    // the string to be at the beginning of a directory component.
-    // That should match the first directory component as well, so
-    // we allow '/foo' to match a filename of 'foo'.
-    if (!target->empty() && (*target)[0] == PATH_SEPARATOR &&
-        strncmp(filename.c_str(), target->c_str() + 1,
-                strlen(target->c_str() + 1)) == 0)
-      return true;
-  }
-  return false;
-}
-
-// Show help for every filename which matches any of the target substrings.
-// If substrings is empty, shows help for every file. If a flag's help message
-// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1'
-// before including gflags/gflags.h), then this flag will not be displayed
-// by '--help' and its variants.
-static void ShowUsageWithFlagsMatching(const char *argv0,
-                                       const vector<string> &substrings) {
-  fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage());
-
-  vector<CommandLineFlagInfo> flags;
-  GetAllFlags(&flags);           // flags are sorted by filename, then flagname
-
-  string last_filename;          // so we know when we're at a new file
-  bool first_directory = true;   // controls blank lines between dirs
-  bool found_match = false;      // stays false iff no dir matches restrict
-  for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
-       flag != flags.end();
-       ++flag) {
-    if (substrings.empty() ||
-        FileMatchesSubstring(flag->filename, substrings)) {
-      // If the flag has been stripped, pretend that it doesn't exist.
-      if (flag->description == kStrippedFlagHelp) continue;
-      found_match = true;     // this flag passed the match!
-      if (flag->filename != last_filename) {                      // new file
-        if (Dirname(flag->filename) != Dirname(last_filename)) {  // new dir!
-          if (!first_directory)
-            fprintf(stdout, "\n\n");   // put blank lines between directories
-          first_directory = false;
-        }
-        fprintf(stdout, "\n  Flags from %s:\n", flag->filename.c_str());
-        last_filename = flag->filename;
-      }
-      // Now print this flag
-      fprintf(stdout, "%s", DescribeOneFlag(*flag).c_str());
-    }
-  }
-  if (!found_match && !substrings.empty()) {
-    fprintf(stdout, "\n  No modules matched: use -help\n");
-  }
-}
-
-void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict_) {
-  vector<string> substrings;
-  if (restrict_ != NULL && *restrict_ != '\0') {
-    substrings.push_back(restrict_);
-  }
-  ShowUsageWithFlagsMatching(argv0, substrings);
-}
-
-void ShowUsageWithFlags(const char *argv0) {
-  ShowUsageWithFlagsRestrict(argv0, "");
-}
-
-// Convert the help, program, and usage to xml.
-static void ShowXMLOfFlags(const char *prog_name) {
-  vector<CommandLineFlagInfo> flags;
-  GetAllFlags(&flags);   // flags are sorted: by filename, then flagname
-
-  // XML.  There is no corresponding schema yet
-  fprintf(stdout, "<?xml version=\"1.0\"?>\n");
-  // The document
-  fprintf(stdout, "<AllFlags>\n");
-  // the program name and usage
-  fprintf(stdout, "<program>%s</program>\n",
-          XMLText(Basename(prog_name)).c_str());
-  fprintf(stdout, "<usage>%s</usage>\n",
-          XMLText(ProgramUsage()).c_str());
-  // All the flags
-  for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
-       flag != flags.end();
-       ++flag) {
-    if (flag->description != kStrippedFlagHelp)
-      fprintf(stdout, "%s\n", DescribeOneFlagInXML(*flag).c_str());
-  }
-  // The end of the document
-  fprintf(stdout, "</AllFlags>\n");
-}
-
-// --------------------------------------------------------------------
-// ShowVersion()
-//    Called upon --version.  Prints build-related info.
-// --------------------------------------------------------------------
-
-static void ShowVersion() {
-  const char* version_string = VersionString();
-  if (version_string && *version_string) {
-    fprintf(stdout, "%s version %s\n",
-            ProgramInvocationShortName(), version_string);
-  } else {
-    fprintf(stdout, "%s\n", ProgramInvocationShortName());
-  }
-# if !defined(NDEBUG)
-  fprintf(stdout, "Debug build (NDEBUG not #defined)\n");
-# endif
-}
-
-static void AppendPrognameStrings(vector<string>* substrings,
-                                  const char* progname) {
-  string r("");
-  r += PATH_SEPARATOR;
-  r += progname;
-  substrings->push_back(r + ".");
-  substrings->push_back(r + "-main.");
-  substrings->push_back(r + "_main.");
-}
-
-// --------------------------------------------------------------------
-// HandleCommandLineHelpFlags()
-//    Checks all the 'reporting' commandline flags to see if any
-//    have been set.  If so, handles them appropriately.  Note
-//    that all of them, by definition, cause the program to exit
-//    if they trigger.
-// --------------------------------------------------------------------
-
-void HandleCommandLineHelpFlags() {
-  const char* progname = ProgramInvocationShortName();
-
-  HandleCommandLineCompletions();
-
-  vector<string> substrings;
-  AppendPrognameStrings(&substrings, progname);
-
-  if (FLAGS_helpshort) {
-    // show only flags related to this binary:
-    // E.g. for fileutil.cc, want flags containing   ... "/fileutil." cc
-    ShowUsageWithFlagsMatching(progname, substrings);
-    gflags_exitfunc(1);
-
-  } else if (FLAGS_help || FLAGS_helpfull) {
-    // show all options
-    ShowUsageWithFlagsRestrict(progname, "");   // empty restrict
-    gflags_exitfunc(1);
-
-  } else if (!FLAGS_helpon.empty()) {
-    string restrict_ = PATH_SEPARATOR + FLAGS_helpon + ".";
-    ShowUsageWithFlagsRestrict(progname, restrict_.c_str());
-    gflags_exitfunc(1);
-
-  } else if (!FLAGS_helpmatch.empty()) {
-    ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str());
-    gflags_exitfunc(1);
-
-  } else if (FLAGS_helppackage) {
-    // Shows help for all files in the same directory as main().  We
-    // don't want to resort to looking at dirname(progname), because
-    // the user can pick progname, and it may not relate to the file
-    // where main() resides.  So instead, we search the flags for a
-    // filename like "/progname.cc", and take the dirname of that.
-    vector<CommandLineFlagInfo> flags;
-    GetAllFlags(&flags);
-    string last_package;
-    for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
-         flag != flags.end();
-         ++flag) {
-      if (!FileMatchesSubstring(flag->filename, substrings))
-        continue;
-      const string package = Dirname(flag->filename) + PATH_SEPARATOR;
-      if (package != last_package) {
-        ShowUsageWithFlagsRestrict(progname, package.c_str());
-        VLOG(7) << "Found package: " << package;
-        if (!last_package.empty()) {      // means this isn't our first pkg
-          LOG(WARNING) << "Multiple packages contain a file=" << progname;
-        }
-        last_package = package;
-      }
-    }
-    if (last_package.empty()) {   // never found a package to print
-      LOG(WARNING) << "Unable to find a package for file=" << progname;
-    }
-    gflags_exitfunc(1);
-
-  } else if (FLAGS_helpxml) {
-    ShowXMLOfFlags(progname);
-    gflags_exitfunc(1);
-
-  } else if (FLAGS_version) {
-    ShowVersion();
-    // Unlike help, we may be asking for version in a script, so return 0
-    gflags_exitfunc(0);
-
-  }
-}
-
-
-} // namespace GFLAGS_NAMESPACE
diff --git a/third_party/gflags/src/mutex.h b/third_party/gflags/src/mutex.h
deleted file mode 100644
index 7d7c364..0000000
--- a/third_party/gflags/src/mutex.h
+++ /dev/null
@@ -1,348 +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.
-// 
-// ---
-//
-// A simple mutex wrapper, supporting locks and read-write locks.
-// You should assume the locks are *not* re-entrant.
-//
-// 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: by default, we have #ifdef'ed out the TryLock() method.
-//       This is for two reasons:
-// 1) TryLock() under Windows is a bit annoying (it requires a
-//    #define to be defined very early).
-// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG
-//    mode.
-// If you need TryLock(), and either these two caveats are not a
-// problem for you, or you're willing to work around them, then
-// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs
-// in the code below.
-//
-// 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 GFLAGS_MUTEX_H_
-#define GFLAGS_MUTEX_H_
-
-#include "gflags/gflags_declare.h"     // to figure out pthreads support
-
-#if defined(NO_THREADS)
-  typedef int MutexType;        // to keep a lock-count
-#elif defined(OS_WINDOWS)
-# ifndef WIN32_LEAN_AND_MEAN
-#   define WIN32_LEAN_AND_MEAN  // We only need minimal includes
-# endif
-# ifndef NOMINMAX
-#   define NOMINMAX             // Don't want windows to override min()/max()
-# endif
-# ifdef GMUTEX_TRYLOCK
-  // 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
-# 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__
-#   if _XOPEN_SOURCE < 500      // including not being defined at all
-#     undef _XOPEN_SOURCE
-#     define _XOPEN_SOURCE 500  // may be needed to get the rwlock calls
-#   endif
-# 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 gflags_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.
-  explicit 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()
-#ifdef GMUTEX_TRYLOCK
-  inline bool TryLock(); // If free, Lock() and return true, else return false
-#endif
-  // 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.
-  explicit 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); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }
-#endif
-void Mutex::ReaderLock()   { assert(++mutex_ > 0); }
-void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
-
-#elif defined(OS_WINDOWS)
-
-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_); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 TryEnterCriticalSection(&mutex_) != 0 : true; }
-#endif
-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); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { return is_safe_ ?
-                               pthread_rwlock_trywrlock(&mutex_) == 0 : true; }
-#endif
-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); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 pthread_mutex_trylock(&mutex_) == 0 : true; }
-#endif
-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
-
-
-#endif  /* #define GFLAGS_MUTEX_H__ */
diff --git a/third_party/gflags/src/util.h b/third_party/gflags/src/util.h
deleted file mode 100644
index 164e3cf..0000000
--- a/third_party/gflags/src/util.h
+++ /dev/null
@@ -1,373 +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.
-// ---
-//
-// Some generically useful utility routines that in google-land would
-// be their own projects.  We make a shortened version here.
-
-#ifndef GFLAGS_UTIL_H_
-#define GFLAGS_UTIL_H_
-
-#include "config.h"
-
-#include <assert.h>
-#ifdef HAVE_INTTYPES_H
-#  include <inttypes.h>
-#endif
-#include <stdarg.h>     // for va_*
-#include <stdlib.h>
-#include <stdio.h>
-#include <iostream>
-#include <string>
-#include <errno.h>
-#ifdef HAVE_SYS_STAT_H
-#  include <sys/stat.h> // for mkdir
-#endif
-
-
-namespace GFLAGS_NAMESPACE {
-
-
-// This is used for unittests for death-testing.  It is defined in gflags.cc.
-extern GFLAGS_DLL_DECL void (*gflags_exitfunc)(int);
-
-// Work properly if either strtoll or strtoq is on this system.
-#if defined(strtoll) || defined(HAVE_STRTOLL)
-#  define strto64  strtoll
-#  define strtou64 strtoull
-#elif defined(HAVE_STRTOQ)
-#  define strto64  strtoq
-#  define strtou64 strtouq
-// Neither strtoll nor strtoq are defined.  I hope strtol works!
-#else
-#  define strto64  strtol
-#  define strtou64 strtoul
-#endif
-
-// If we have inttypes.h, it will have defined PRId32/etc for us.
-// If not, take our best guess.
-#ifndef PRId32
-#  define PRId32 "d"
-#endif
-#ifndef PRId64
-#  define PRId64 "lld"
-#endif
-#ifndef PRIu64
-#  define PRIu64 "llu"
-#endif
-
-typedef signed char int8;
-typedef unsigned char uint8;
-
-// -- utility macros ---------------------------------------------------------
-
-template <bool b> struct CompileAssert;
-template <> struct CompileAssert<true> {};
-#define COMPILE_ASSERT(expr, msg) \
-  enum { assert_##msg = sizeof(CompileAssert<bool(expr)>) }
-
-// Returns the number of elements in an array.
-#define arraysize(arr) (sizeof(arr)/sizeof(*(arr)))
-
-
-// -- logging and testing ---------------------------------------------------
-
-// For now, we ignore the level for logging, and don't show *VLOG's at
-// all, except by hand-editing the lines below
-#define LOG(level)    std::cerr
-#define VLOG(level)   if (true) {} else std::cerr
-#define DVLOG(level)  if (true) {} else std::cerr
-
-// 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)
-// We allow stream-like objects after this for debugging, but they're ignored.
-#define EXPECT_TRUE(condition)                                  \
-  if (true) {                                                   \
-    if (!(condition)) {                                         \
-      fprintf(stderr, "Check failed: %s\n", #condition);        \
-      exit(1);                                                  \
-    }                                                           \
-  } else std::cerr << ""
-
-#define EXPECT_OP(op, val1, val2)                                       \
-  if (true) {                                                           \
-    if (!((val1) op (val2))) {                                          \
-      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
-      exit(1);                                                          \
-    }                                                                   \
-  } else std::cerr << ""
-
-#define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2)
-#define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2)
-#define EXPECT_LE(val1, val2) EXPECT_OP(<=, val1, val2)
-#define EXPECT_LT(val1, val2) EXPECT_OP(< , val1, val2)
-#define EXPECT_GE(val1, val2) EXPECT_OP(>=, val1, val2)
-#define EXPECT_GT(val1, val2) EXPECT_OP(> , val1, val2)
-#define EXPECT_FALSE(cond)    EXPECT_TRUE(!(cond))
-
-// C99 declares isnan and isinf should be macros, so the #ifdef test
-// should be reliable everywhere.  Of course, it's not, but these
-// are testing pertty marginal functionality anyway, so it's ok to
-// not-run them even in situations they might, with effort, be made to work.
-#ifdef isnan  // Some compilers, like sun's for Solaris 10, don't define this
-#define EXPECT_NAN(arg)                                         \
-  do {                                                          \
-    if (!isnan(arg)) {                                          \
-      fprintf(stderr, "Check failed: isnan(%s)\n", #arg);       \
-      exit(1);                                                  \
-    }                                                           \
-  } while (0)
-#else
-#define EXPECT_NAN(arg)
-#endif
-
-#ifdef isinf  // Some compilers, like sun's for Solaris 10, don't define this
-#define EXPECT_INF(arg)                                         \
-  do {                                                          \
-    if (!isinf(arg)) {                                          \
-      fprintf(stderr, "Check failed: isinf(%s)\n", #arg);       \
-      exit(1);                                                  \
-    }                                                           \
-  } while (0)
-#else
-#define EXPECT_INF(arg)
-#endif
-
-#define EXPECT_DOUBLE_EQ(val1, val2)                                    \
-  do {                                                                  \
-    if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) {         \
-      fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2);        \
-      exit(1);                                                          \
-    }                                                                   \
-  } while (0)
-
-#define EXPECT_STREQ(val1, val2)                                        \
-  do {                                                                  \
-    if (strcmp((val1), (val2)) != 0) {                                  \
-      fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2);   \
-      exit(1);                                                          \
-    }                                                                   \
-  } while (0)
-
-// Call this in a .cc file where you will later call RUN_ALL_TESTS in main().
-#define TEST_INIT                                                       \
-  static std::vector<void (*)()> g_testlist;  /* the tests to run */    \
-  static int RUN_ALL_TESTS() {                                          \
-    std::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;                                                           \
-  }
-
-// Note that this macro uses a FlagSaver to keep tests isolated.
-#define TEST(a, b)                                      \
-  struct Test_##a##_##b {                               \
-    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
-    static void Run() {                                 \
-      FlagSaver fs;                                     \
-      fprintf(stderr, "Running test %s/%s\n", #a, #b);  \
-      RunTest();                                        \
-    }                                                   \
-    static void RunTest();                              \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::RunTest()
-
-// This is a dummy class that eases the google->opensource transition.
-namespace testing {
-class Test {};
-}
-
-// Call this in a .cc file where you will later call EXPECT_DEATH
-#define EXPECT_DEATH_INIT                               \
-  static bool g_called_exit;                            \
-  static void CalledExit(int) { g_called_exit = true; }
-
-#define EXPECT_DEATH(fn, msg)                                           \
-  do {                                                                  \
-    g_called_exit = false;                                              \
-    gflags_exitfunc = &CalledExit;                            \
-    fn;                                                                 \
-    gflags_exitfunc = &exit;    /* set back to its default */ \
-    if (!g_called_exit) {                                               \
-      fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn);      \
-      exit(1);                                                          \
-    }                                                                   \
-  } while (0)
-
-#define GTEST_HAS_DEATH_TEST 1
-
-// -- path routines ----------------------------------------------------------
-
-// Tries to create the directory path as a temp-dir.  If it fails,
-// changes path to some directory it *can* create.
-#if defined(__MINGW32__)
-#include <io.h>
-inline void MakeTmpdir(std::string* path) {
-  if (!path->empty()) {
-	path->append("/gflags_unittest_testdir");
-	int err = mkdir(path->c_str());
-	if (err == 0 || errno == EEXIST) return;
-  }
-  // I had trouble creating a directory in /tmp from mingw
-  *path = "./gflags_unittest";
-  mkdir(path->c_str());
-}
-#elif defined(_MSC_VER)
-#include <direct.h>
-inline void MakeTmpdir(std::string* path) {
-  if (!path->empty()) {
-	int err = _mkdir(path->c_str());
-	if (err == 0 || errno == EEXIST) return;
-  }
-  char tmppath_buffer[1024];
-  int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
-  assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer));
-  assert(tmppath_buffer[tmppath_len - 1] == '\\');   // API guarantees it
-  *path = std::string(tmppath_buffer) + "gflags_unittest";
-  _mkdir(path->c_str());
-}
-#else
-inline void MakeTmpdir(std::string* path) {
-  if (!path->empty()) {
-	int err = mkdir(path->c_str(), 0755);
-	if (err == 0 || errno == EEXIST) return;
-  }
-  mkdir("/tmp/gflags_unittest", 0755);
-}
-#endif
-
-// -- string routines --------------------------------------------------------
-
-inline void InternalStringPrintf(std::string* output, const char* format,
-                                 va_list ap) {
-  char space[128];    // try a small buffer and hope it fits
-
-  // It's possible for methods that use a va_list to invalidate
-  // the data in it upon use.  The fix is to make a copy
-  // of the structure before using it and use that copy instead.
-  va_list backup_ap;
-  va_copy(backup_ap, ap);
-  int bytes_written = vsnprintf(space, sizeof(space), format, backup_ap);
-  va_end(backup_ap);
-
-  if ((bytes_written >= 0) && (static_cast<size_t>(bytes_written) < sizeof(space))) {
-    output->append(space, bytes_written);
-    return;
-  }
-
-  // Repeatedly increase buffer size until it fits.
-  int length = sizeof(space);
-  while (true) {
-    if (bytes_written < 0) {
-      // Older snprintf() behavior. :-(  Just try doubling the buffer size
-      length *= 2;
-    } else {
-      // We need exactly "bytes_written+1" characters
-      length = bytes_written+1;
-    }
-    char* buf = new char[length];
-
-    // Restore the va_list before we use it again
-    va_copy(backup_ap, ap);
-    bytes_written = vsnprintf(buf, length, format, backup_ap);
-    va_end(backup_ap);
-
-    if ((bytes_written >= 0) && (bytes_written < length)) {
-      output->append(buf, bytes_written);
-      delete[] buf;
-      return;
-    }
-    delete[] buf;
-  }
-}
-
-// Clears output before writing to it.
-inline void SStringPrintf(std::string* output, const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  output->clear();
-  InternalStringPrintf(output, format, ap);
-  va_end(ap);
-}
-
-inline void StringAppendF(std::string* output, const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  InternalStringPrintf(output, format, ap);
-  va_end(ap);
-}
-
-inline std::string StringPrintf(const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  std::string output;
-  InternalStringPrintf(&output, format, ap);
-  va_end(ap);
-  return output;
-}
-
-inline bool SafeGetEnv(const char *varname, std::string &valstr)
-{
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-	char  *val;
-	size_t sz;
-	if (_dupenv_s(&val, &sz, varname) != 0 || !val) return false;
-	valstr = val;
-	free(val);
-#else
-	const char * const val = getenv(varname);
-	if (!val) return false;
-	valstr = val;
-#endif
-	return true;
-}
-
-inline int SafeFOpen(FILE **fp, const char* fname, const char *mode)
-{
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-	return fopen_s(fp, fname, mode);
-#else
-	assert(fp != NULL);
-	*fp = fopen(fname, mode);
-    // errno only guaranteed to be set on failure
-	return ((*fp == NULL) ? errno : 0);
-#endif
-}
-
-
-} // namespace GFLAGS_NAMESPACE
-
-
-#endif  // GFLAGS_UTIL_H_
diff --git a/third_party/gflags/src/windows_port.cc b/third_party/gflags/src/windows_port.cc
deleted file mode 100644
index b5b7194..0000000
--- a/third_party/gflags/src/windows_port.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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 _WIN32
-#  error You should only be including windows/port.cc in a windows environment!
-#endif
-
-#include <string.h>    // for strlen(), memset(), memcmp()
-#include <assert.h>
-#include <stdarg.h>    // for va_list, va_start, va_end
-#include <windows.h>
-
-#include "windows_port.h"
-
-// These call the windows _vsnprintf, but always NUL-terminate.
-#if !defined(__MINGW32__) && !defined(__MINGW64__)  /* mingw already defines */
-#if !(defined(_MSC_VER) && _MSC_VER >= 1900)  /* msvc 2015 already defines */
-
-#ifdef _MSC_VER
-#  pragma warning(push)
-#  pragma warning(disable: 4996) // ignore _vsnprintf security warning
-#endif
-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);
-}
-#ifdef _MSC_VER
-#  pragma warning(pop)
-#endif
-
-int snprintf(char *str, size_t size, const char *format, ...) {
-  int r;
-  va_list ap;
-  va_start(ap, format);
-  r = vsnprintf(str, size, format, ap);
-  va_end(ap);
-  return r;
-}
-
-#endif  /* if !(defined(_MSC_VER) && _MSC_VER >= 1900)  */
-#endif  /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
diff --git a/third_party/gflags/src/windows_port.h b/third_party/gflags/src/windows_port.h
deleted file mode 100644
index 61cf5b7..0000000
--- a/third_party/gflags/src/windows_port.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* 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
- *
- * 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 GFLAGS_WINDOWS_PORT_H_
-#define GFLAGS_WINDOWS_PORT_H_
-
-#include "config.h"
-
-// This must be defined before the windows.h is included.
-// It's needed for mutex.h, to give access to the TryLock method.
-#  if !defined(_WIN32_WINNT) && !(defined( __MINGW32__) || defined(__MINGW64__))
-#    define _WIN32_WINNT 0x0400
-#  endif
-// We always want minimal includes
-#ifndef WIN32_LEAN_AND_MEAN
-#  define WIN32_LEAN_AND_MEAN
-#endif
-#include <windows.h>
-#include <direct.h>          /* for mkdir */
-#include <stdlib.h>          /* for _putenv, getenv */
-#include <stdio.h>           /* need this to override stdio's snprintf, also defines _unlink used by unit tests */
-#include <stdarg.h>          /* util.h uses va_copy */
-#include <string.h>          /* for _stricmp and _strdup */
-
-/* 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(__MINGW32__) && !defined(__MINGW64__)  /* mingw already defines */
-#if !(defined(_MSC_VER) && _MSC_VER >= 1900)  /* msvc 2015 already defines */
-extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size,
-                                       const char *format, ...);
-extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size,
-                                             const char *format, va_list ap);
-#define vsnprintf(str, size, format, ap)  safe_vsnprintf(str, size, format, ap)
-#define va_copy(dst, src)  (dst) = (src)
-#endif
-#endif  /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
-
-#ifdef _MSC_VER
-#  pragma warning(push)
-#  pragma warning(disable: 4996) // ignore getenv security warning
-#endif
-inline void setenv(const char* name, const char* value, int) {
-  // In windows, it's impossible to set a variable to the empty string.
-  // We handle this by setting it to "0" and the NUL-ing out the \0.
-  // That is, we putenv("FOO=0") and then find out where in memory the
-  // putenv wrote "FOO=0", and change it in-place to "FOO=\0".
-  // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508
-  static const char* const kFakeZero = "0";
-  if (*value == '\0')
-    value = kFakeZero;
-  // Apparently the semantics of putenv() is that the input
-  // must live forever, so we leak memory here. :-(
-  const size_t nameval_len = strlen(name) + 1 + strlen(value) + 1;
-  char* nameval = reinterpret_cast<char*>(malloc(nameval_len));
-  snprintf(nameval, nameval_len, "%s=%s", name, value);
-  _putenv(nameval);
-  if (value == kFakeZero) {
-    nameval[nameval_len - 2] = '\0';   // works when putenv() makes no copy
-    if (*getenv(name) != '\0')
-      *getenv(name) = '\0';            // works when putenv() copies nameval
-  }
-}
-#ifdef _MSC_VER
-#  pragma warning(pop)
-#endif
-
-#define strcasecmp _stricmp
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-#define strdup   _strdup
-#define unlink   _unlink
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1800
-#include <inttypes.h>
-#else
-#define PRId32  "d"
-#define PRIu32  "u"
-#define PRId64  "I64d"
-#define PRIu64  "I64u"
-#endif
-
-#if !defined(__MINGW32__) && !defined(__MINGW64__)
-#define strtoq   _strtoi64
-#define strtouq  _strtoui64
-#define strtoll  _strtoi64
-#define strtoull _strtoui64
-#define atoll    _atoi64
-#endif
-
-#ifndef PATH_MAX
-#define PATH_MAX 1024
-#endif
-
-#endif  /* GFLAGS_WINDOWS_PORT_H_ */
diff --git a/third_party/gflags/test/CMakeLists.txt b/third_party/gflags/test/CMakeLists.txt
deleted file mode 100644
index 4cd1e69..0000000
--- a/third_party/gflags/test/CMakeLists.txt
+++ /dev/null
@@ -1,209 +0,0 @@
-## gflags tests
-
-# ----------------------------------------------------------------------------
-# output directories
-set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
-set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
-set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
-
-# set working directory of test commands
-set (GFLAGS_FLAGFILES_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
-
-# ----------------------------------------------------------------------------
-# common include directories and link libraries
-include_directories ("${CMAKE_CURRENT_SOURCE_DIR}")
-include_directories ("${gflags_SOURCE_DIR}/src")
-include_directories ("${gflags_BINARY_DIR}/include")
-include_directories ("${gflags_BINARY_DIR}/include/gflags")
-
-if (BUILD_SHARED_LIBS)
-  set (type shared)
-  if (GFLAGS_IS_A_DLL)
-    add_definitions(-DGFLAGS_IS_A_DLL)
-  endif ()
-else ()
-  set (type static)
-endif ()
-if (BUILD_gflags_LIB)
-  link_libraries (gflags_${type})
-else ()
-  link_libraries (gflags_nothreads_${type})
-endif ()
-
-# ----------------------------------------------------------------------------
-# STRIP_FLAG_HELP
-add_executable (gflags_strip_flags_test gflags_strip_flags_test.cc)
-# Make sure the --help output doesn't print the stripped text.
-add_gflags_test (strip_flags_help 1 "" "This text should be stripped out" gflags_strip_flags_test --help)
-# Make sure the stripped text isn't in the binary at all.
-add_test (
-  NAME strip_flags_binary
-  COMMAND "${CMAKE_COMMAND}" "-DBINARY=$<TARGET_FILE:gflags_strip_flags_test>"
-          -P "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.cmake"
-  CONFIGURATIONS Release MinSizeRel
-)
-
-# ----------------------------------------------------------------------------
-# unit tests
-configure_file (gflags_unittest.cc gflags_unittest-main.cc COPYONLY)
-configure_file (gflags_unittest.cc gflags_unittest_main.cc COPYONLY)
-
-add_executable (gflags_unittest      gflags_unittest.cc)
-add_executable (gflags_unittest-main gflags_unittest-main.cc)
-add_executable (gflags_unittest_main gflags_unittest_main.cc)
-
-if (OS_WINDOWS)
-  set (SLASH "\\\\")
-else ()
-  set (SLASH "/")
-endif ()
-
-# First, just make sure the  gflags_unittest  works as-is
-add_gflags_test(unittest 0 "" "" gflags_unittest)
-
-# --help should show all flags, including flags from gflags_reporting
-add_gflags_test(help-reporting 1 "${SLASH}gflags_reporting.cc:" ""  gflags_unittest  --help)
-
-# Make sure that --help prints even very long helpstrings.
-add_gflags_test(long-helpstring 1 "end of a long helpstring" ""  gflags_unittest  --help)
-
-# Make sure --help reflects flag changes made before flag-parsing
-add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" ""  gflags_unittest  --help)
-add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" ""  gflags_unittest  --help)
-# And on the command-line, too
-add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" ""  gflags_unittest  --changeable_string_var 2 --help)
-
-# --nohelp and --help=false should be as if we didn't say anything
-add_gflags_test(nohelp     0 "PASS" ""  gflags_unittest  --nohelp)
-add_gflags_test(help=false 0 "PASS" ""  gflags_unittest  --help=false)
-
-# --helpfull is the same as help
-add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc:" ""  gflags_unittest  --helpfull)
-
-# --helpshort should show only flags from the  gflags_unittest  itself
-add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags_reporting.cc:"  gflags_unittest  --helpshort)
-
-# --helpshort should show the tldflag we created in the  gflags_unittest  dir
-add_gflags_test(helpshort-tldflag1 1 "tldflag1" "${SLASH}google.cc:"  gflags_unittest  --helpshort)
-add_gflags_test(helpshort-tldflag2 1 "tldflag2" "${SLASH}google.cc:"  gflags_unittest  --helpshort)
-
-# --helpshort should work if the main source file is suffixed with [_-]main
-add_gflags_test(helpshort-main 1 "${SLASH}gflags_unittest-main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest-main --helpshort)
-add_gflags_test(helpshort_main 1 "${SLASH}gflags_unittest_main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest_main --helpshort)
-
-# --helpon needs an argument
-add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" ""  gflags_unittest  --helpon)
-# --helpon argument indicates what file we'll show args from
-add_gflags_test(helpon=gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --helpon=gflags)
-# another way of specifying the argument
-add_gflags_test(helpon_gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --helpon gflags)
-# test another argument
-add_gflags_test(helpon=gflags_unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:"  gflags_unittest  --helpon=gflags_unittest)
-
-# helpmatch is like helpon but takes substrings
-add_gflags_test(helpmatch_reporting 1 "${SLASH}gflags_reporting.cc:" "${SLASH}gflags_unittest.cc:"  gflags_unittest  -helpmatch reporting)
-add_gflags_test(helpmatch=unittest  1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:"  gflags_unittest  -helpmatch=unittest)
-
-# if no flags are found with helpmatch or helpon, suggest --help
-add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "${SLASH}gflags_unittest.cc:"  gflags_unittest  -helpmatch=nosuchsubstring)
-add_gflags_test(helpon=nosuchmodule       1 "No modules matched" "${SLASH}gflags_unittest.cc:"  gflags_unittest  -helpon=nosuchmodule)
-
-# helppackage shows all the flags in the same dir as this unittest
-# --help should show all flags, including flags from google.cc
-add_gflags_test(helppackage 1 "${SLASH}gflags_reporting.cc:" ""  gflags_unittest  --helppackage)
-
-# xml!
-add_gflags_test(helpxml 1 "${SLASH}gflags_unittest.cc</file>" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --helpxml)
-
-# just print the version info and exit
-add_gflags_test(version-1 0 "gflags_unittest"      "${SLASH}gflags_unittest.cc:"  gflags_unittest  --version)
-add_gflags_test(version-2 0 "version test_version" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --version)
-
-# --undefok is a fun flag...
-add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" ""  gflags_unittest  --undefok= --foo --unused_bool)
-add_gflags_test(undefok-2 0 "PASS" ""  gflags_unittest  --undefok=foo --foo --unused_bool)
-# If you say foo is ok to be undefined, we'll accept --nofoo as well
-add_gflags_test(undefok-3 0 "PASS" ""  gflags_unittest  --undefok=foo --nofoo --unused_bool)
-# It's ok if the foo is in the middle
-add_gflags_test(undefok-4 0 "PASS" ""  gflags_unittest  --undefok=fee,fi,foo,fum --foo --unused_bool)
-# But the spelling has to be just right...
-add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" ""  gflags_unittest  --undefok=fo --foo --unused_bool)
-add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" ""  gflags_unittest  --undefok=foot --foo --unused_bool)
-
-# See if we can successfully load our flags from the flagfile
-add_gflags_test(flagfile.1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:"  gflags_unittest  "--flagfile=flagfile.1")
-add_gflags_test(flagfile.2 0 "PASS" ""  gflags_unittest  "--flagfile=flagfile.2")
-add_gflags_test(flagfile.3 0 "PASS" ""  gflags_unittest  "--flagfile=flagfile.3")
-
-# Also try to load flags from the environment
-add_gflags_test(fromenv=version      0 "gflags_unittest" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --fromenv=version)
-add_gflags_test(tryfromenv=version   0 "gflags_unittest" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --tryfromenv=version)
-add_gflags_test(fromenv=help         0 "PASS" ""  gflags_unittest  --fromenv=help)
-add_gflags_test(tryfromenv=help      0 "PASS" ""  gflags_unittest  --tryfromenv=help)
-add_gflags_test(fromenv=helpfull     1 "helpfull not found in environment" ""  gflags_unittest  --fromenv=helpfull)
-add_gflags_test(tryfromenv=helpfull  0 "PASS" ""  gflags_unittest  --tryfromenv=helpfull)
-add_gflags_test(tryfromenv=undefok   0 "PASS" ""  gflags_unittest  --tryfromenv=undefok --foo)
-add_gflags_test(tryfromenv=weirdo    1 "unknown command line flag" ""  gflags_unittest  --tryfromenv=weirdo)
-add_gflags_test(tryfromenv-multiple  0 "gflags_unittest" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --tryfromenv=test_bool,version,unused_bool)
-add_gflags_test(fromenv=test_bool    1 "not found in environment" ""  gflags_unittest  --fromenv=test_bool)
-add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" ""  gflags_unittest  --fromenv=test_bool,ok)
-# Here, the --version overrides the fromenv
-add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:"  gflags_unittest  --fromenv=test_bool,version,ok)
-
-# Make sure -- by itself stops argv processing
-add_gflags_test(dashdash 0 "PASS" ""  gflags_unittest  -- --help)
-
-# And we should die if the flag value doesn't pass the validator
-add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" ""  gflags_unittest  --always_fail)
-
-# And if locking in validators fails
-# TODO(andreas): Worked on Windows 7 Release configuration, but causes
-#                debugger abort() intervention in case of Debug configuration.
-#add_gflags_test(deadlock_if_cant_lock 0 "PASS" ""  gflags_unittest  --deadlock_if_cant_lock)
-
-# ----------------------------------------------------------------------------
-# use gflags_declare.h
-add_executable (gflags_declare_test gflags_declare_test.cc gflags_declare_flags.cc)
-
-add_test(NAME gflags_declare COMMAND gflags_declare_test --message "Hello gflags!")
-set_tests_properties(gflags_declare PROPERTIES PASS_REGULAR_EXPRESSION "Hello gflags!")
-
-# ----------------------------------------------------------------------------
-# configure Python script which configures and builds a test project
-if (BUILD_NC_TESTS OR BUILD_CONFIG_TESTS)
-  find_package (PythonInterp)
-  if (NOT PYTHON_EXECUTABLE)
-    message (FATAL_ERROR "No Python installation found! It is required by the (negative) compilation tests."
-                         " Either install Python or set BUILD_NC_TESTS and BUILD_CONFIG_TESTS to FALSE.")
-  endif ()
-  set (TMPDIR "${PROJECT_BINARY_DIR}/Testing/Temporary")
-  configure_file (gflags_build.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/build.py" @ONLY)
-  function (add_gflags_build_test name srcdir expect_fail)
-    set (srcdir "${CMAKE_CURRENT_SOURCE_DIR}/${srcdir}")
-    add_test (
-      NAME    "${name}"
-      COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/build.py" 
-                    ${name} ${srcdir} ${expect_fail}
-    )
-  endfunction ()
-endif ()
-
-# ----------------------------------------------------------------------------
-# negative compilation tests
-option (BUILD_NC_TESTS "Request addition of negative compilation tests." OFF)
-mark_as_advanced (BUILD_NC_TESTS)
-if (BUILD_NC_TESTS)
-  add_gflags_build_test (nc_sanity               nc 0)
-  add_gflags_build_test (nc_swapped_args         nc 1)
-  add_gflags_build_test (nc_int_instead_of_bool  nc 1)
-  add_gflags_build_test (nc_bool_in_quotes       nc 1)
-  add_gflags_build_test (nc_define_string_with_0 nc 1)
-endif ()
-
-# ----------------------------------------------------------------------------
-# build configuration test
-option (BUILD_CONFIG_TESTS "Request addition of package configuration tests." OFF)
-mark_as_advanced (BUILD_CONFIG_TESTS)
-if (BUILD_CONFIG_TESTS)
-  add_gflags_build_test (cmake_config config 0)
-endif ()
diff --git a/third_party/gflags/test/config/CMakeLists.txt b/third_party/gflags/test/config/CMakeLists.txt
deleted file mode 100644
index 6190b25..0000000
--- a/third_party/gflags/test/config/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-## gflags package configuration tests
-
-cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR)
-
-project (gflags_${TEST_NAME})
-
-find_package (gflags REQUIRED)
-
-add_executable (foo main.cc)
-target_link_libraries (foo gflags::gflags)
diff --git a/third_party/gflags/test/config/main.cc b/third_party/gflags/test/config/main.cc
deleted file mode 100644
index 3c033e3..0000000
--- a/third_party/gflags/test/config/main.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <iostream>
-#include <gflags/gflags.h>
-
-DEFINE_string(message, "Hello World!", "The message to print");
-
-static bool ValidateMessage(const char* flagname, const std::string &message)
-{
-  return !message.empty();
-}
-DEFINE_validator(message, ValidateMessage);
-
-int main(int argc, char **argv)
-{
-  gflags::SetUsageMessage("Test CMake configuration of gflags library (gflags-config.cmake)");
-  gflags::SetVersionString("0.1");
-  gflags::ParseCommandLineFlags(&argc, &argv, true);
-  std::cout << FLAGS_message << std::endl;
-  gflags::ShutDownCommandLineFlags();
-  return 0;
-}
diff --git a/third_party/gflags/test/flagfile.1 b/third_party/gflags/test/flagfile.1
deleted file mode 100644
index e0f9217..0000000
--- a/third_party/gflags/test/flagfile.1
+++ /dev/null
@@ -1 +0,0 @@
---version
\ No newline at end of file
diff --git a/third_party/gflags/test/flagfile.2 b/third_party/gflags/test/flagfile.2
deleted file mode 100644
index 864f8e8..0000000
--- a/third_party/gflags/test/flagfile.2
+++ /dev/null
@@ -1,2 +0,0 @@
---foo=bar
---nounused_bool
\ No newline at end of file
diff --git a/third_party/gflags/test/flagfile.3 b/third_party/gflags/test/flagfile.3
deleted file mode 100644
index 76d92bb..0000000
--- a/third_party/gflags/test/flagfile.3
+++ /dev/null
@@ -1 +0,0 @@
---flagfile=flagfile.2
\ No newline at end of file
diff --git a/third_party/gflags/test/gflags_build.py.in b/third_party/gflags/test/gflags_build.py.in
deleted file mode 100644
index a8cba2b..0000000
--- a/third_party/gflags/test/gflags_build.py.in
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import sys
-import subprocess
-import shutil
-
-CMAKE            = '@CMAKE_COMMAND@'
-CMAKE_BUILD_TYPE = '@CMAKE_BUILD_TYPE@'
-TMPDIR           = '@TMPDIR@'
-SRCDIR           = '@SRCDIR@'
-GFLAGS_DIR       = '@gflags_BINARY_DIR@'
-
-if __name__ == "__main__":
-  if len(sys.argv) != 4:
-    sys.stderr.write(' '.join(['usage:', sys.argv[0], '<test_name> <srcdir> <expect_fail:0|1>\n']))
-    sys.exit(1)
-  test_name   = sys.argv[1]
-  srcdir      = sys.argv[2]
-  expect_fail = (sys.argv[3].lower() in ['true', 'yes', 'on', '1'])
-  bindir      = os.path.join(TMPDIR, test_name)
-  if TMPDIR == '':
-    sys.stderr.write('Temporary directory not set!\n')
-    sys.exit(1)
-  # create build directory
-  if os.path.isdir(bindir): shutil.rmtree(bindir)
-  os.makedirs(bindir)
-  # configure the build tree
-  if subprocess.call([CMAKE, '-DCMAKE_BUILD_TYPE:STRING='+CMAKE_BUILD_TYPE,
-                             '-Dgflags_DIR:PATH='+GFLAGS_DIR,
-                             '-DTEST_NAME:STRING='+test_name, srcdir], cwd=bindir) != 0:
-    sys.stderr.write('Failed to configure the build tree!\n')
-    sys.exit(1)
-  # build the test project
-  exit_code = subprocess.call([CMAKE, '--build', bindir, '--config', CMAKE_BUILD_TYPE], cwd=bindir)
-  if expect_fail == True:
-    if exit_code == 0:
-      sys.stderr.write('Build expected to fail, but it succeeded!\n')
-      sys.exit(1)
-    else:
-      sys.stderr.write('Build failed as expected\n')
-      exit_code = 0
-  sys.exit(exit_code)
diff --git a/third_party/gflags/test/gflags_declare_flags.cc b/third_party/gflags/test/gflags_declare_flags.cc
deleted file mode 100755
index 3d952a8..0000000
--- a/third_party/gflags/test/gflags_declare_flags.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-#define GFLAGS_DLL_DECLARE_FLAG
-
-#include <iostream>
-#include <gflags/gflags_declare.h>
-
-DECLARE_string(message); // in gflags_delcare_test.cc
-
-void print_message();
-void print_message()
-{
-  std::cout << FLAGS_message << std::endl;
-}
diff --git a/third_party/gflags/test/gflags_declare_test.cc b/third_party/gflags/test/gflags_declare_test.cc
deleted file mode 100644
index 47d11c2..0000000
--- a/third_party/gflags/test/gflags_declare_test.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <gflags/gflags.h>
-
-DEFINE_string(message, "", "The message to print");
-void print_message(); // in gflags_declare_flags.cc
-
-int main(int argc, char **argv)
-{
-  GFLAGS_NAMESPACE::SetUsageMessage("Test compilation and use of gflags_declare.h");
-  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-  print_message();
-  return 0;
-}
diff --git a/third_party/gflags/test/gflags_strip_flags_test.cc b/third_party/gflags/test/gflags_strip_flags_test.cc
deleted file mode 100755
index 143f0c6..0000000
--- a/third_party/gflags/test/gflags_strip_flags_test.cc
+++ /dev/null
@@ -1,60 +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: csilvers@google.com (Craig Silverstein)
-//
-// A simple program that uses STRIP_FLAG_HELP.  We'll have a shell
-// script that runs 'strings' over this program and makes sure
-// that the help string is not in there.
-
-#define STRIP_FLAG_HELP 1
-#include <gflags/gflags.h>
-
-#include <stdio.h>
-
-using GFLAGS_NAMESPACE::SetUsageMessage;
-using GFLAGS_NAMESPACE::ParseCommandLineFlags;
-
-
-DEFINE_bool(test, true, "This text should be stripped out");
-
-int main(int argc, char** argv) {
-  SetUsageMessage("Usage message");
-  ParseCommandLineFlags(&argc, &argv, false);
-
-  // 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
-  // 'strings' on it, so we construct this binary to print the real
-  // name (argv[0]) on stdout when run.
-  puts(argv[0]);
-
-  return 0;
-}
diff --git a/third_party/gflags/test/gflags_strip_flags_test.cmake b/third_party/gflags/test/gflags_strip_flags_test.cmake
deleted file mode 100644
index 5bb5cc1..0000000
--- a/third_party/gflags/test/gflags_strip_flags_test.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-if (NOT BINARY)
-  message (FATAL_ERROR "BINARY file to check not specified!")
-endif ()
-file (STRINGS "${BINARY}" strings REGEX "This text should be stripped out")
-if (strings)
-  message (FATAL_ERROR "Text not stripped from binary like it should be: ${BINARY}")
-endif ()
diff --git a/third_party/gflags/test/gflags_unittest.cc b/third_party/gflags/test/gflags_unittest.cc
deleted file mode 100755
index 9a922ef..0000000
--- a/third_party/gflags/test/gflags_unittest.cc
+++ /dev/null
@@ -1,1572 +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.
-
-// ---
-//
-// For now, this unit test does not cover all features of
-// gflags.cc
-
-#include <gflags/gflags.h>
-
-#include "config.h"
-#include "util.h"
-
-#include <math.h>       // for isinf() and isnan()
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>   // for unlink()
-#endif
-#include <vector>
-#include <string>
-TEST_INIT
-EXPECT_DEATH_INIT
-
-// I don't actually use this header file, but #include it under the
-// old location to make sure that the include-header-forwarding
-// works.  But don't bother on windows; the windows port is so new
-// it never had the old location-names.
-#ifndef _MSC_VER
-#include <gflags/gflags_completions.h>
-void (*unused_fn)() = &GFLAGS_NAMESPACE::HandleCommandLineCompletions;
-#endif
-
-using std::string;
-using std::vector;
-using GFLAGS_NAMESPACE::int32;
-using GFLAGS_NAMESPACE::FlagRegisterer;
-using GFLAGS_NAMESPACE::StringFromEnv;
-using GFLAGS_NAMESPACE::RegisterFlagValidator;
-using GFLAGS_NAMESPACE::CommandLineFlagInfo;
-using GFLAGS_NAMESPACE::GetAllFlags;
-
-DEFINE_string(test_tmpdir, "", "Dir we use for temp files");
-DEFINE_string(srcdir, StringFromEnv("SRCDIR", "."), "Source-dir root, needed to find gflags_unittest_flagfile");
-
-DECLARE_string(tryfromenv);   // in gflags.cc
-
-DEFINE_bool(test_bool, false, "tests bool-ness");
-DEFINE_int32(test_int32, -1, "");
-DEFINE_int64(test_int64, -2, "");
-DEFINE_uint32(test_uint32, 1, "");
-DEFINE_uint64(test_uint64, 2, "");
-DEFINE_double(test_double, -1.0, "");
-DEFINE_string(test_string, "initial", "");
-
-//
-// The below ugliness gets some additional code coverage in the -helpxml
-// and -helpmatch test cases having to do with string lengths and formatting
-//
-DEFINE_bool(test_bool_with_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_long_name,
-            false,
-            "extremely_extremely_extremely_extremely_extremely_extremely_extremely_extremely_long_meaning");
-
-DEFINE_string(test_str1, "initial", "");
-DEFINE_string(test_str2, "initial", "");
-DEFINE_string(test_str3, "initial", "");
-
-// This is used to test setting tryfromenv manually
-DEFINE_string(test_tryfromenv, "initial", "");
-
-// Don't try this at home!
-static int changeable_var = 12;
-DEFINE_int32(changeable_var, ++changeable_var, "");
-
-static int changeable_bool_var = 8008;
-DEFINE_bool(changeable_bool_var, ++changeable_bool_var == 8009, "");
-
-static int changeable_string_var = 0;
-static string ChangeableString() {
-  char r[] = {static_cast<char>('0' + ++changeable_string_var), '\0'};
-  return r;
-}
-DEFINE_string(changeable_string_var, ChangeableString(), "");
-
-// These are never used in this unittest, but can be used by
-// gflags_unittest.sh when it needs to specify flags
-// that are legal for gflags_unittest but don't need to
-// be a particular value.
-DEFINE_bool(unused_bool, true, "unused bool-ness");
-DEFINE_int32(unused_int32, -1001, "");
-DEFINE_int64(unused_int64, -2001, "");
-DEFINE_uint32(unused_uint32, 1000, "");
-DEFINE_uint64(unused_uint64, 2000, "");
-DEFINE_double(unused_double, -1000.0, "");
-DEFINE_string(unused_string, "unused", "");
-
-// These flags are used by gflags_unittest.sh
-DEFINE_bool(changed_bool1, false, "changed");
-DEFINE_bool(changed_bool2, false, "changed");
-DEFINE_bool(long_helpstring, false,
-            "This helpstring goes on forever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever and ever and ever and ever and ever and ever and ever and "
-            "ever.  This is the end of a long helpstring");
-
-
-static bool AlwaysFail(const char* flag, bool value) { return value == false; }
-DEFINE_bool(always_fail, false, "will fail to validate when you set it");
-DEFINE_validator(always_fail, AlwaysFail);
-
-// See the comment by GetAllFlags in gflags.h
-static bool DeadlockIfCantLockInValidators(const char* flag, bool value) {
-  if (!value) {
-    return true;
-  }
-  vector<CommandLineFlagInfo> dummy;
-  GetAllFlags(&dummy);
-  return true;
-}
-DEFINE_bool(deadlock_if_cant_lock,
-            false,
-            "will deadlock if set to true and "
-            "if locking of registry in validators fails.");
-DEFINE_validator(deadlock_if_cant_lock, DeadlockIfCantLockInValidators);
-
-#define MAKEFLAG(x) DEFINE_int32(test_flag_num##x, x, "Test flag")
-
-// Define 10 flags
-#define MAKEFLAG10(x)                           \
-  MAKEFLAG(x##0);                               \
-  MAKEFLAG(x##1);                               \
-  MAKEFLAG(x##2);                               \
-  MAKEFLAG(x##3);                               \
-  MAKEFLAG(x##4);                               \
-  MAKEFLAG(x##5);                               \
-  MAKEFLAG(x##6);                               \
-  MAKEFLAG(x##7);                               \
-  MAKEFLAG(x##8);                               \
-  MAKEFLAG(x##9)
-
-// Define 100 flags
-#define MAKEFLAG100(x)                          \
-  MAKEFLAG10(x##0);                             \
-  MAKEFLAG10(x##1);                             \
-  MAKEFLAG10(x##2);                             \
-  MAKEFLAG10(x##3);                             \
-  MAKEFLAG10(x##4);                             \
-  MAKEFLAG10(x##5);                             \
-  MAKEFLAG10(x##6);                             \
-  MAKEFLAG10(x##7);                             \
-  MAKEFLAG10(x##8);                             \
-  MAKEFLAG10(x##9)
-
-// Define a bunch of command-line flags.  Each occurrence of the MAKEFLAG100
-// macro defines 100 integer flags.  This lets us test the effect of having
-// many flags on startup time.
-MAKEFLAG100(1);
-MAKEFLAG100(2);
-MAKEFLAG100(3);
-MAKEFLAG100(4);
-MAKEFLAG100(5);
-MAKEFLAG100(6);
-MAKEFLAG100(7);
-MAKEFLAG100(8);
-MAKEFLAG100(9);
-MAKEFLAG100(10);
-MAKEFLAG100(11);
-MAKEFLAG100(12);
-MAKEFLAG100(13);
-MAKEFLAG100(14);
-MAKEFLAG100(15);
-
-#undef MAKEFLAG100
-#undef MAKEFLAG10
-#undef MAKEFLAG
-
-// This is a pseudo-flag -- we want to register a flag with a filename
-// at the top level, but there is no way to do this except by faking
-// the filename.
-namespace fLI {
-  static const int32 FLAGS_nonotldflag1 = 12;
-  int32 FLAGS_tldflag1 = FLAGS_nonotldflag1;
-  int32 FLAGS_notldflag1 = FLAGS_nonotldflag1;
-  static FlagRegisterer o_tldflag1(
-    "tldflag1",
-    "should show up in --helpshort", "gflags_unittest.cc",
-    &FLAGS_tldflag1, &FLAGS_notldflag1);
-}
-using fLI::FLAGS_tldflag1;
-
-namespace fLI {
-  static const int32 FLAGS_nonotldflag2 = 23;
-  int32 FLAGS_tldflag2 = FLAGS_nonotldflag2;
-  int32 FLAGS_notldflag2 = FLAGS_nonotldflag2;
-  static FlagRegisterer o_tldflag2(
-    "tldflag2",
-    "should show up in --helpshort", "gflags_unittest.",
-    &FLAGS_tldflag2, &FLAGS_notldflag2);
-}
-using fLI::FLAGS_tldflag2;
-
-namespace GFLAGS_NAMESPACE {
-
-namespace {
-
-
-static string TmpFile(const string& basename) {
-#ifdef _MSC_VER
-  return FLAGS_test_tmpdir + "\\" + basename;
-#else
-  return FLAGS_test_tmpdir + "/" + basename;
-#endif
-}
-
-// Returns the definition of the --flagfile flag to be used in the tests.
-// Must be called after ParseCommandLineFlags().
-static const char* GetFlagFileFlag() {
-#ifdef _MSC_VER
-  static const string flagfile = FLAGS_srcdir + "\\gflags_unittest_flagfile";
-#else
-  static const string flagfile = FLAGS_srcdir + "/gflags_unittest_flagfile";
-#endif
-  static const string flagfile_flag = string("--flagfile=") + flagfile;
-  return flagfile_flag.c_str();
-}
-
-
-// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
-// compiler error iff T1 and T2 are different types.
-template <typename T1, typename T2>
-struct CompileAssertTypesEqual;
-
-template <typename T>
-struct CompileAssertTypesEqual<T, T> {
-};
-
-
-template <typename Expected, typename Actual>
-void AssertIsType(Actual& x) {
-  CompileAssertTypesEqual<Expected, Actual>();
-}
-
-// Verify all the flags are the right type.
-TEST(FlagTypes, FlagTypes) {
-  AssertIsType<bool>(FLAGS_test_bool);
-  AssertIsType<int32>(FLAGS_test_int32);
-  AssertIsType<int64>(FLAGS_test_int64);
-  AssertIsType<uint32>(FLAGS_test_uint32);
-  AssertIsType<uint64>(FLAGS_test_uint64);
-  AssertIsType<double>(FLAGS_test_double);
-  AssertIsType<string>(FLAGS_test_string);
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-// Death tests for "help" options.
-//
-// The help system automatically calls gflags_exitfunc(1) when you specify any of
-// the help-related flags ("-helpmatch", "-helpxml") so we can't test
-// those mainline.
-
-// Tests that "-helpmatch" causes the process to die.
-TEST(ReadFlagsFromStringDeathTest, HelpMatch) {
-  EXPECT_DEATH(ReadFlagsFromString("-helpmatch=base", GetArgv0(), true),
-               "");
-}
-
-
-// Tests that "-helpxml" causes the process to die.
-TEST(ReadFlagsFromStringDeathTest, HelpXml) {
-  EXPECT_DEATH(ReadFlagsFromString("-helpxml", GetArgv0(), true),
-               "");
-}
-#endif
-
-
-// A subroutine needed for testing reading flags from a string.
-void TestFlagString(const string& flags,
-                    const string& expected_string,
-                    bool expected_bool,
-                    int32 expected_int32,
-                    double expected_double) {
-  EXPECT_TRUE(ReadFlagsFromString(flags,
-                                  GetArgv0(),
-                                  // errors are fatal
-                                  true));
-
-  EXPECT_EQ(expected_string, FLAGS_test_string);
-  EXPECT_EQ(expected_bool, FLAGS_test_bool);
-  EXPECT_EQ(expected_int32, FLAGS_test_int32);
-  EXPECT_DOUBLE_EQ(expected_double, FLAGS_test_double);
-}
-
-
-// Tests reading flags from a string.
-TEST(FlagFileTest, ReadFlagsFromString) {
-  TestFlagString(
-      // Flag string
-      "-test_string=continued\n"
-      "# some comments are in order\n"
-      "# some\n"
-      "  # comments\n"
-      "#are\n"
-      "                  #trickier\n"
-      "# than others\n"
-      "-test_bool=true\n"
-      "     -test_int32=1\n"
-      "-test_double=0.0\n",
-      // Expected values
-      "continued",
-      true,
-      1,
-      0.0);
-
-  TestFlagString(
-      // Flag string
-      "# let's make sure it can update values\n"
-      "-test_string=initial\n"
-      "-test_bool=false\n"
-      "-test_int32=123\n"
-      "-test_double=123.0\n",
-      // Expected values
-      "initial",
-      false,
-      123,
-      123.0);
-
-  // Test that flags can use dashes instead of underscores.
-  TestFlagString(
-      // Flag string
-      "-test-string=initial\n"
-      "--test-bool=false\n"
-      "--test-int32=123\n"
-      "--test-double=123.0\n",
-      // Expected values
-      "initial",
-      false,
-      123,
-      123.0);
-}
-
-// Tests the filename part of the flagfile
-TEST(FlagFileTest, FilenamesOurfileLast) {
-  FLAGS_test_string = "initial";
-  FLAGS_test_bool = false;
-  FLAGS_test_int32 = -1;
-  FLAGS_test_double = -1.0;
-  TestFlagString(
-      // Flag string
-      "-test_string=continued\n"
-      "# some comments are in order\n"
-      "# some\n"
-      "  # comments\n"
-      "#are\n"
-      "                  #trickier\n"
-      "# than others\n"
-      "not_our_filename\n"
-      "-test_bool=true\n"
-      "     -test_int32=1\n"
-      "gflags_unittest\n"
-      "-test_double=1000.0\n",
-      // Expected values
-      "continued",
-      false,
-      -1,
-      1000.0);
-}
-
-TEST(FlagFileTest, FilenamesOurfileFirst) {
-  FLAGS_test_string = "initial";
-  FLAGS_test_bool = false;
-  FLAGS_test_int32 = -1;
-  FLAGS_test_double = -1.0;
-  TestFlagString(
-      // Flag string
-      "-test_string=continued\n"
-      "# some comments are in order\n"
-      "# some\n"
-      "  # comments\n"
-      "#are\n"
-      "                  #trickier\n"
-      "# than others\n"
-      "gflags_unittest\n"
-      "-test_bool=true\n"
-      "     -test_int32=1\n"
-      "not_our_filename\n"
-      "-test_double=1000.0\n",
-      // Expected values
-      "continued",
-      true,
-      1,
-      -1.0);
-}
-
-#if defined(HAVE_FNMATCH_H) || defined(HAVE_SHLWAPI_H)  // otherwise glob isn't supported
-TEST(FlagFileTest, FilenamesOurfileGlob) {
-  FLAGS_test_string = "initial";
-  FLAGS_test_bool = false;
-  FLAGS_test_int32 = -1;
-  FLAGS_test_double = -1.0;
-  TestFlagString(
-      // Flag string
-      "-test_string=continued\n"
-      "# some comments are in order\n"
-      "# some\n"
-      "  # comments\n"
-      "#are\n"
-      "                  #trickier\n"
-      "# than others\n"
-      "*flags*\n"
-      "-test_bool=true\n"
-      "     -test_int32=1\n"
-      "flags\n"
-      "-test_double=1000.0\n",
-      // Expected values
-      "continued",
-      true,
-      1,
-      -1.0);
-}
-
-TEST(FlagFileTest, FilenamesOurfileInBigList) {
-  FLAGS_test_string = "initial";
-  FLAGS_test_bool = false;
-  FLAGS_test_int32 = -1;
-  FLAGS_test_double = -1.0;
-  TestFlagString(
-      // Flag string
-      "-test_string=continued\n"
-      "# some comments are in order\n"
-      "# some\n"
-      "  # comments\n"
-      "#are\n"
-      "                  #trickier\n"
-      "# than others\n"
-      "*first* *flags* *third*\n"
-      "-test_bool=true\n"
-      "     -test_int32=1\n"
-      "flags\n"
-      "-test_double=1000.0\n",
-      // Expected values
-      "continued",
-      true,
-      1,
-      -1.0);
-}
-#endif  // defined(HAVE_FNMATCH_H) || defined(HAVE_SHLWAPI_H)
-
-// Tests that a failed flag-from-string read keeps flags at default values
-TEST(FlagFileTest, FailReadFlagsFromString) {
-  FLAGS_test_int32 = 119;
-  string flags("# let's make sure it can update values\n"
-               "-test_string=non_initial\n"
-               "-test_bool=false\n"
-               "-test_int32=123\n"
-               "-test_double=illegal\n");
-
-  EXPECT_FALSE(ReadFlagsFromString(flags,
-                                   GetArgv0(),
-                                   // errors are fatal
-                                   false));
-
-  EXPECT_EQ(119, FLAGS_test_int32);
-  EXPECT_EQ("initial", FLAGS_test_string);
-}
-
-// Tests that flags can be set to ordinary values.
-TEST(SetFlagValueTest, OrdinaryValues) {
-  EXPECT_EQ("initial", FLAGS_test_str1);
-
-  SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("second", FLAGS_test_str1);  // set; was default
-
-  SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("second", FLAGS_test_str1);  // already set once
-
-  FLAGS_test_str1 = "initial";
-  SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("initial", FLAGS_test_str1);  // still already set before
-
-  SetCommandLineOptionWithMode("test_str1", "third", SET_FLAGS_VALUE);
-  EXPECT_EQ("third", FLAGS_test_str1);  // changed value
-
-  SetCommandLineOptionWithMode("test_str1", "fourth", SET_FLAGS_DEFAULT);
-  EXPECT_EQ("third", FLAGS_test_str1);
-  // value not changed (already set before)
-
-  EXPECT_EQ("initial", FLAGS_test_str2);
-
-  SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_DEFAULT);
-  EXPECT_EQ("second", FLAGS_test_str2);  // changed (was default)
-
-  FLAGS_test_str2 = "extra";
-  EXPECT_EQ("extra", FLAGS_test_str2);
-
-  FLAGS_test_str2 = "second";
-  SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
-  EXPECT_EQ("third", FLAGS_test_str2);  // still changed (was equal to default)
-
-  SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("fourth", FLAGS_test_str2);  // changed (was default)
-
-  EXPECT_EQ("initial", FLAGS_test_str3);
-
-  SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
-  EXPECT_EQ("second", FLAGS_test_str3);  // changed
-
-  FLAGS_test_str3 = "third";
-  SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_DEFAULT);
-  EXPECT_EQ("third", FLAGS_test_str3);  // not changed (was set)
-
-  SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("third", FLAGS_test_str3);  // not changed (was set)
-
-  SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_VALUE);
-  EXPECT_EQ("fourth", FLAGS_test_str3);  // changed value
-}
-
-
-// Tests that flags can be set to exceptional values.
-// Note: apparently MINGW doesn't parse inf and nan correctly:
-//    http://www.mail-archive.com/bug-gnulib@gnu.org/msg09573.html
-// This url says FreeBSD also has a problem, but I didn't see that.
-TEST(SetFlagValueTest, ExceptionalValues) {
-#if defined(isinf) && !defined(__MINGW32__)
-  EXPECT_EQ("test_double set to inf\n",
-            SetCommandLineOption("test_double", "inf"));
-  EXPECT_INF(FLAGS_test_double);
-
-  EXPECT_EQ("test_double set to inf\n",
-            SetCommandLineOption("test_double", "INF"));
-  EXPECT_INF(FLAGS_test_double);
-#endif
-
-  // set some bad values
-  EXPECT_EQ("",
-            SetCommandLineOption("test_double", "0.1xxx"));
-  EXPECT_EQ("",
-            SetCommandLineOption("test_double", " "));
-  EXPECT_EQ("",
-            SetCommandLineOption("test_double", ""));
-#if defined(isinf) && !defined(__MINGW32__)
-  EXPECT_EQ("test_double set to -inf\n",
-            SetCommandLineOption("test_double", "-inf"));
-  EXPECT_INF(FLAGS_test_double);
-  EXPECT_GT(0, FLAGS_test_double);
-#endif
-
-#if defined(isnan) && !defined(__MINGW32__)
-  EXPECT_EQ("test_double set to nan\n",
-            SetCommandLineOption("test_double", "NaN"));
-  EXPECT_NAN(FLAGS_test_double);
-#endif
-}
-
-// Tests that integer flags can be specified in many ways
-TEST(SetFlagValueTest, DifferentRadices) {
-  EXPECT_EQ("test_int32 set to 12\n",
-            SetCommandLineOption("test_int32", "12"));
-
-  EXPECT_EQ("test_int32 set to 16\n",
-            SetCommandLineOption("test_int32", "0x10"));
-
-  EXPECT_EQ("test_int32 set to 34\n",
-            SetCommandLineOption("test_int32", "0X22"));
-
-  // Leading 0 is *not* octal; it's still decimal
-  EXPECT_EQ("test_int32 set to 10\n",
-            SetCommandLineOption("test_int32", "010"));
-}
-
-// Tests what happens when you try to set a flag to an illegal value
-TEST(SetFlagValueTest, IllegalValues) {
-  FLAGS_test_bool = true;
-  FLAGS_test_int32 = 119;
-  FLAGS_test_int64 = 1191;
-  FLAGS_test_uint32 = 11911;
-  FLAGS_test_uint64 = 119111;
-
-  EXPECT_EQ("",
-            SetCommandLineOption("test_bool", "12"));
-
-  EXPECT_EQ("",
-            SetCommandLineOption("test_uint32", "-1970"));
-
-  EXPECT_EQ("",
-            SetCommandLineOption("test_int32", "7000000000000"));
-
-  EXPECT_EQ("",
-            SetCommandLineOption("test_uint64", "-1"));
-
-  EXPECT_EQ("",
-            SetCommandLineOption("test_int64", "not a number!"));
-
-  // Test the empty string with each type of input
-  EXPECT_EQ("", SetCommandLineOption("test_bool", ""));
-  EXPECT_EQ("", SetCommandLineOption("test_int32", ""));
-  EXPECT_EQ("", SetCommandLineOption("test_int64", ""));
-  EXPECT_EQ("", SetCommandLineOption("test_uint32", ""));
-  EXPECT_EQ("", SetCommandLineOption("test_uint64", ""));
-  EXPECT_EQ("", SetCommandLineOption("test_double", ""));
-  EXPECT_EQ("test_string set to \n", SetCommandLineOption("test_string", ""));
-
-  EXPECT_TRUE(FLAGS_test_bool);
-  EXPECT_EQ(119, FLAGS_test_int32);
-  EXPECT_EQ(1191, FLAGS_test_int64);
-  EXPECT_EQ(11911, FLAGS_test_uint32);
-  EXPECT_EQ(119111, FLAGS_test_uint64);
-}
-
-
-// Tests that we only evaluate macro args once
-TEST(MacroArgs, EvaluateOnce) {
-  EXPECT_EQ(13, FLAGS_changeable_var);
-  // Make sure we don't ++ the value somehow, when evaluating the flag.
-  EXPECT_EQ(13, FLAGS_changeable_var);
-  // Make sure the macro only evaluated this var once.
-  EXPECT_EQ(13, changeable_var);
-  // Make sure the actual value and default value are the same
-  SetCommandLineOptionWithMode("changeable_var", "21", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ(21, FLAGS_changeable_var);
-}
-
-TEST(MacroArgs, EvaluateOnceBool) {
-  EXPECT_TRUE(FLAGS_changeable_bool_var);
-  EXPECT_TRUE(FLAGS_changeable_bool_var);
-  EXPECT_EQ(8009, changeable_bool_var);
-  SetCommandLineOptionWithMode("changeable_bool_var", "false",
-                               SET_FLAG_IF_DEFAULT);
-  EXPECT_FALSE(FLAGS_changeable_bool_var);
-}
-
-TEST(MacroArgs, EvaluateOnceStrings) {
-  EXPECT_EQ("1", FLAGS_changeable_string_var);
-  EXPECT_EQ("1", FLAGS_changeable_string_var);
-  EXPECT_EQ(1, changeable_string_var);
-  SetCommandLineOptionWithMode("changeable_string_var", "different",
-                               SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("different", FLAGS_changeable_string_var);
-}
-
-// Tests that the FooFromEnv does the right thing
-TEST(FromEnvTest, LegalValues) {
-  setenv("BOOL_VAL1", "true", 1);
-  setenv("BOOL_VAL2", "false", 1);
-  setenv("BOOL_VAL3", "1", 1);
-  setenv("BOOL_VAL4", "F", 1);
-  EXPECT_TRUE(BoolFromEnv("BOOL_VAL1", false));
-  EXPECT_FALSE(BoolFromEnv("BOOL_VAL2", true));
-  EXPECT_TRUE(BoolFromEnv("BOOL_VAL3", false));
-  EXPECT_FALSE(BoolFromEnv("BOOL_VAL4", true));
-  EXPECT_TRUE(BoolFromEnv("BOOL_VAL_UNKNOWN", true));
-  EXPECT_FALSE(BoolFromEnv("BOOL_VAL_UNKNOWN", false));
-
-  setenv("INT_VAL1", "1", 1);
-  setenv("INT_VAL2", "-1", 1);
-  EXPECT_EQ(1, Int32FromEnv("INT_VAL1", 10));
-  EXPECT_EQ(-1, Int32FromEnv("INT_VAL2", 10));
-  EXPECT_EQ(10, Int32FromEnv("INT_VAL_UNKNOWN", 10));
-
-  setenv("INT_VAL3", "4294967295", 1);
-  EXPECT_EQ(1, Uint32FromEnv("INT_VAL1", 10));
-  EXPECT_EQ(4294967295L, Uint32FromEnv("INT_VAL3", 30));
-  EXPECT_EQ(10, Uint32FromEnv("INT_VAL_UNKNOWN", 10));
-
-  setenv("INT_VAL4", "1099511627776", 1);
-  EXPECT_EQ(1, Int64FromEnv("INT_VAL1", 20));
-  EXPECT_EQ(-1, Int64FromEnv("INT_VAL2", 20));
-  EXPECT_EQ(1099511627776LL, Int64FromEnv("INT_VAL4", 20));
-  EXPECT_EQ(20, Int64FromEnv("INT_VAL_UNKNOWN", 20));
-
-  EXPECT_EQ(1, Uint64FromEnv("INT_VAL1", 30));
-  EXPECT_EQ(1099511627776ULL, Uint64FromEnv("INT_VAL4", 30));
-  EXPECT_EQ(30, Uint64FromEnv("INT_VAL_UNKNOWN", 30));
-
-  // I pick values here that can be easily represented exactly in floating-point
-  setenv("DOUBLE_VAL1", "0.0", 1);
-  setenv("DOUBLE_VAL2", "1.0", 1);
-  setenv("DOUBLE_VAL3", "-1.0", 1);
-  EXPECT_EQ(0.0, DoubleFromEnv("DOUBLE_VAL1", 40.0));
-  EXPECT_EQ(1.0, DoubleFromEnv("DOUBLE_VAL2", 40.0));
-  EXPECT_EQ(-1.0, DoubleFromEnv("DOUBLE_VAL3", 40.0));
-  EXPECT_EQ(40.0, DoubleFromEnv("DOUBLE_VAL_UNKNOWN", 40.0));
-
-  setenv("STRING_VAL1", "", 1);
-  setenv("STRING_VAL2", "my happy string!", 1);
-  EXPECT_STREQ("", StringFromEnv("STRING_VAL1", "unknown"));
-  EXPECT_STREQ("my happy string!", StringFromEnv("STRING_VAL2", "unknown"));
-  EXPECT_STREQ("unknown", StringFromEnv("STRING_VAL_UNKNOWN", "unknown"));
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-// Tests that the FooFromEnv dies on parse-error
-TEST(FromEnvDeathTest, IllegalValues) {
-  setenv("BOOL_BAD1", "so true!", 1);
-  setenv("BOOL_BAD2", "", 1);
-  EXPECT_DEATH(BoolFromEnv("BOOL_BAD1", false), "error parsing env variable");
-  EXPECT_DEATH(BoolFromEnv("BOOL_BAD2", true), "error parsing env variable");
-
-  setenv("INT_BAD1", "one", 1);
-  setenv("INT_BAD2", "100000000000000000", 1);
-  setenv("INT_BAD3", "0xx10", 1);
-  setenv("INT_BAD4", "", 1);
-  EXPECT_DEATH(Int32FromEnv("INT_BAD1", 10), "error parsing env variable");
-  EXPECT_DEATH(Int32FromEnv("INT_BAD2", 10), "error parsing env variable");
-  EXPECT_DEATH(Int32FromEnv("INT_BAD3", 10), "error parsing env variable");
-  EXPECT_DEATH(Int32FromEnv("INT_BAD4", 10), "error parsing env variable");
-
-  EXPECT_DEATH(Uint32FromEnv("INT_BAD1", 10), "error parsing env variable");
-  EXPECT_DEATH(Uint32FromEnv("INT_BAD2", 10), "error parsing env variable");
-  EXPECT_DEATH(Uint32FromEnv("INT_BAD3", 10), "error parsing env variable");
-  EXPECT_DEATH(Uint32FromEnv("INT_BAD4", 10), "error parsing env variable");
-
-  setenv("BIGINT_BAD1", "18446744073709551616000", 1);
-  EXPECT_DEATH(Int64FromEnv("INT_BAD1", 20), "error parsing env variable");
-  EXPECT_DEATH(Int64FromEnv("INT_BAD3", 20), "error parsing env variable");
-  EXPECT_DEATH(Int64FromEnv("INT_BAD4", 20), "error parsing env variable");
-  EXPECT_DEATH(Int64FromEnv("BIGINT_BAD1", 200), "error parsing env variable");
-
-  setenv("BIGINT_BAD2", "-1", 1);
-  EXPECT_DEATH(Uint64FromEnv("INT_BAD1", 30), "error parsing env variable");
-  EXPECT_DEATH(Uint64FromEnv("INT_BAD3", 30), "error parsing env variable");
-  EXPECT_DEATH(Uint64FromEnv("INT_BAD4", 30), "error parsing env variable");
-  EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD1", 30), "error parsing env variable");
-  // TODO(csilvers): uncomment this when we disallow negative numbers for uint64
-#if 0
-  EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD2", 30), "error parsing env variable");
-#endif
-
-  setenv("DOUBLE_BAD1", "0.0.0", 1);
-  setenv("DOUBLE_BAD2", "", 1);
-  EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD1", 40.0), "error parsing env variable");
-  EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD2", 40.0), "error parsing env variable");
-}
-#endif
-
-
-// Tests that FlagSaver can save the states of string flags.
-TEST(FlagSaverTest, CanSaveStringFlagStates) {
-  // 1. Initializes the flags.
-
-  // State of flag test_str1:
-  //   default value - "initial"
-  //   current value - "initial"
-  //   not set       - true
-
-  SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_VALUE);
-  // State of flag test_str2:
-  //   default value - "initial"
-  //   current value - "second"
-  //   not set       - false
-
-  SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
-  // State of flag test_str3:
-  //   default value - "second"
-  //   current value - "second"
-  //   not set       - true
-
-  // 2. Saves the flag states.
-
-  {
-    FlagSaver fs;
-
-    // 3. Modifies the flag states.
-
-    SetCommandLineOptionWithMode("test_str1", "second", SET_FLAGS_VALUE);
-    EXPECT_EQ("second", FLAGS_test_str1);
-    // State of flag test_str1:
-    //   default value - "second"
-    //   current value - "second"
-    //   not set       - true
-
-    SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
-    EXPECT_EQ("second", FLAGS_test_str2);
-    // State of flag test_str2:
-    //   default value - "third"
-    //   current value - "second"
-    //   not set       - false
-
-    SetCommandLineOptionWithMode("test_str3", "third", SET_FLAGS_VALUE);
-    EXPECT_EQ("third", FLAGS_test_str3);
-    // State of flag test_str1:
-    //   default value - "second"
-    //   current value - "third"
-    //   not set       - false
-
-    // 4. Restores the flag states.
-  }
-
-  // 5. Verifies that the states were restored.
-
-  // Verifies that the value of test_str1 was restored.
-  EXPECT_EQ("initial", FLAGS_test_str1);
-  // Verifies that the "not set" attribute of test_str1 was restored to true.
-  SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("second", FLAGS_test_str1);
-
-  // Verifies that the value of test_str2 was restored.
-  EXPECT_EQ("second", FLAGS_test_str2);
-  // Verifies that the "not set" attribute of test_str2 was restored to false.
-  SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("second", FLAGS_test_str2);
-
-  // Verifies that the value of test_str3 was restored.
-  EXPECT_EQ("second", FLAGS_test_str3);
-  // Verifies that the "not set" attribute of test_str3 was restored to true.
-  SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
-  EXPECT_EQ("fourth", FLAGS_test_str3);
-}
-
-
-// Tests that FlagSaver can save the values of various-typed flags.
-TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
-  // Initializes the flags.
-  FLAGS_test_bool = false;
-  FLAGS_test_int32 = -1;
-  FLAGS_test_uint32 = 2;
-  FLAGS_test_int64 = -3;
-  FLAGS_test_uint64 = 4;
-  FLAGS_test_double = 5.0;
-  FLAGS_test_string = "good";
-
-  // Saves the flag states.
-  {
-    FlagSaver fs;
-
-    // Modifies the flags.
-    FLAGS_test_bool = true;
-    FLAGS_test_int32 = -5;
-    FLAGS_test_uint32 = 6;
-    FLAGS_test_int64 = -7;
-    FLAGS_test_uint64 = 8;
-    FLAGS_test_double = 8.0;
-    FLAGS_test_string = "bad";
-
-    // Restores the flag states.
-  }
-
-  // Verifies the flag values were restored.
-  EXPECT_FALSE(FLAGS_test_bool);
-  EXPECT_EQ(-1, FLAGS_test_int32);
-  EXPECT_EQ(2, FLAGS_test_uint32);
-  EXPECT_EQ(-3, FLAGS_test_int64);
-  EXPECT_EQ(4, FLAGS_test_uint64);
-  EXPECT_DOUBLE_EQ(5.0, FLAGS_test_double);
-  EXPECT_EQ("good", FLAGS_test_string);
-}
-
-TEST(GetAllFlagsTest, BaseTest) {
-  vector<CommandLineFlagInfo> flags;
-  GetAllFlags(&flags);
-  bool found_test_bool = false;
-  vector<CommandLineFlagInfo>::const_iterator i;
-  for (i = flags.begin(); i != flags.end(); ++i) {
-    if (i->name == "test_bool") {
-      found_test_bool = true;
-      EXPECT_EQ(i->type, "bool");
-      EXPECT_EQ(i->default_value, "false");
-      EXPECT_EQ(i->flag_ptr, &FLAGS_test_bool);
-      break;
-    }
-  }
-  EXPECT_TRUE(found_test_bool);
-}
-
-TEST(ShowUsageWithFlagsTest, BaseTest) {
-  // TODO(csilvers): test this by allowing output other than to stdout.
-  // Not urgent since this functionality is tested via
-  // gflags_unittest.sh, though only through use of --help.
-}
-
-TEST(ShowUsageWithFlagsRestrictTest, BaseTest) {
-  // TODO(csilvers): test this by allowing output other than to stdout.
-  // Not urgent since this functionality is tested via
-  // gflags_unittest.sh, though only through use of --helpmatch.
-}
-
-// Note: all these argv-based tests depend on SetArgv being called
-// before ParseCommandLineFlags() in main(), below.
-TEST(GetArgvsTest, BaseTest) {
-  vector<string> argvs = GetArgvs();
-  EXPECT_EQ(4, argvs.size());
-  EXPECT_EQ("/test/argv/for/gflags_unittest", argvs[0]);
-  EXPECT_EQ("argv 2", argvs[1]);
-  EXPECT_EQ("3rd argv", argvs[2]);
-  EXPECT_EQ("argv #4", argvs[3]);
-}
-
-TEST(GetArgvTest, BaseTest) {
-  EXPECT_STREQ("/test/argv/for/gflags_unittest "
-               "argv 2 3rd argv argv #4", GetArgv());
-}
-
-TEST(GetArgv0Test, BaseTest) {
-  EXPECT_STREQ("/test/argv/for/gflags_unittest", GetArgv0());
-}
-
-TEST(GetArgvSumTest, BaseTest) {
-  // This number is just the sum of the ASCII values of all the chars
-  // in GetArgv().
-  EXPECT_EQ(4904, GetArgvSum());
-}
-
-TEST(ProgramInvocationNameTest, BaseTest) {
-  EXPECT_STREQ("/test/argv/for/gflags_unittest",
-               ProgramInvocationName());
-}
-
-TEST(ProgramInvocationShortNameTest, BaseTest) {
-  EXPECT_STREQ("gflags_unittest", ProgramInvocationShortName());
-}
-
-TEST(ProgramUsageTest, BaseTest) {  // Depends on 1st arg to ParseCommandLineFlags()
-  EXPECT_STREQ("/test/argv/for/gflags_unittest: "
-               "<useless flag> [...]\nDoes something useless.\n",
-               ProgramUsage());
-}
-
-TEST(GetCommandLineOptionTest, NameExistsAndIsDefault) {
-  string value("will be changed");
-  bool r = GetCommandLineOption("test_bool", &value);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("false", value);
-
-  r = GetCommandLineOption("test_int32", &value);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("-1", value);
-}
-
-TEST(GetCommandLineOptionTest, NameExistsAndWasAssigned) {
-  FLAGS_test_int32 = 400;
-  string value("will be changed");
-  const bool r = GetCommandLineOption("test_int32", &value);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("400", value);
-}
-
-TEST(GetCommandLineOptionTest, NameExistsAndWasSet) {
-  SetCommandLineOption("test_int32", "700");
-  string value("will be changed");
-  const bool r = GetCommandLineOption("test_int32", &value);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("700", value);
-}
-
-TEST(GetCommandLineOptionTest, NameExistsAndWasNotSet) {
-  // This doesn't set the flag's value, but rather its default value.
-  // is_default is still true, but the 'default' value returned has changed!
-  SetCommandLineOptionWithMode("test_int32", "800", SET_FLAGS_DEFAULT);
-  string value("will be changed");
-  const bool r = GetCommandLineOption("test_int32", &value);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("800", value);
-  EXPECT_TRUE(GetCommandLineFlagInfoOrDie("test_int32").is_default);
-}
-
-TEST(GetCommandLineOptionTest, NameExistsAndWasConditionallySet) {
-  SetCommandLineOptionWithMode("test_int32", "900", SET_FLAG_IF_DEFAULT);
-  string value("will be changed");
-  const bool r = GetCommandLineOption("test_int32", &value);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("900", value);
-}
-
-TEST(GetCommandLineOptionTest, NameDoesNotExist) {
-  string value("will not be changed");
-  const bool r = GetCommandLineOption("test_int3210", &value);
-  EXPECT_FALSE(r);
-  EXPECT_EQ("will not be changed", value);
-}
-
-TEST(GetCommandLineFlagInfoTest, FlagExists) {
-  CommandLineFlagInfo info;
-  bool r = GetCommandLineFlagInfo("test_int32", &info);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("test_int32", info.name);
-  EXPECT_EQ("int32", info.type);
-  EXPECT_EQ("", info.description);
-  EXPECT_EQ("-1", info.current_value);
-  EXPECT_EQ("-1", info.default_value);
-  EXPECT_TRUE(info.is_default);
-  EXPECT_FALSE(info.has_validator_fn);
-  EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
-
-  FLAGS_test_bool = true;
-  r = GetCommandLineFlagInfo("test_bool", &info);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("test_bool", info.name);
-  EXPECT_EQ("bool", info.type);
-  EXPECT_EQ("tests bool-ness", info.description);
-  EXPECT_EQ("true", info.current_value);
-  EXPECT_EQ("false", info.default_value);
-  EXPECT_FALSE(info.is_default);
-  EXPECT_FALSE(info.has_validator_fn);
-  EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
-
-  FLAGS_test_bool = false;
-  r = GetCommandLineFlagInfo("test_bool", &info);
-  EXPECT_TRUE(r);
-  EXPECT_EQ("test_bool", info.name);
-  EXPECT_EQ("bool", info.type);
-  EXPECT_EQ("tests bool-ness", info.description);
-  EXPECT_EQ("false", info.current_value);
-  EXPECT_EQ("false", info.default_value);
-  EXPECT_FALSE(info.is_default);  // value is same, but flag *was* modified
-  EXPECT_FALSE(info.has_validator_fn);
-  EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
-}
-
-TEST(GetCommandLineFlagInfoTest, FlagDoesNotExist) {
-  CommandLineFlagInfo info;
-  // Set to some random values that GetCommandLineFlagInfo should not change
-  info.name = "name";
-  info.type = "type";
-  info.current_value = "curr";
-  info.default_value = "def";
-  info.filename = "/";
-  info.is_default = false;
-  info.has_validator_fn = true;
-  info.flag_ptr = NULL;
-  bool r = GetCommandLineFlagInfo("test_int3210", &info);
-  EXPECT_FALSE(r);
-  EXPECT_EQ("name", info.name);
-  EXPECT_EQ("type", info.type);
-  EXPECT_EQ("", info.description);
-  EXPECT_EQ("curr", info.current_value);
-  EXPECT_EQ("def", info.default_value);
-  EXPECT_EQ("/", info.filename);
-  EXPECT_FALSE(info.is_default);
-  EXPECT_TRUE(info.has_validator_fn);
-  EXPECT_EQ(NULL, info.flag_ptr);
-}
-
-TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndIsDefault) {
-  CommandLineFlagInfo info;
-  info = GetCommandLineFlagInfoOrDie("test_int32");
-  EXPECT_EQ("test_int32", info.name);
-  EXPECT_EQ("int32", info.type);
-  EXPECT_EQ("", info.description);
-  EXPECT_EQ("-1", info.current_value);
-  EXPECT_EQ("-1", info.default_value);
-  EXPECT_TRUE(info.is_default);
-  EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
-  info = GetCommandLineFlagInfoOrDie("test_bool");
-  EXPECT_EQ("test_bool", info.name);
-  EXPECT_EQ("bool", info.type);
-  EXPECT_EQ("tests bool-ness", info.description);
-  EXPECT_EQ("false", info.current_value);
-  EXPECT_EQ("false", info.default_value);
-  EXPECT_TRUE(info.is_default);
-  EXPECT_FALSE(info.has_validator_fn);
-  EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
-}
-
-TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndWasAssigned) {
-  FLAGS_test_int32 = 400;
-  CommandLineFlagInfo info;
-  info = GetCommandLineFlagInfoOrDie("test_int32");
-  EXPECT_EQ("test_int32", info.name);
-  EXPECT_EQ("int32", info.type);
-  EXPECT_EQ("", info.description);
-  EXPECT_EQ("400", info.current_value);
-  EXPECT_EQ("-1", info.default_value);
-  EXPECT_FALSE(info.is_default);
-  EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
-  FLAGS_test_bool = true;
-  info = GetCommandLineFlagInfoOrDie("test_bool");
-  EXPECT_EQ("test_bool", info.name);
-  EXPECT_EQ("bool", info.type);
-  EXPECT_EQ("tests bool-ness", info.description);
-  EXPECT_EQ("true", info.current_value);
-  EXPECT_EQ("false", info.default_value);
-  EXPECT_FALSE(info.is_default);
-  EXPECT_FALSE(info.has_validator_fn);
-  EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-TEST(GetCommandLineFlagInfoOrDieDeathTest, FlagDoesNotExist) {
-  EXPECT_DEATH(GetCommandLineFlagInfoOrDie("test_int3210"),
-               ".*: flag test_int3210 does not exist");
-}
-#endif
-
-
-// These are lightly tested because they're deprecated.  Basically,
-// the tests are meant to cover how existing users use these functions,
-// but not necessarily how new users could use them.
-TEST(DeprecatedFunctionsTest, CommandlineFlagsIntoString) {
-  string s = CommandlineFlagsIntoString();
-  EXPECT_NE(string::npos, s.find("--test_bool="));
-}
-
-TEST(DeprecatedFunctionsTest, AppendFlagsIntoFile) {
-  FLAGS_test_int32 = 10;     // just to make the test more interesting
-  string filename(TmpFile("flagfile"));
-  unlink(filename.c_str());  // just to be safe
-  const bool r = AppendFlagsIntoFile(filename, "not the real argv0");
-  EXPECT_TRUE(r);
-
-  FILE* fp;
-  EXPECT_EQ(0, SafeFOpen(&fp, filename.c_str(), "r"));
-  EXPECT_TRUE(fp != NULL);
-  char line[8192];
-  EXPECT_TRUE(fgets(line, sizeof(line)-1, fp) != NULL);  // get the first line
-  // First line should be progname.
-  EXPECT_STREQ("not the real argv0\n", line);
-
-  bool found_bool = false, found_int32 = false;
-  while (fgets(line, sizeof(line)-1, fp)) {
-    line[sizeof(line)-1] = '\0';    // just to be safe
-    if (strcmp(line, "--test_bool=false\n") == 0)
-      found_bool = true;
-    if (strcmp(line, "--test_int32=10\n") == 0)
-      found_int32 = true;
-  }
-  EXPECT_TRUE(found_int32);
-  EXPECT_TRUE(found_bool);
-  fclose(fp);
-}
-
-TEST(DeprecatedFunctionsTest, ReadFromFlagsFile) {
-  FLAGS_test_int32 = -10;    // just to make the test more interesting
-  string filename(TmpFile("flagfile2"));
-  unlink(filename.c_str());  // just to be safe
-  bool r = AppendFlagsIntoFile(filename, GetArgv0());
-  EXPECT_TRUE(r);
-
-  FLAGS_test_int32 = -11;
-  r = ReadFromFlagsFile(filename, GetArgv0(), true);
-  EXPECT_TRUE(r);
-  EXPECT_EQ(-10, FLAGS_test_int32);
-}  // unnamed namespace
-
-TEST(DeprecatedFunctionsTest, ReadFromFlagsFileFailure) {
-  FLAGS_test_int32 = -20;
-  string filename(TmpFile("flagfile3"));
-  FILE* fp;
-  EXPECT_EQ(0, SafeFOpen(&fp, filename.c_str(), "w"));
-  EXPECT_TRUE(fp != NULL);
-  // Note the error in the bool assignment below...
-  fprintf(fp, "%s\n--test_int32=-21\n--test_bool=not_a_bool!\n", GetArgv0());
-  fclose(fp);
-
-  FLAGS_test_int32 = -22;
-  const bool r = ReadFromFlagsFile(filename, GetArgv0(), false);
-  EXPECT_FALSE(r);
-  EXPECT_EQ(-22, FLAGS_test_int32);   // the -21 from the flagsfile didn't take
-}
-
-TEST(FlagsSetBeforeInitTest, TryFromEnv) {
-  EXPECT_EQ("pre-set", FLAGS_test_tryfromenv);
-}
-
-// The following test case verifies that ParseCommandLineFlags() and
-// ParseCommandLineNonHelpFlags() uses the last definition of a flag
-// in case it's defined more than once.
-
-DEFINE_int32(test_flag, -1, "used for testing gflags.cc");
-
-// Parses and returns the --test_flag flag.
-// If with_help is true, calls ParseCommandLineFlags; otherwise calls
-// ParseCommandLineNonHelpFlags.
-int32 ParseTestFlag(bool with_help, int argc, const char** const_argv) {
-  FlagSaver fs;  // Restores the flags before returning.
-
-  // Makes a copy of the input array s.t. it can be reused
-  // (ParseCommandLineFlags() will alter the array).
-  char** const argv_save = new char*[argc + 1];
-  char** argv = argv_save;
-  memcpy(argv, const_argv, sizeof(*argv)*(argc + 1));
-
-  if (with_help) {
-    ParseCommandLineFlags(&argc, &argv, true);
-  } else {
-    ParseCommandLineNonHelpFlags(&argc, &argv, true);
-  }
-
-  delete[] argv_save;
-  return FLAGS_test_flag;
-}
-
-TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
-     WhenFlagIsDefinedTwiceOnCommandLine) {
-  const char* argv[] = {
-    "my_test",
-    "--test_flag=1",
-    "--test_flag=2",
-    NULL,
-  };
-
-  EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
-     WhenFlagIsDefinedTwiceInFlagFile) {
-  const char* argv[] = {
-    "my_test",
-    GetFlagFileFlag(),
-    NULL,
-  };
-
-  EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
-     WhenFlagIsDefinedInCommandLineAndThenFlagFile) {
-  const char* argv[] = {
-    "my_test",
-    "--test_flag=0",
-    GetFlagFileFlag(),
-    NULL,
-  };
-
-  EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
-     WhenFlagIsDefinedInFlagFileAndThenCommandLine) {
-  const char* argv[] = {
-    "my_test",
-    GetFlagFileFlag(),
-    "--test_flag=3",
-    NULL,
-  };
-
-  EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
-     WhenFlagIsDefinedInCommandLineAndFlagFileAndThenCommandLine) {
-  const char* argv[] = {
-    "my_test",
-    "--test_flag=0",
-    GetFlagFileFlag(),
-    "--test_flag=3",
-    NULL,
-  };
-
-  EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgFirst) {
-  const char* argv[] = {
-    "my_test",
-    "--",
-    "--test_flag=0",
-    NULL,
-  };
-
-  EXPECT_EQ(-1, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(-1, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgMiddle) {
-  const char* argv[] = {
-    "my_test",
-    "--test_flag=7",
-    "--",
-    "--test_flag=0",
-    NULL,
-  };
-
-  EXPECT_EQ(7, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(7, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-TEST(ParseCommandLineFlagsAndDashArgs, OneDashArg) {
-  const char* argv[] = {
-    "my_test",
-    "-",
-    "--test_flag=0",
-    NULL,
-  };
-
-  EXPECT_EQ(0, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  EXPECT_EQ(0, ParseTestFlag(false, arraysize(argv) - 1, argv));
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
-     FlagIsCompletelyUnknown) {
-  const char* argv[] = {
-    "my_test",
-    "--this_flag_does_not_exist",
-    NULL,
-  };
-
-  EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
-               "unknown command line flag.*");
-  EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
-               "unknown command line flag.*");
-}
-
-TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
-     BoolFlagIsCompletelyUnknown) {
-  const char* argv[] = {
-    "my_test",
-    "--nothis_flag_does_not_exist",
-    NULL,
-  };
-
-  EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
-               "unknown command line flag.*");
-  EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
-               "unknown command line flag.*");
-}
-
-TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
-     FlagIsNotABool) {
-  const char* argv[] = {
-    "my_test",
-    "--notest_string",
-    NULL,
-  };
-
-  EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
-               "boolean value .* specified for .* command line flag");
-  EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
-               "boolean value .* specified for .* command line flag");
-}
-#endif
-
-TEST(ParseCommandLineFlagsWrongFields,
-     DescriptionIsInvalid) {
-  // These must not be automatic variables, since command line flags
-  // aren't unregistered and gUnit uses FlagSaver to save and restore
-  // command line flags' values.  If these are on the stack, then when
-  // later tests attempt to save and restore their values, the stack
-  // addresses of these variables will be overwritten...  Stack smash!
-  static bool current_storage;
-  static bool defvalue_storage;
-  FlagRegisterer fr("flag_name", NULL, "filename",
-                    &current_storage, &defvalue_storage);
-  CommandLineFlagInfo fi;
-  EXPECT_TRUE(GetCommandLineFlagInfo("flag_name", &fi));
-  EXPECT_EQ("", fi.description);
-  EXPECT_EQ(&current_storage, fi.flag_ptr);
-}
-
-static bool ValidateTestFlagIs5(const char* flagname, int32 flagval) {
-  if (flagval == 5)
-    return true;
-  printf("%s isn't 5!\n", flagname);
-  return false;
-}
-
-static bool ValidateTestFlagIs10(const char* flagname, int32 flagval) {
-  return flagval == 10;
-}
-
-
-TEST(FlagsValidator, ValidFlagViaArgv) {
-  const char* argv[] = {
-    "my_test",
-    "--test_flag=5",
-    NULL,
-  };
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  EXPECT_EQ(5, ParseTestFlag(true, arraysize(argv) - 1, argv));
-  // Undo the flag validator setting
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-
-TEST(FlagsValidator, ValidFlagViaSetDefault) {
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  // SetCommandLineOptionWithMode returns the empty string on error.
-  EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
-                                             SET_FLAG_IF_DEFAULT));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-
-TEST(FlagsValidator, ValidFlagViaSetValue) {
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  FLAGS_test_flag = 100;   // doesn't trigger the validator
-  // SetCommandLineOptionWithMode returns the empty string on error.
-  EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
-                                             SET_FLAGS_VALUE));
-  EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
-                                             SET_FLAGS_DEFAULT));
-  EXPECT_NE("", SetCommandLineOption("test_flag", "5"));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-TEST(FlagsValidatorDeathTest, InvalidFlagViaArgv) {
-  const char* argv[] = {
-    "my_test",
-    "--test_flag=50",
-    NULL,
-  };
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
-               "ERROR: failed validation of new value '50' for flag 'test_flag'");
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-#endif
-
-TEST(FlagsValidator, InvalidFlagViaSetDefault) {
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  // SetCommandLineOptionWithMode returns the empty string on error.
-  EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
-                                             SET_FLAG_IF_DEFAULT));
-  EXPECT_EQ(-1, FLAGS_test_flag);   // the setting-to-50 should have failed
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-
-TEST(FlagsValidator, InvalidFlagViaSetValue) {
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  FLAGS_test_flag = 100;   // doesn't trigger the validator
-  // SetCommandLineOptionWithMode returns the empty string on error.
-  EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
-                                             SET_FLAGS_VALUE));
-  EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
-                                             SET_FLAGS_DEFAULT));
-  EXPECT_EQ("", SetCommandLineOption("test_flag", "50"));
-  EXPECT_EQ(100, FLAGS_test_flag);   // the setting-to-50 should have failed
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-TEST(FlagsValidatorDeathTest, InvalidFlagNeverSet) {
-  // If a flag keeps its default value, and that default value is
-  // invalid, we should die at argv-parse time.
-  const char* argv[] = {
-    "my_test",
-    NULL,
-  };
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
-               "ERROR: --test_flag must be set on the commandline");
-}
-#endif
-
-TEST(FlagsValidator, InvalidFlagPtr) {
-  int32 dummy;
-  EXPECT_FALSE(RegisterFlagValidator(NULL, &ValidateTestFlagIs5));
-  EXPECT_FALSE(RegisterFlagValidator(&dummy, &ValidateTestFlagIs5));
-}
-
-TEST(FlagsValidator, RegisterValidatorTwice) {
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
-  EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-}
-
-TEST(FlagsValidator, CommandLineFlagInfo) {
-  CommandLineFlagInfo info;
-  info = GetCommandLineFlagInfoOrDie("test_flag");
-  EXPECT_FALSE(info.has_validator_fn);
-
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  info = GetCommandLineFlagInfoOrDie("test_flag");
-  EXPECT_TRUE(info.has_validator_fn);
-
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-  info = GetCommandLineFlagInfoOrDie("test_flag");
-  EXPECT_FALSE(info.has_validator_fn);
-}
-
-TEST(FlagsValidator, FlagSaver) {
-  {
-    FlagSaver fs;
-    EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-    EXPECT_EQ("", SetCommandLineOption("test_flag", "50"));  // fails validation
-  }
-  EXPECT_NE("", SetCommandLineOption("test_flag", "50"));  // validator is gone
-
-  EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
-  {
-    FlagSaver fs;
-    EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
-    EXPECT_NE("", SetCommandLineOption("test_flag", "50"));  // no validator
-  }
-  EXPECT_EQ("", SetCommandLineOption("test_flag", "50"));  // validator is back
-}
-
-
-}  // unnamed namespace
-
-static int main(int argc, char **argv) {
-
-  // Run unit tests only if called without arguments, otherwise this program
-  // is used by an "external" usage test
-  const bool run_tests = (argc == 1);
-
-  // We need to call SetArgv before parsing flags, so our "test" argv will
-  // win out over this executable's real argv.  That makes running this
-  // test with a real --help flag kinda annoying, unfortunately.
-  const char* test_argv[] = { "/test/argv/for/gflags_unittest",
-                              "argv 2", "3rd argv", "argv #4" };
-  SetArgv(arraysize(test_argv), test_argv);
-
-  // The first arg is the usage message, also important for testing.
-  string usage_message = (string(GetArgv0()) +
-                          ": <useless flag> [...]\nDoes something useless.\n");
-
-  // We test setting tryfromenv manually, and making sure
-  // ParseCommandLineFlags still evaluates it.
-  FLAGS_tryfromenv = "test_tryfromenv";
-  setenv("FLAGS_test_tryfromenv", "pre-set", 1);
-
-  // Modify flag values from declared default value in two ways.
-  // The recommended way:
-  SetCommandLineOptionWithMode("changed_bool1", "true", SET_FLAGS_DEFAULT);
-
-  // The non-recommended way:
-  FLAGS_changed_bool2 = true;
-
-  SetUsageMessage(usage_message);
-  SetVersionString("test_version");
-  ParseCommandLineFlags(&argc, &argv, true);
-  MakeTmpdir(&FLAGS_test_tmpdir);
-
-  int exit_status = 0;
-  if (run_tests) {
-	  fprintf(stdout, "Running the unit tests now...\n\n"); fflush(stdout);
-	  exit_status = RUN_ALL_TESTS();
-  } else fprintf(stderr, "\n\nPASS\n");
-  ShutDownCommandLineFlags();
-  return exit_status;
-}
-
-} // GFLAGS_NAMESPACE
-
-int main(int argc, char** argv) {
-  return GFLAGS_NAMESPACE::main(argc, argv);
-}
-
diff --git a/third_party/gflags/test/gflags_unittest_flagfile b/third_party/gflags/test/gflags_unittest_flagfile
deleted file mode 100644
index f4fa0c4..0000000
--- a/third_party/gflags/test/gflags_unittest_flagfile
+++ /dev/null
@@ -1,2 +0,0 @@
---test_flag=1
---test_flag=2
diff --git a/third_party/gflags/test/nc/CMakeLists.txt b/third_party/gflags/test/nc/CMakeLists.txt
deleted file mode 100644
index d00b07d..0000000
--- a/third_party/gflags/test/nc/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-## gflags negative compilation tests
-
-cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR)
-
-if (NOT TEST_NAME)
-  message (FATAL_ERROR "Missing TEST_NAME CMake flag")
-endif ()
-string (TOUPPER ${TEST_NAME} TEST_NAME_UPPER)
-
-project (gflags_${TEST_NAME})
-
-find_package (gflags REQUIRED)
-include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/..")
-add_definitions (-DTEST_${TEST_NAME_UPPER})
-add_executable (gflags_${TEST_NAME} gflags_nc.cc)
-target_link_libraries(gflags_${TEST_NAME} gflags)
diff --git a/third_party/gflags/test/nc/gflags_nc.cc b/third_party/gflags/test/nc/gflags_nc.cc
deleted file mode 100644
index 1990c30..0000000
--- a/third_party/gflags/test/nc/gflags_nc.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-// ---
-//
-// A negative comiple test for gflags.
-
-#include <gflags/gflags.h>
-
-#if defined(TEST_NC_SWAPPED_ARGS)
-
-DEFINE_bool(some_bool_flag,
-            "the default value should go here, not the description",
-            false);
-
-
-#elif defined(TEST_NC_INT_INSTEAD_OF_BOOL)
-
-DEFINE_bool(some_bool_flag_2,
-            0,
-            "should have been an int32 flag but mistakenly used bool instead");
-
-#elif defined(TEST_NC_BOOL_IN_QUOTES)
-
-
-DEFINE_bool(some_bool_flag_3,
-            "false",
-            "false in in quotes, which is wrong");
-
-#elif defined(TEST_NC_SANITY)
-
-DEFINE_bool(some_bool_flag_4,
-            true,
-            "this is the correct usage of DEFINE_bool");
-
-#elif defined(TEST_NC_DEFINE_STRING_WITH_0)
-
-DEFINE_string(some_string_flag,
-              0,
-              "Trying to construct a string by passing 0 would cause a crash.");
-
-#endif
-
-int main(int, char **)
-{
-  return 0;
-}
diff --git a/third_party/google-glog/.bazelci/presubmit.yml b/third_party/google-glog/.bazelci/presubmit.yml
deleted file mode 100644
index 9065173..0000000
--- a/third_party/google-glog/.bazelci/presubmit.yml
+++ /dev/null
@@ -1,58 +0,0 @@
----
-tasks:
-  ubuntu1804:
-    name: "Ubuntu 18.04"
-    platform: ubuntu1804
-    build_flags:
-    - "--features=layering_check"
-    - "--copt=-Werror"
-    build_targets:
-    - "//..."
-    test_flags:
-    - "--features=layering_check"
-    - "--copt=-Werror"
-    test_targets:
-    - "//..."
-  macos:
-    name: "macOS: latest Xcode"
-    platform: macos
-    build_flags:
-    - "--features=layering_check"
-    - "--copt=-Werror"
-    build_targets:
-    - "//..."
-    test_flags:
-    - "--features=layering_check"
-    - "--copt=-Werror"
-    test_targets:
-    - "//..."
-  windows-msvc:
-    name: "Windows: MSVC 2017"
-    platform: windows
-    environment:
-      BAZEL_VC: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC"
-    build_flags:
-    - "--features=layering_check"
-    - "--copt=/WX"
-    build_targets:
-    - "//..."
-    test_flags:
-    - "--features=layering_check"
-    - "--copt=/WX"
-    test_targets:
-    - "//..."
-  windows-clang-cl:
-    name: "Windows: Clang"
-    platform: windows
-    environment:
-      BAZEL_VC: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC"
-    build_flags:
-    - "--compiler=clang-cl"
-    - "--features=layering_check"
-    build_targets:
-    - "//..."
-    test_flags:
-    - "--compiler=clang-cl"
-    - "--features=layering_check"
-    test_targets:
-    - "//..."
diff --git a/third_party/google-glog/.clang-format b/third_party/google-glog/.clang-format
deleted file mode 100644
index f2dd0de..0000000
--- a/third_party/google-glog/.clang-format
+++ /dev/null
@@ -1,168 +0,0 @@
----
-Language:        Cpp
-# BasedOnStyle:  Google
-AccessModifierOffset: -1
-AlignAfterOpenBracket: Align
-AlignConsecutiveMacros: false
-AlignConsecutiveAssignments: false
-AlignConsecutiveDeclarations: false
-AlignEscapedNewlines: Left
-AlignOperands:   true
-AlignTrailingComments: true
-AllowAllArgumentsOnNextLine: true
-AllowAllConstructorInitializersOnNextLine: true
-AllowAllParametersOfDeclarationOnNextLine: true
-AllowShortBlocksOnASingleLine: Never
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: All
-AllowShortLambdasOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: WithoutElse
-AllowShortLoopsOnASingleLine: true
-AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: true
-AlwaysBreakTemplateDeclarations: Yes
-BinPackArguments: true
-BinPackParameters: true
-BraceWrapping:
-  AfterCaseLabel:  false
-  AfterClass:      false
-  AfterControlStatement: false
-  AfterEnum:       false
-  AfterFunction:   false
-  AfterNamespace:  false
-  AfterObjCDeclaration: false
-  AfterStruct:     false
-  AfterUnion:      false
-  AfterExternBlock: false
-  BeforeCatch:     false
-  BeforeElse:      false
-  IndentBraces:    false
-  SplitEmptyFunction: true
-  SplitEmptyRecord: true
-  SplitEmptyNamespace: true
-BreakBeforeBinaryOperators: None
-BreakBeforeBraces: Attach
-BreakBeforeInheritanceComma: false
-BreakInheritanceList: BeforeColon
-BreakBeforeTernaryOperators: true
-BreakConstructorInitializersBeforeComma: false
-BreakConstructorInitializers: BeforeColon
-BreakAfterJavaFieldAnnotations: false
-BreakStringLiterals: true
-ColumnLimit:     80
-CommentPragmas:  '^ IWYU pragma:'
-CompactNamespaces: false
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
-ConstructorInitializerIndentWidth: 4
-ContinuationIndentWidth: 4
-Cpp11BracedListStyle: true
-DeriveLineEnding: true
-DerivePointerAlignment: true
-DisableFormat:   false
-ExperimentalAutoDetectBinPacking: false
-FixNamespaceComments: true
-ForEachMacros:
-  - foreach
-  - Q_FOREACH
-  - BOOST_FOREACH
-IncludeBlocks:   Regroup
-IncludeCategories:
-  - Regex:           '^<ext/.*\.h>'
-    Priority:        2
-    SortPriority:    0
-  - Regex:           '^<.*\.h>'
-    Priority:        1
-    SortPriority:    0
-  - Regex:           '^<.*'
-    Priority:        2
-    SortPriority:    0
-  - Regex:           '.*'
-    Priority:        3
-    SortPriority:    0
-IncludeIsMainRegex: '([-_](test|unittest))?$'
-IncludeIsMainSourceRegex: ''
-IndentCaseLabels: true
-IndentGotoLabels: true
-IndentPPDirectives: None
-IndentWidth:     2
-IndentWrappedFunctionNames: false
-JavaScriptQuotes: Leave
-JavaScriptWrapImports: true
-KeepEmptyLinesAtTheStartOfBlocks: false
-MacroBlockBegin: ''
-MacroBlockEnd:   ''
-MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None
-ObjCBinPackProtocolList: Never
-ObjCBlockIndentWidth: 2
-ObjCSpaceAfterProperty: false
-ObjCSpaceBeforeProtocolList: true
-PenaltyBreakAssignment: 2
-PenaltyBreakBeforeFirstCallParameter: 1
-PenaltyBreakComment: 300
-PenaltyBreakFirstLessLess: 120
-PenaltyBreakString: 1000
-PenaltyBreakTemplateDeclaration: 10
-PenaltyExcessCharacter: 1000000
-PenaltyReturnTypeOnItsOwnLine: 200
-PointerAlignment: Left
-RawStringFormats:
-  - Language:        Cpp
-    Delimiters:
-      - cc
-      - CC
-      - cpp
-      - Cpp
-      - CPP
-      - 'c++'
-      - 'C++'
-    CanonicalDelimiter: ''
-    BasedOnStyle:    google
-  - Language:        TextProto
-    Delimiters:
-      - pb
-      - PB
-      - proto
-      - PROTO
-    EnclosingFunctions:
-      - EqualsProto
-      - EquivToProto
-      - PARSE_PARTIAL_TEXT_PROTO
-      - PARSE_TEST_PROTO
-      - PARSE_TEXT_PROTO
-      - ParseTextOrDie
-      - ParseTextProtoOrDie
-    CanonicalDelimiter: ''
-    BasedOnStyle:    google
-ReflowComments:  true
-SortIncludes:    true
-SortUsingDeclarations: true
-SpaceAfterCStyleCast: false
-SpaceAfterLogicalNot: false
-SpaceAfterTemplateKeyword: true
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeCpp11BracedList: false
-SpaceBeforeCtorInitializerColon: true
-SpaceBeforeInheritanceColon: true
-SpaceBeforeParens: ControlStatements
-SpaceBeforeRangeBasedForLoopColon: true
-SpaceInEmptyBlock: false
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 2
-SpacesInAngles:  false
-SpacesInConditionalStatement: false
-SpacesInContainerLiterals: true
-SpacesInCStyleCastParentheses: false
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
-SpaceBeforeSquareBrackets: false
-Standard:        Auto
-StatementMacros:
-  - Q_UNUSED
-  - QT_REQUIRE_VERSION
-TabWidth:        8
-UseCRLF:         false
-UseTab:          Never
-...
-
diff --git a/third_party/google-glog/.clang-tidy b/third_party/google-glog/.clang-tidy
deleted file mode 100644
index 19082cd..0000000
--- a/third_party/google-glog/.clang-tidy
+++ /dev/null
@@ -1,59 +0,0 @@
----
-Checks:          'clang-diagnostic-*,clang-analyzer-*,google-*'
-WarningsAsErrors: ''
-HeaderFilterRegex: ''
-AnalyzeTemporaryDtors: false
-FormatStyle:     file
-CheckOptions:
-  - key:             cert-dcl16-c.NewSuffixes
-    value:           'L;LL;LU;LLU'
-  - key:             cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
-    value:           '0'
-  - key:             cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
-    value:           '1'
-  - key:             cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
-    value:           '1'
-  - key:             google-build-namespaces.HeaderFileExtensions
-    value:           ',h,hh,hpp,hxx'
-  - key:             google-global-names-in-headers.HeaderFileExtensions
-    value:           ',h,hh,hpp,hxx'
-  - key:             google-readability-braces-around-statements.ShortStatementLines
-    value:           '1'
-  - key:             google-readability-function-size.BranchThreshold
-    value:           '4294967295'
-  - key:             google-readability-function-size.LineThreshold
-    value:           '4294967295'
-  - key:             google-readability-function-size.NestingThreshold
-    value:           '4294967295'
-  - key:             google-readability-function-size.ParameterThreshold
-    value:           '4294967295'
-  - key:             google-readability-function-size.StatementThreshold
-    value:           '800'
-  - key:             google-readability-function-size.VariableThreshold
-    value:           '4294967295'
-  - key:             google-readability-namespace-comments.ShortNamespaceLines
-    value:           '10'
-  - key:             google-readability-namespace-comments.SpacesBeforeComments
-    value:           '2'
-  - key:             google-runtime-int.SignedTypePrefix
-    value:           int
-  - key:             google-runtime-int.TypeSuffix
-    value:           ''
-  - key:             google-runtime-int.UnsignedTypePrefix
-    value:           uint
-  - key:             google-runtime-references.WhiteListTypes
-    value:           ''
-  - key:             modernize-loop-convert.MaxCopySize
-    value:           '16'
-  - key:             modernize-loop-convert.MinConfidence
-    value:           reasonable
-  - key:             modernize-loop-convert.NamingStyle
-    value:           CamelCase
-  - key:             modernize-pass-by-value.IncludeStyle
-    value:           llvm
-  - key:             modernize-replace-auto-ptr.IncludeStyle
-    value:           llvm
-  - key:             modernize-use-nullptr.NullMacros
-    value:           'NULL'
-...
-
diff --git a/third_party/google-glog/.gitattributes b/third_party/google-glog/.gitattributes
deleted file mode 100644
index 2f6d494..0000000
--- a/third_party/google-glog/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-*.h linguist-language=C++
diff --git a/third_party/google-glog/.github/workflows/android.yml b/third_party/google-glog/.github/workflows/android.yml
deleted file mode 100644
index c372669..0000000
--- a/third_party/google-glog/.github/workflows/android.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-name: Android
-
-on: [push, pull_request]
-
-jobs:
-  build-android:
-    name: NDK-C++${{matrix.std}}-${{matrix.abi}}-${{matrix.build_type}}
-    runs-on: ubuntu-latest
-    defaults:
-      run:
-        shell: bash
-    env:
-      NDK_VERSION: 25.0.8775105
-    strategy:
-      fail-fast: true
-      matrix:
-        std: [98, 11, 14, 17, 20]
-        abi: [arm64-v8a, armeabi-v7a, x86_64, x86]
-        build_type: [Debug, Release]
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup Ninja
-        uses: ashutoshvarma/setup-ninja@master
-        with:
-          version: 1.10.0
-
-      - name: Setup C++98 Environment
-        if: matrix.std == '98'
-        run: |
-          echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
-
-      - name: Setup NDK
-        env:
-          ANDROID_SDK_ROOT: /usr/local/lib/android/sdk
-        run: |
-          echo 'y' | ${{env.ANDROID_SDK_ROOT}}/cmdline-tools/latest/bin/sdkmanager --install 'ndk;${{env.NDK_VERSION}}'
-
-      - name: Configure
-        env:
-          CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
-        run: |
-          cmake -S . -B build_${{matrix.abi}} \
-                -DCMAKE_ANDROID_API=28 \
-                -DCMAKE_ANDROID_ARCH_ABI=${{matrix.abi}} \
-                -DCMAKE_ANDROID_NDK=/usr/local/lib/android/sdk/ndk/${{env.NDK_VERSION}} \
-                -DCMAKE_ANDROID_STL_TYPE=c++_shared \
-                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-                -DCMAKE_CXX_EXTENSIONS=OFF \
-                -DCMAKE_CXX_STANDARD=${{matrix.std}} \
-                -DCMAKE_CXX_STANDARD_REQUIRED=ON \
-                -DCMAKE_SYSTEM_NAME=Android \
-                -G Ninja \
-                -Werror
-
-      - name: Build
-        run: |
-          cmake --build build_${{matrix.abi}} \
-                --config ${{matrix.build_type}}
diff --git a/third_party/google-glog/.github/workflows/emscripten.yml b/third_party/google-glog/.github/workflows/emscripten.yml
deleted file mode 100644
index 566c67e..0000000
--- a/third_party/google-glog/.github/workflows/emscripten.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-name: Emscripten
-
-on: [push, pull_request]
-
-jobs:
-  build-linux:
-    defaults:
-      run:
-        shell: bash
-    name: Emscripten-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}
-    runs-on: ubuntu-latest
-    container: emscripten/emsdk
-    strategy:
-      fail-fast: true
-      matrix:
-        build_type: [Release, Debug]
-        extra: [no-custom-prefix, custom-prefix]
-        lib: [static]
-        std: [98, 11, 14, 17, 20]
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup Dependencies
-        run: |
-          apt-get update
-          DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \
-            cmake \
-            ninja-build
-
-      - name: Setup C++98 Environment
-        if: matrix.std == '98'
-        run: |
-          echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
-
-      - name: Configure
-        env:
-          CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror -Wno-error=wasm-exception-spec ${{env.CXXFLAGS}}
-        run: |
-          cmake -S . -B build_${{matrix.build_type}} \
-            -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \
-            -DCMAKE_AR=$(which emar) \
-            -DCMAKE_C_COMPILER=$(which emcc) \
-            -DCMAKE_CXX_COMPILER=$(which em++) \
-            -DCMAKE_CXX_STANDARD=${{matrix.std}} \
-            -DCMAKE_CXX_STANDARD_REQUIRED=ON \
-            -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
-            -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
-            -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
-            -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
-            -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install \
-            -DCMAKE_RANLIB=$(which emranlib) \
-            -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \
-            -G Ninja \
-            -Werror
-
-      - name: Build
-        run: |
-          cmake --build build_${{matrix.build_type}} \
-                --config ${{matrix.build_type}}
diff --git a/third_party/google-glog/.github/workflows/linux.yml b/third_party/google-glog/.github/workflows/linux.yml
deleted file mode 100644
index c9ac1a4..0000000
--- a/third_party/google-glog/.github/workflows/linux.yml
+++ /dev/null
@@ -1,150 +0,0 @@
-name: Linux
-
-on: [push, pull_request]
-
-jobs:
-  build-linux:
-    defaults:
-      run:
-        shell: bash
-    name: GCC-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: true
-      matrix:
-        build_type: [Release, Debug]
-        extra: [no-custom-prefix, custom-prefix]
-        lib: [shared, static]
-        std: [98, 11, 14, 17, 20]
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup Dependencies
-        run: |
-          sudo apt-get update
-          DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \
-            build-essential \
-            cmake \
-            lcov \
-            libgflags-dev \
-            libunwind-dev \
-            ninja-build
-
-      - name: Cache GTest
-        id: cache-gtest
-        uses: actions/cache@v2
-        with:
-          path: gtest/
-          key: ${{runner.os}}-gtest-1.11
-
-      - name: Download GTest
-        if: steps.cache-gtest.outputs.cache-hit != 'true'
-        run: |
-          wget https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz
-          tar xvf release-1.11.0.tar.gz
-
-      - name: Build GTest
-        if: steps.cache-gtest.outputs.cache-hit != 'true'
-        run: |
-          cmake -S googletest-release-1.11.0 -B build-googletest \
-            -DBUILD_SHARED_LIBS=${{matrix.shared}} \
-            -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-            -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/gtest \
-            -G Ninja
-          cmake --build build-googletest --target install
-
-      - name: Setup Environment
-        if: matrix.build_type == 'Debug'
-        run: |
-          echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV
-          echo 'GTest_ROOT=${{github.workspace}}/gtest' >> $GITHUB_ENV
-
-      - name: Setup C++98 Environment
-        if: matrix.std == '98'
-        run: |
-          echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
-
-      - name: Configure
-        env:
-          CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
-        run: |
-          cmake -S . -B build_${{matrix.build_type}} \
-            -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \
-            -DCMAKE_CXX_STANDARD=${{matrix.std}} \
-            -DCMAKE_CXX_STANDARD_REQUIRED=ON \
-            -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install \
-            -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \
-            -G Ninja \
-            -Werror
-
-      - name: Build
-        run: |
-          cmake --build build_${{matrix.build_type}} \
-                --config ${{matrix.build_type}}
-
-      - name: Install
-        run: |
-          cmake --build build_${{matrix.build_type}} \
-                --config ${{matrix.build_type}} \
-                --target install
-
-          cmake build_${{matrix.build_type}} \
-                -DCMAKE_INSTALL_INCLUDEDIR=${{runner.workspace}}/foo/include \
-                -DCMAKE_INSTALL_LIBDIR=${{runner.workspace}}/foo/lib \
-                -DCMAKE_INSTALL_DATAROOTDIR=${{runner.workspace}}/foo/share
-          cmake --build build_${{matrix.build_type}} \
-                --config ${{matrix.build_type}} \
-                --target install
-
-      - name: Test CMake Package (relative GNUInstallDirs)
-        run: |
-          cmake -S src/package_config_unittest/working_config \
-                -B build_${{matrix.build_type}}_package \
-                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-                -DCMAKE_PREFIX_PATH=${{github.workspace}}/install \
-                -G Ninja
-          cmake --build build_${{matrix.build_type}}_package \
-                --config ${{matrix.build_type}}
-
-      - name: Test CMake Package (absolute GNUInstallDirs)
-        run: |
-          cmake -S src/package_config_unittest/working_config \
-                -B build_${{matrix.build_type}}_package_foo \
-                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-                -DCMAKE_PREFIX_PATH=${{runner.workspace}}/foo \
-                -G Ninja
-          cmake --build build_${{matrix.build_type}}_package_foo \
-                --config ${{matrix.build_type}}
-
-      - name: Test
-        run: |
-          ctest --test-dir build_${{matrix.build_type}} -j$(nproc) --output-on-failure
-
-      - name: Generate Coverage
-        if: matrix.build_type == 'Debug'
-        run: |
-          lcov --directory . --capture --output-file coverage.info
-          lcov --remove coverage.info \
-            '${{github.workspace}}/gtest/*' \
-            '*/src/*_unittest.cc' \
-            '*/src/googletest.h' \
-            '*/src/mock-log.h' \
-            '/usr/*' \
-            --output-file coverage.info
-
-          for file in src/glog/*.h.in; do
-            name=$(basename ${file})
-            name_we=${name%.h.in}
-            sed -i "s|build_${{matrix.build_type}}/glog/${name_we}.h\$|${file}|g" coverage.info
-          done
-
-          lcov --list coverage.info
-
-      - name: Upload Coverage to Codecov
-        if: matrix.build_type == 'Debug'
-        uses: codecov/codecov-action@v2
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          fail_ci_if_error: true
-          verbose: true
diff --git a/third_party/google-glog/.github/workflows/macos.yml b/third_party/google-glog/.github/workflows/macos.yml
deleted file mode 100644
index 9e64b09..0000000
--- a/third_party/google-glog/.github/workflows/macos.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-name: macOS
-
-on: [push, pull_request]
-
-jobs:
-  build-macos:
-    name: AppleClang-C++${{matrix.std}}-${{matrix.build_type}}
-    runs-on: macos-12
-    strategy:
-      fail-fast: true
-      matrix:
-        std: [98, 11, 14, 17, 20]
-        include:
-          - generator: Ninja
-          - build_type: Debug
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup Ninja
-        uses: ashutoshvarma/setup-ninja@master
-        with:
-          version: 1.10.0
-
-      - name: Setup Dependencies
-        run: |
-          brew install lcov
-
-      - name: Setup Environment
-        if: matrix.build_type == 'Debug'
-        run: |
-          echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV
-
-      - name: Configure
-        shell: bash
-        env:
-          CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
-        run: |
-          cmake -S . -B build_${{matrix.build_type}} \
-                -DCMAKE_CXX_EXTENSIONS=OFF \
-                -DCMAKE_CXX_FLAGS_DEBUG=-pedantic-errors  \
-                -DCMAKE_CXX_FLAGS_RELEASE=-pedantic-errors \
-                -DCMAKE_CXX_STANDARD=${{matrix.std}} \
-                -DCMAKE_CXX_STANDARD_REQUIRED=ON \
-                -G "${{matrix.generator}}" \
-                -Werror
-
-      - name: Build
-        run: |
-          cmake --build build_${{matrix.build_type}} \
-                --config ${{matrix.build_type}}
-
-      - name: Test
-        run: |
-          ctest --test-dir build_${{matrix.build_type}} \
-                --output-on-failure
-
-      - name: Generate Coverage
-        if: matrix.build_type == 'Debug'
-        run: |
-          lcov --directory . --capture --output-file coverage.info
-          lcov --remove coverage.info \
-            '*/src/*_unittest.cc' \
-            '*/src/googletest.h' \
-            '*/src/mock-log.h' \
-            '*/usr/*' \
-            --output-file coverage.info
-
-          for file in src/glog/*.h.in; do
-            name=$(basename ${file})
-            name_we=${name%.h.in}
-            sed -i "" "s|${{github.workspace}}/glog/${name_we}.h\$|${file}|g" coverage.info
-          done
-
-          lcov --list coverage.info
-
-      - name: Upload Coverage to Codecov
-        if: matrix.build_type == 'Debug'
-        uses: codecov/codecov-action@v2
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          fail_ci_if_error: true
-          verbose: true
diff --git a/third_party/google-glog/.github/workflows/windows.yml b/third_party/google-glog/.github/workflows/windows.yml
deleted file mode 100644
index de3b05d..0000000
--- a/third_party/google-glog/.github/workflows/windows.yml
+++ /dev/null
@@ -1,234 +0,0 @@
-name: Windows
-
-on: [push, pull_request]
-
-jobs:
-  build-msvc:
-    name: ${{matrix.msvc}}-${{matrix.arch}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}
-    runs-on: ${{matrix.os}}
-    defaults:
-      run:
-        shell: powershell
-    env:
-      CL: /MP
-      CXXFLAGS: /WX /permissive-
-    strategy:
-      fail-fast: true
-      matrix:
-        arch: [Win32, x64]
-        build_type: [Debug, Release]
-        extra: [no-custom-prefix, custom-prefix]
-        lib: [shared, static]
-        msvc: [VS-16-2019, VS-17-2022]
-        # Visual Studio 17 2022 does not support C++11 and older language standard
-        std: [14, 17, 20]
-        include:
-          - msvc: VS-16-2019
-            os: windows-2019
-            generator: 'Visual Studio 16 2019'
-          - msvc: VS-17-2022
-            os: windows-2022
-            generator: 'Visual Studio 17 2022'
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Cache GTest
-        id: cache-gtest
-        uses: actions/cache@v2
-        with:
-          path: gtest/
-          key: ${{runner.os}}-gtest-1.11-${{matrix.lib}}-${{matrix.arch}}-${{matrix.build_type}}
-
-      - name: Download GTest
-        if: steps.cache-gtest.outputs.cache-hit != 'true'
-        run: |
-          (New-Object System.Net.WebClient).DownloadFile("https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip", "release-1.11.0.zip")
-          Expand-Archive release-1.11.0.zip .
-
-      - name: Build GTest
-        if: steps.cache-gtest.outputs.cache-hit != 'true'
-        run: |
-          cmake -S googletest-release-1.11.0 -B build-googletest `
-                -A ${{matrix.arch}} `
-                -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} `
-                -Dgtest_force_shared_crt=ON `
-                -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/gtest
-          cmake --build build-googletest `
-                --config ${{matrix.build_type}} `
-                --target install
-
-      - name: Cache gflags
-        id: cache-gflags
-        uses: actions/cache@v2
-        with:
-          path: gflags/
-          key: ${{runner.os}}-gflags-2.2.2-${{matrix.lib}}-${{matrix.arch}}-${{matrix.build_type}}
-
-      - name: Download gflags
-        if: steps.cache-gflags.outputs.cache-hit != 'true'
-        run: |
-          (New-Object System.Net.WebClient).DownloadFile("https://github.com/gflags/gflags/archive/refs/tags/v2.2.2.zip", "v2.2.2.zip")
-          Expand-Archive v2.2.2.zip .
-
-      - name: Build gflags
-        if: steps.cache-gflags.outputs.cache-hit != 'true'
-        run: |
-          cmake -S gflags-2.2.2 -B build-gflags `
-                -A ${{matrix.arch}} `
-                -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} `
-                -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/gflags
-          cmake --build build-gflags `
-                --config ${{matrix.build_type}} `
-                --target install
-
-      - name: Setup Environment
-        run: |
-          echo "GTest_ROOT=$((Get-Item .).FullName)/gtest" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
-          echo "gflags_ROOT=$((Get-Item .).FullName)/gflags" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
-          echo "${{github.workspace}}/gtest/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-          echo "${{github.workspace}}/gflags/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-
-      - name: Setup Release Environment
-        if: matrix.build_type != 'Debug'
-        run: |
-          echo "CXXFLAGS=/Zi ${{env.CXXFLAGS}}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
-
-      - name: Configure
-        run: |
-          cmake -S . -B build_${{matrix.build_type}} `
-                -A ${{matrix.arch}} `
-                -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} `
-                -DCMAKE_CXX_EXTENSIONS=OFF `
-                -DCMAKE_CXX_STANDARD=${{matrix.std}} `
-                -DCMAKE_CXX_STANDARD_REQUIRED=ON `
-                -DCMAKE_EXE_LINKER_FLAGS='/NOIMPLIB' `
-                -DCMAKE_EXE_LINKER_FLAGS_RELEASE='/INCREMENTAL:NO /DEBUG' `
-                -DCMAKE_INSTALL_PREFIX:PATH=./install `
-                -DCMAKE_MSVC_RUNTIME_LIBRARY='MultiThreaded$<$<CONFIG:Debug>:Debug>DLL' `
-                -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} `
-                -G "${{matrix.generator}}" `
-                -Werror
-
-      - name: Build
-        run: cmake --build build_${{matrix.build_type}} `
-                   --config ${{matrix.build_type}}
-
-      - name: Test
-        env:
-          CTEST_OUTPUT_ON_FAILURE: 1
-        run: |
-          cmake --build build_${{matrix.build_type}}/ `
-                --config ${{matrix.build_type}} `
-                --target RUN_TESTS
-
-      - name: Install
-        run: |
-          cmake --build build_${{matrix.build_type}}/ `
-                --config ${{matrix.build_type}} `
-                --target install
-
-  build-mingw:
-    name: ${{matrix.sys}}-${{matrix.env}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}
-    runs-on: windows-2022
-    env:
-      BUILDDIR: 'build_${{matrix.sys}}-${{matrix.env}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}'
-    defaults:
-      run:
-        shell: msys2 {0}
-    strategy:
-      fail-fast: true
-      matrix:
-        build_type: [Debug]
-        extra: [no-custom-prefix, custom-prefix]
-        lib: [shared, static]
-        std: [98, 11, 14, 17, 20]
-        sys: [mingw32, mingw64]
-        include:
-         - sys: mingw32
-           env: i686
-         - sys: mingw64
-           env: x86_64
-
-    steps:
-      - uses: actions/checkout@v2
-      - uses: msys2/setup-msys2@v2
-        with:
-          msystem: ${{matrix.sys}}
-          install: >-
-            lcov
-            mingw-w64-${{matrix.env}}-cmake
-            mingw-w64-${{matrix.env}}-gcc
-            mingw-w64-${{matrix.env}}-gflags
-            mingw-w64-${{matrix.env}}-ninja
-
-      - name: Setup C++98 Environment
-        if: matrix.std == '98'
-        run: |
-          echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
-
-      - name: Setup Environment
-        if: matrix.build_type == 'Debug'
-        run: |
-          echo 'CXXFLAGS=--coverage ${{env.CXXFLAGS}}' >> $GITHUB_ENV
-
-      - name: Configure
-        env:
-          CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
-        run: |
-          cmake -S . -B build_${{matrix.build_type}}/ \
-                -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \
-                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-                -DCMAKE_CXX_EXTENSIONS=OFF \
-                -DCMAKE_CXX_STANDARD=${{matrix.std}} \
-                -DCMAKE_CXX_STANDARD_REQUIRED=ON \
-                -DCMAKE_INSTALL_PREFIX:PATH=./install \
-                -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \
-                -G Ninja \
-                -Werror
-
-      - name: Build
-        run: |
-          cmake --build build_${{matrix.build_type}}/ --config ${{matrix.build_type}}
-
-      - name: Test
-        env:
-          CTEST_OUTPUT_ON_FAILURE: 1
-        run: |
-          cmake --build build_${{matrix.build_type}}/ --config ${{matrix.build_type}} \
-                --target test
-
-      - name: Install
-        run: |
-          cmake --build build_${{matrix.build_type}}/ \
-                --config ${{matrix.build_type}} \
-                --target install
-
-      - name: Generate Coverage
-        if: matrix.build_type == 'Debug'
-        run: |
-          lcov --directory . --capture --output-file coverage.info
-          lcov --remove coverage.info \
-            '*/install/include/*' \
-            '*/msys64/mingw32/*' \
-            '*/msys64/mingw64/*' \
-            '*/src/*_unittest.cc' \
-            '*/src/googletest.h' \
-            '*/src/mock-log.h' \
-            --output-file coverage.info
-
-          for file in src/glog/*.h.in; do
-            name=$(basename ${file})
-            name_we=${name%.h.in}
-            sed -i "s|build_${{matrix.build_type}}/glog/${name_we}.h\$|${file}|g" coverage.info
-          done
-
-          lcov --list coverage.info
-
-      - name: Upload Coverage to Codecov
-        if: matrix.build_type == 'Debug'
-        uses: codecov/codecov-action@v2
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          fail_ci_if_error: true
-          verbose: true
diff --git a/third_party/google-glog/.gitignore b/third_party/google-glog/.gitignore
deleted file mode 100644
index 2678271..0000000
--- a/third_party/google-glog/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.orig
-/build*/
-bazel-*
diff --git a/third_party/google-glog/AUTHORS b/third_party/google-glog/AUTHORS
deleted file mode 100644
index 9d711ec..0000000
--- a/third_party/google-glog/AUTHORS
+++ /dev/null
@@ -1,29 +0,0 @@
-# This is the official list of glog authors for copyright purposes.
-# This file is distinct from the CONTRIBUTORS files.
-# See the latter for an explanation.
-#
-# Names should be added to this file as:
-#	Name or Organization <email address>
-# The email address is not required for organizations.
-#
-# Please keep the list sorted.
-
-Abhishek Dasgupta <abhi2743@gmail.com>
-Abhishek Parmar <abhishek@orng.net>
-Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
-Andy Ying <andy@trailofbits.com>
-Brian Silverman <bsilver16384@gmail.com>
-Dmitriy Arbitman <d.arbitman@gmail.com>
-Google Inc.
-Guillaume Dumont <dumont.guillaume@gmail.com>
-Marco Wang <m.aesophor@gmail.com>
-Michael Tanner <michael@tannertaxpro.com>
-MiniLight <MiniLightAR@Gmail.com>
-romange <romange@users.noreply.github.com>
-Roman Perepelitsa <roman.perepelitsa@gmail.com>
-Sergiu Deitsch <sergiu.deitsch@gmail.com>
-tbennun <tbennun@gmail.com>
-Teddy Reed <teddy@prosauce.org>
-Vijaymahantesh Sattigeri <vijaymahantesh016@gmail.com>
-Zhongming Qu <qzmfranklin@gmail.com>
-Zhuoran Shen <cmsflash99@gmail.com>
diff --git a/third_party/google-glog/BUILD.bazel b/third_party/google-glog/BUILD.bazel
deleted file mode 100644
index 0acdc72..0000000
--- a/third_party/google-glog/BUILD.bazel
+++ /dev/null
@@ -1,22 +0,0 @@
-licenses(["notice"])
-
-exports_files(["COPYING"])
-
-load(":bazel/glog.bzl", "glog_library")
-
-glog_library()
-
-# platform() to build with clang-cl on Bazel CI. This is enabled with
-# the flags in .bazelci/presubmit.yml:
-#
-#   --incompatible_enable_cc_toolchain_resolution
-#   --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl
-#   --extra_execution_platforms=//:x64_windows-clang-cl
-platform(
-    name = "x64_windows-clang-cl",
-    constraint_values = [
-        "@platforms//cpu:x86_64",
-        "@platforms//os:windows",
-        "@bazel_tools//tools/cpp:clang-cl",
-    ],
-)
diff --git a/third_party/google-glog/CMakeLists.txt b/third_party/google-glog/CMakeLists.txt
deleted file mode 100644
index ce6daa4..0000000
--- a/third_party/google-glog/CMakeLists.txt
+++ /dev/null
@@ -1,1102 +0,0 @@
-cmake_minimum_required (VERSION 3.16)
-project (glog
-  VERSION 0.7.0
-  DESCRIPTION "C++ implementation of the Google logging module"
-  HOMEPAGE_URL https://github.com/google/glog
-  LANGUAGES CXX
-)
-
-set (CPACK_PACKAGE_NAME glog)
-set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Google logging library")
-set (CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
-set (CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
-set (CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
-set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
-
-list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-
-include (CheckCXXCompilerFlag)
-include (CheckCXXSourceCompiles)
-include (CheckCXXSourceRuns)
-include (CheckCXXSymbolExists)
-include (CheckFunctionExists)
-include (CheckIncludeFileCXX)
-include (CheckLibraryExists)
-include (CheckStructHasMember)
-include (CheckTypeSize)
-include (CMakeDependentOption)
-include (CMakePackageConfigHelpers)
-include (CMakePushCheckState)
-include (CPack)
-include (CTest)
-include (DetermineGflagsNamespace)
-include (GenerateExportHeader)
-include (GetCacheVariables)
-include (GNUInstallDirs)
-
-option (BUILD_SHARED_LIBS "Build shared libraries" ON)
-option (PRINT_UNSYMBOLIZED_STACK_TRACES
-  "Print file offsets in traces instead of symbolizing" OFF)
-option (WITH_CUSTOM_PREFIX "Enable support for user-generated message prefixes" ON)
-option (WITH_GFLAGS "Use gflags" ON)
-option (WITH_GTEST "Use Google Test" ON)
-option (WITH_PKGCONFIG "Enable pkg-config support" ON)
-option (WITH_SYMBOLIZE "Enable symbolize module" ON)
-option (WITH_THREADS "Enable multithreading support" ON)
-option (WITH_TLS "Enable Thread Local Storage (TLS) support" ON)
-option (WITH_UNWIND "Enable libunwind support" ON)
-
-cmake_dependent_option (WITH_GMOCK "Use Google Mock" ON WITH_GTEST OFF)
-
-if (NOT WITH_UNWIND)
-  set (CMAKE_DISABLE_FIND_PACKAGE_Unwind ON)
-endif (NOT WITH_UNWIND)
-
-if (NOT WITH_GTEST)
-  set (CMAKE_DISABLE_FIND_PACKAGE_GTest ON)
-endif (NOT WITH_GTEST)
-
-if (NOT WITH_THREADS)
-  set (CMAKE_DISABLE_FIND_PACKAGE_Threads ON)
-endif (NOT WITH_THREADS)
-
-set (CMAKE_C_VISIBILITY_PRESET hidden)
-set (CMAKE_CXX_VISIBILITY_PRESET hidden)
-set (CMAKE_POSITION_INDEPENDENT_CODE ON)
-set (CMAKE_VISIBILITY_INLINES_HIDDEN ON)
-
-set (CMAKE_DEBUG_POSTFIX d)
-set (CMAKE_THREAD_PREFER_PTHREAD 1)
-
-find_package (GTest NO_MODULE)
-
-if (GTest_FOUND)
-  set (HAVE_LIB_GTEST 1)
-endif (GTest_FOUND)
-
-if (WITH_GMOCK AND TARGET GTest::gmock)
-  set (HAVE_LIB_GMOCK 1)
-endif (WITH_GMOCK AND TARGET GTest::gmock)
-
-if (WITH_GFLAGS)
-  find_package (gflags 2.2.2)
-
-  if (gflags_FOUND)
-    set (HAVE_LIB_GFLAGS 1)
-    determine_gflags_namespace (gflags_NAMESPACE)
-  endif (gflags_FOUND)
-endif (WITH_GFLAGS)
-
-find_package (Threads)
-find_package (Unwind)
-
-if (Unwind_FOUND)
-  set (HAVE_LIB_UNWIND 1)
-else (Unwind_FOUND)
-  # Check whether linking actually succeeds. ARM toolchains of LLVM unwind
-  # implementation do not necessarily provide the _Unwind_Backtrace function
-  # which causes the previous check to succeed but the linking to fail.
-  check_cxx_symbol_exists (_Unwind_Backtrace unwind.h HAVE__UNWIND_BACKTRACE)
-  check_cxx_symbol_exists (_Unwind_GetIP unwind.h HAVE__UNWIND_GETIP)
-endif (Unwind_FOUND)
-
-check_include_file_cxx (dlfcn.h HAVE_DLFCN_H)
-check_include_file_cxx (glob.h HAVE_GLOB_H)
-check_include_file_cxx (inttypes.h HAVE_INTTYPES_H)
-check_include_file_cxx (memory.h HAVE_MEMORY_H)
-check_include_file_cxx (pwd.h HAVE_PWD_H)
-check_include_file_cxx (stdint.h HAVE_STDINT_H)
-check_include_file_cxx (strings.h HAVE_STRINGS_H)
-check_include_file_cxx (sys/stat.h HAVE_SYS_STAT_H)
-check_include_file_cxx (sys/syscall.h HAVE_SYS_SYSCALL_H)
-check_include_file_cxx (sys/time.h HAVE_SYS_TIME_H)
-check_include_file_cxx (sys/types.h HAVE_SYS_TYPES_H)
-check_include_file_cxx (sys/utsname.h HAVE_SYS_UTSNAME_H)
-check_include_file_cxx (sys/wait.h HAVE_SYS_WAIT_H)
-check_include_file_cxx (syscall.h HAVE_SYSCALL_H)
-check_include_file_cxx (syslog.h HAVE_SYSLOG_H)
-check_include_file_cxx (ucontext.h HAVE_UCONTEXT_H)
-check_include_file_cxx (unistd.h HAVE_UNISTD_H)
-
-check_include_file_cxx ("ext/hash_map" HAVE_EXT_HASH_MAP)
-check_include_file_cxx ("ext/hash_set" HAVE_EXT_HASH_SET)
-check_include_file_cxx ("ext/slist" HAVE_EXT_SLIST)
-check_include_file_cxx ("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP)
-check_include_file_cxx ("tr1/unordered_set" HAVE_TR1_UNORDERED_SET)
-check_include_file_cxx ("unordered_map" HAVE_UNORDERED_MAP)
-check_include_file_cxx ("unordered_set" HAVE_UNORDERED_SET)
-
-check_type_size ("unsigned __int16" HAVE___UINT16 LANGUAGE CXX)
-check_type_size (mode_t HAVE_MODE_T LANGUAGE CXX)
-check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX)
-check_type_size (u_int16_t HAVE_U_INT16_T LANGUAGE CXX)
-check_type_size (uint16_t HAVE_UINT16_T LANGUAGE CXX)
-
-check_function_exists (dladdr HAVE_DLADDR)
-check_function_exists (fcntl HAVE_FCNTL)
-check_function_exists (pread HAVE_PREAD)
-check_function_exists (pwrite HAVE_PWRITE)
-check_function_exists (sigaction HAVE_SIGACTION)
-check_function_exists (sigaltstack HAVE_SIGALTSTACK)
-
-check_cxx_symbol_exists (backtrace execinfo.h HAVE_EXECINFO_BACKTRACE)
-check_cxx_symbol_exists (backtrace_symbols execinfo.h
-  HAVE_EXECINFO_BACKTRACE_SYMBOLS)
-
-# NOTE gcc does not fail if you pass a non-existent -Wno-* option as an
-# argument. However, it will happily fail if you pass the corresponding -W*
-# option. So, we check whether options that disable warnings exist by testing
-# the availability of the corresponding option that enables the warning. This
-# eliminates the need to check for compiler for several (mainly Clang) options.
-
-check_cxx_compiler_flag (-Wdeprecated HAVE_NO_DEPRECATED)
-check_cxx_compiler_flag (-Wunnamed-type-template-args
-    HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS)
-
-cmake_push_check_state (RESET)
-
-if (Threads_FOUND)
-  set (CMAKE_REQUIRED_LIBRARIES Threads::Threads)
-endif (Threads_FOUND)
-
-check_cxx_symbol_exists (pthread_threadid_np "pthread.h" HAVE_PTHREAD_THREADID_NP)
-cmake_pop_check_state ()
-
-# NOTE: Cannot use check_function_exists here since >=vc-14.0 can define
-# snprintf as an inline function
-check_cxx_symbol_exists (snprintf cstdio HAVE_SNPRINTF)
-
-check_library_exists (dbghelp UnDecorateSymbolName "" HAVE_DBGHELP)
-
-check_cxx_source_compiles ("
-#include <cstdlib>
-static void foo(void) __attribute__ ((unused));
-int main(void) { return 0; }
-" HAVE___ATTRIBUTE__)
-
-check_cxx_source_compiles ("
-#include <cstdlib>
-static void foo(void) __attribute__ ((visibility(\"default\")));
-int main(void) { return 0; }
-" HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
-
-check_cxx_source_compiles ("
-#include <cstdlib>
-static void foo(void) __attribute__ ((visibility(\"hidden\")));
-int main(void) { return 0; }
-" HAVE___ATTRIBUTE__VISIBILITY_HIDDEN)
-
-check_cxx_source_compiles ("
-int main(void) { if (__builtin_expect(0, 0)) return 1; return 0; }
-" HAVE___BUILTIN_EXPECT)
-
-check_cxx_source_compiles ("
-int main(void)
-{
-  int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0;
-}
-" HAVE___SYNC_VAL_COMPARE_AND_SWAP)
-
-if (Threads_FOUND)
-  cmake_push_check_state (RESET)
-  set (CMAKE_REQUIRED_LIBRARIES Threads::Threads)
-  check_cxx_source_compiles ("
-#define _XOPEN_SOURCE 500
-#include <pthread.h>
-int main(void)
-{
-  pthread_rwlock_t l;
-  pthread_rwlock_init(&l, NULL);
-  pthread_rwlock_rdlock(&l);
-  return 0;
-}
-  " HAVE_RWLOCK)
-  cmake_pop_check_state ()
-endif (Threads_FOUND)
-
-check_cxx_source_compiles ("
-__declspec(selectany) int a;
-int main(void) { return 0; }
-" HAVE___DECLSPEC)
-
-check_cxx_source_compiles ("
-#include <vector>
-vector<int> t; int main() { }
-" STL_NO_NAMESPACE)
-
-check_cxx_source_compiles ("
-#include <vector>
-std::vector<int> t; int main() { }
-" STL_STD_NAMESPACE)
-
-check_cxx_source_compiles ("
-#include <iostream>
-std::ostream& operator<<(std::ostream&, struct s);
-using ::operator<<;
-int main() { }
-" HAVE_USING_OPERATOR)
-
-check_cxx_source_compiles ("
-namespace Outer { namespace Inner { int i = 0; }}
-using namespace Outer::Inner;;
-int main() { return i; }
-" HAVE_NAMESPACES)
-
-check_cxx_source_compiles ("
-__thread int tls;
-int main() { }
-" HAVE_GCC_TLS)
-
-check_cxx_source_compiles ("
-__declspec(thread) int tls;
-int main() { }
-" HAVE_MSVC_TLS)
-
-check_cxx_source_compiles ("
-thread_local int tls;
-int main() { }
-" HAVE_CXX11_TLS)
-
-check_cxx_source_compiles ("
-#include <type_traits>
-std::aligned_storage<sizeof(char), alignof(char)>::type data;
-int main() { }
-" HAVE_ALIGNED_STORAGE)
-
-check_cxx_source_compiles ("
-#include <atomic>
-std::atomic<int> i;
-int main() { }
-" HAVE_CXX11_ATOMIC)
-
-check_cxx_source_compiles ("
-constexpr int x = 0;
-int main() { }
-" HAVE_CXX11_CONSTEXPR)
-
-check_cxx_source_compiles ("
-#include <chrono>
-std::chrono::seconds s;
-int main() { }
-" HAVE_CXX11_CHRONO)
-
-check_cxx_source_compiles ("
-#include <cstddef>
-void foo(std::nullptr_t) {}
-int main(void) { foo(nullptr); }
-" HAVE_CXX11_NULLPTR_T)
-
-if (WITH_TLS)
-  # Cygwin does not support the thread attribute. Don't bother.
-  if (HAVE_GCC_TLS)
-    set (GLOG_THREAD_LOCAL_STORAGE "__thread")
-  elseif (HAVE_MSVC_TLS)
-    set (GLOG_THREAD_LOCAL_STORAGE "__declspec(thread)")
-  elseif (HAVE_CXX11_TLS)
-    set (GLOG_THREAD_LOCAL_STORAGE thread_local)
-  endif (HAVE_GCC_TLS)
-endif (WITH_TLS)
-
-set (_PC_FIELDS
-  "gregs[REG_PC]"
-  "gregs[REG_EIP]"
-  "gregs[REG_RIP]"
-  "sc_ip"
-  "uc_regs->gregs[PT_NIP]"
-  "gregs[R15]"
-  "arm_pc"
-  "mc_eip"
-  "mc_rip"
-  "__gregs[REG_EIP]"
-  "__gregs[REG_RIP]"
-  "ss.eip"
-  "__ss.__eip"
-  "ss.rip"
-  "__ss.__rip"
-  "ss.srr0"
-  "__ss.__srr0"
-)
-
-set (_PC_HEADERS ucontext.h signal.h)
-
-if (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
-  foreach (_PC_FIELD ${_PC_FIELDS})
-    foreach (_PC_HEADER ${_PC_HEADERS})
-      set (_TMP
-      ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/uctfield.cpp)
-      file (WRITE ${_TMP} "
-#define _GNU_SOURCE 1
-#include <${_PC_HEADER}>
-int main(void)
-{
-  ucontext_t u;
-  return u.${_PC_FIELD} == 0;
-}
-")
-      try_compile (HAVE_PC_FROM_UCONTEXT ${CMAKE_CURRENT_BINARY_DIR} ${_TMP}
-        COMPILE_DEFINITIONS _GNU_SOURCE=1)
-
-      if (HAVE_PC_FROM_UCONTEXT)
-        set (PC_FROM_UCONTEXT ${_PC_FIELD} CACHE)
-      endif (HAVE_PC_FROM_UCONTEXT)
-    endforeach (_PC_HEADER)
-  endforeach (_PC_FIELD)
-endif  (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
-
-if (STL_STD_NAMESPACE)
-  set (STL_NAMESPACE std)
-else (STL_STD_NAMESPACE)
-  set (STL_NAMESPACE "")
-endif (STL_STD_NAMESPACE)
-
-set (GOOGLE_NAMESPACE google)
-set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {")
-set (_END_GOOGLE_NAMESPACE_ "}")
-set (ac_cv_have_glog_export 1)
-
-if (HAVE___UINT16)
-  set (ac_cv_have___uint16 1)
-else (HAVE___UINT16)
-  set (ac_cv_have___uint16 0)
-endif (HAVE___UINT16)
-
-if (HAVE_INTTYPES_H)
-  set (ac_cv_have_inttypes_h 1)
-else (HAVE_INTTYPES_H)
-  set (ac_cv_have_inttypes_h 0)
-endif (HAVE_INTTYPES_H)
-
-if (HAVE_LIB_GFLAGS)
-  set (ac_cv_have_libgflags 1)
-else (HAVE_LIB_GFLAGS)
-  set (ac_cv_have_libgflags 0)
-endif (HAVE_LIB_GFLAGS)
-
-if (HAVE_STDINT_H)
-  set (ac_cv_have_stdint_h 1)
-else (HAVE_STDINT_H)
-  set (ac_cv_have_stdint_h 0)
-endif (HAVE_STDINT_H)
-
-if (HAVE_SYS_TYPES_H)
-  set (ac_cv_have_systypes_h 1)
-else (HAVE_SYS_TYPES_H)
-  set (ac_cv_have_systypes_h 0)
-endif (HAVE_SYS_TYPES_H)
-
-if (HAVE_U_INT16_T)
-  set (ac_cv_have_u_int16_t 1)
-else (HAVE_U_INT16_T)
-  set (ac_cv_have_u_int16_t 0)
-endif (HAVE_U_INT16_T)
-
-if (HAVE_UINT16_T)
-  set (ac_cv_have_uint16_t 1)
-else (HAVE_UINT16_T)
-  set (ac_cv_have_uint16_t 0)
-endif (HAVE_UINT16_T)
-
-if (HAVE_SSIZE_T)
-  set (ac_cv_have_ssize_t 1)
-else (HAVE_SSIZE_T)
-  set (ac_cv_have_ssize_t 0)
-endif (HAVE_SSIZE_T)
-
-if (HAVE_MODE_T)
-  set (ac_cv_have_mode_t 1)
-else (HAVE_MODE_T)
-  set (ac_cv_have_mode_t 0)
-endif (HAVE_MODE_T)
-
-if (HAVE_UNISTD_H)
-  set (ac_cv_have_unistd_h 1)
-else (HAVE_UNISTD_H)
-  set (ac_cv_have_unistd_h 0)
-endif (HAVE_UNISTD_H)
-
-set (ac_google_namespace ${GOOGLE_NAMESPACE})
-set (ac_google_end_namespace ${_END_GOOGLE_NAMESPACE_})
-set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_})
-
-if (HAVE___ATTRIBUTE__)
-  set (ac_cv___attribute___noreturn "__attribute__((noreturn))")
-  set (ac_cv___attribute___noinline "__attribute__((noinline))")
-  set (ac_cv___attribute___printf_4_5 "__attribute__((__format__(__printf__, 4, 5)))")
-elseif (HAVE___DECLSPEC)
-  set (ac_cv___attribute___noreturn "__declspec(noreturn)")
-  #set (ac_cv___attribute___noinline "__declspec(noinline)")
-endif (HAVE___ATTRIBUTE__)
-
-if (HAVE___BUILTIN_EXPECT)
-  set (ac_cv_have___builtin_expect 1)
-else (HAVE___BUILTIN_EXPECT)
-  set (ac_cv_have___builtin_expect 0)
-endif (HAVE___BUILTIN_EXPECT)
-
-if (HAVE_USING_OPERATOR)
-  set (ac_cv_cxx_using_operator 1)
-else (HAVE_USING_OPERATOR)
-  set (ac_cv_cxx_using_operator 0)
-endif (HAVE_USING_OPERATOR)
-
-if (HAVE_CXX11_CONSTEXPR)
-  set (ac_cv_cxx11_constexpr 1)
-else (HAVE_CXX11_CONSTEXPR)
-  set (ac_cv_cxx11_constexpr 0)
-endif (HAVE_CXX11_CONSTEXPR)
-
-if (HAVE_CXX11_CHRONO)
-  set (ac_cv_cxx11_chrono 1)
-else (HAVE_CXX11_CHRONO)
-  set (ac_cv_cxx11_chrono 0)
-endif (HAVE_CXX11_CHRONO)
-
-if (HAVE_CXX11_NULLPTR_T)
-  set (ac_cv_cxx11_nullptr_t 1)
-else (HAVE_CXX11_NULLPTR_T)
-  set (ac_cv_cxx11_nullptr_t 0)
-endif (HAVE_CXX11_NULLPTR_T)
-
-if (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
-  set (HAVE_STACKTRACE 1)
-endif (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
-
-if (HAVE_CXX11_ATOMIC)
-  set (ac_cv_cxx11_atomic 1)
-else (HAVE_CXX11_ATOMIC)
-  set (ac_cv_cxx11_atomic 0)
-endif (HAVE_CXX11_ATOMIC)
-
-if (WITH_SYMBOLIZE)
-  if (WIN32 OR CYGWIN)
-    cmake_push_check_state (RESET)
-    set (CMAKE_REQUIRED_LIBRARIES DbgHelp)
-
-    check_cxx_source_runs ([=[
-    #include <windows.h>
-    #include <dbghelp.h>
-    #include <cstdlib>
-
-    void foobar() { }
-
-    int main()
-    {
-        HANDLE process = GetCurrentProcess();
-
-        if (!SymInitialize(process, NULL, TRUE))
-            return EXIT_FAILURE;
-
-        char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
-        SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(buf);
-        symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
-        symbol->MaxNameLen = MAX_SYM_NAME;
-
-        void* const pc = reinterpret_cast<void*>(&foobar);
-        BOOL ret = SymFromAddr(process, reinterpret_cast<DWORD64>(pc), 0, symbol);
-
-        return ret ? EXIT_SUCCESS : EXIT_FAILURE;
-    }
-    ]=] HAVE_SYMBOLIZE)
-
-    cmake_pop_check_state ()
-
-    if (HAVE_SYMBOLIZE)
-      set (HAVE_STACKTRACE 1)
-    endif (HAVE_SYMBOLIZE)
-  elseif (UNIX OR (APPLE AND HAVE_DLADDR))
-    set (HAVE_SYMBOLIZE 1)
-  endif (WIN32 OR CYGWIN)
-endif (WITH_SYMBOLIZE)
-
-# CMake manages symbolize availability. The definition is necessary only when
-# building the library. Switch to add_compile_definitions once we drop support
-# for CMake below version 3.12.
-add_definitions (-DGLOG_NO_SYMBOLIZE_DETECTION)
-
-check_cxx_source_compiles ("
-#include <cstdlib>
-#include <ctime>
-int main()
-{
-    time_t timep;
-    struct tm result;
-    localtime_r(&timep, &result);
-    return EXIT_SUCCESS;
-}
-" HAVE_LOCALTIME_R)
-
-set (SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
-
-if (WITH_THREADS AND Threads_FOUND)
-  if (CMAKE_USE_PTHREADS_INIT)
-    set (HAVE_PTHREAD 1)
-  endif (CMAKE_USE_PTHREADS_INIT)
-else (WITH_THREADS AND Threads_FOUND)
-  set (NO_THREADS 1)
-endif (WITH_THREADS AND Threads_FOUND)
-
-# fopen/open on Cygwin can not handle unix-type paths like /home/....
-# therefore we translate TEST_SRC_DIR to windows-path.
-if (CYGWIN)
-  execute_process (COMMAND cygpath.exe -m ${CMAKE_CURRENT_SOURCE_DIR}
-                   OUTPUT_STRIP_TRAILING_WHITESPACE
-                   OUTPUT_VARIABLE TEST_SRC_DIR)
-  set (TEST_SRC_DIR \"${TEST_SRC_DIR}\")
-else (CYGWIN)
-  set (TEST_SRC_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\")
-endif (CYGWIN)
-
-configure_file (src/config.h.cmake.in config.h)
-configure_file (src/glog/logging.h.in glog/logging.h @ONLY)
-configure_file (src/glog/raw_logging.h.in glog/raw_logging.h @ONLY)
-configure_file (src/glog/stl_logging.h.in glog/stl_logging.h @ONLY)
-configure_file (src/glog/vlog_is_on.h.in glog/vlog_is_on.h @ONLY)
-
-add_compile_options ($<$<AND:$<BOOL:${HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS}>,$<NOT:$<CXX_COMPILER_ID:GNU>>>:-Wno-unnamed-type-template-args>)
-
-set (_glog_CMake_BINDIR ${CMAKE_INSTALL_BINDIR})
-set (_glog_CMake_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
-set (_glog_CMake_LIBDIR ${CMAKE_INSTALL_LIBDIR})
-set (_glog_CMake_INSTALLDIR ${_glog_CMake_LIBDIR}/cmake/glog)
-
-set (_glog_CMake_DIR glog/cmake)
-set (_glog_CMake_DATADIR ${CMAKE_INSTALL_DATAROOTDIR}/${_glog_CMake_DIR})
-set (_glog_BINARY_CMake_DATADIR
-  ${CMAKE_CURRENT_BINARY_DIR}/${_glog_CMake_DATADIR})
-
-# Add additional CMake find modules here.
-set (_glog_CMake_MODULES)
-
-if (Unwind_FOUND)
-  # Copy the module only if libunwind is actually used.
-  list (APPEND _glog_CMake_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindUnwind.cmake)
-endif (Unwind_FOUND)
-
-# Generate file name for each module in the binary directory
-foreach (_file ${_glog_CMake_MODULES})
-  get_filename_component (_module "${_file}" NAME)
-
-  list (APPEND _glog_BINARY_CMake_MODULES
-    ${_glog_BINARY_CMake_DATADIR}/${_module})
-endforeach (_file)
-
-if (_glog_CMake_MODULES)
-  # Copy modules to binary directory during the build
-  add_custom_command (OUTPUT ${_glog_BINARY_CMake_MODULES}
-    COMMAND ${CMAKE_COMMAND} -E make_directory
-    ${_glog_BINARY_CMake_DATADIR}
-    COMMAND ${CMAKE_COMMAND} -E copy ${_glog_CMake_MODULES}
-    ${_glog_BINARY_CMake_DATADIR}
-    DEPENDS ${_glog_CMake_MODULES}
-    COMMENT "Copying find modules..."
-  )
-endif (_glog_CMake_MODULES)
-
-set (GLOG_PUBLIC_H
-  ${CMAKE_CURRENT_BINARY_DIR}/glog/export.h
-  ${CMAKE_CURRENT_BINARY_DIR}/glog/logging.h
-  ${CMAKE_CURRENT_BINARY_DIR}/glog/raw_logging.h
-  ${CMAKE_CURRENT_BINARY_DIR}/glog/stl_logging.h
-  ${CMAKE_CURRENT_BINARY_DIR}/glog/vlog_is_on.h
-  src/glog/log_severity.h
-  src/glog/platform.h
-)
-
-set (GLOG_SRCS
-  ${GLOG_PUBLIC_H}
-  src/base/commandlineflags.h
-  src/base/googleinit.h
-  src/base/mutex.h
-  src/demangle.cc
-  src/demangle.h
-  src/logging.cc
-  src/raw_logging.cc
-  src/symbolize.cc
-  src/symbolize.h
-  src/utilities.cc
-  src/utilities.h
-  src/vlog_is_on.cc
-)
-
-if (HAVE_PTHREAD OR WIN32 OR CYGWIN)
-  list (APPEND GLOG_SRCS src/signalhandler.cc)
-endif (HAVE_PTHREAD OR WIN32 OR CYGWIN)
-
-if (CYGWIN OR WIN32)
-  list (APPEND GLOG_SRCS
-    src/windows/port.cc
-    src/windows/port.h
-  )
-endif (CYGWIN OR WIN32)
-
-add_library (glogbase OBJECT
-  ${_glog_BINARY_CMake_MODULES}
-  ${GLOG_SRCS}
-)
-
-add_library (glog
-  $<TARGET_OBJECTS:glogbase>
-)
-
-add_library (glog::glog ALIAS glog)
-
-set (glog_libraries_options_for_static_linking)
-
-if (Unwind_FOUND)
-  target_link_libraries (glog PRIVATE unwind::unwind)
-  set (glog_libraries_options_for_static_linking "${glog_libraries_options_for_static_linking} -lunwind")
-  set (Unwind_DEPENDENCY "find_dependency (Unwind ${Unwind_VERSION})")
-endif (Unwind_FOUND)
-
-if (HAVE_DBGHELP)
-  target_link_libraries (glog PRIVATE dbghelp)
-  set (glog_libraries_options_for_static_linking "${glog_libraries_options_for_static_linking} -ldbghelp")
-endif (HAVE_DBGHELP)
-
-if (HAVE_PTHREAD)
-  target_link_libraries (glog PRIVATE ${CMAKE_THREAD_LIBS_INIT})
-
-  if (CMAKE_THREAD_LIBS_INIT)
-    set (glog_libraries_options_for_static_linking "${glog_libraries_options_for_static_linking} ${CMAKE_THREAD_LIBS_INIT}")
-  endif (CMAKE_THREAD_LIBS_INIT)
-endif (HAVE_PTHREAD)
-
-if (gflags_FOUND)
-  # Prefer the gflags target that uses double colon convention
-  if (TARGET gflags::gflags)
-    target_link_libraries (glog PUBLIC gflags::gflags)
-  else (TARGET gflags::gflags)
-    target_link_libraries (glog PUBLIC gflags)
-  endif (TARGET gflags::gflags)
-
-  set (glog_libraries_options_for_static_linking "${glog_libraries_options_for_static_linking} -lgflags")
-endif (gflags_FOUND)
-
-if (ANDROID)
-  target_link_libraries (glog PRIVATE log)
-  set (glog_libraries_options_for_static_linking "${glog_libraries_options_for_static_linking} -llog")
-endif (ANDROID)
-
-set_target_properties (glog PROPERTIES VERSION ${PROJECT_VERSION})
-set_target_properties (glog PROPERTIES SOVERSION 1)
-
-if (CYGWIN OR WIN32)
-  target_compile_definitions (glog PUBLIC GLOG_NO_ABBREVIATED_SEVERITIES)
-endif (CYGWIN OR WIN32)
-
-if (WITH_CUSTOM_PREFIX)
-  target_compile_definitions (glog PUBLIC GLOG_CUSTOM_PREFIX_SUPPORT)
-endif (WITH_CUSTOM_PREFIX)
-
-set_target_properties (glog PROPERTIES PUBLIC_HEADER "${GLOG_PUBLIC_H}")
-
-target_include_directories (glog BEFORE PUBLIC
-  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
-  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
-  "$<INSTALL_INTERFACE:${_glog_CMake_INCLUDE_DIR}>"
-  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
-
-if (CYGWIN OR WIN32)
-  target_include_directories (glogbase PUBLIC
-    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/windows>"
-    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/windows)
-
-  target_include_directories (glog PUBLIC
-    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/windows>"
-    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/windows)
-endif (CYGWIN OR WIN32)
-
-set_target_properties (glog PROPERTIES DEFINE_SYMBOL GOOGLE_GLOG_IS_A_DLL)
-
-target_include_directories (glogbase PUBLIC
-  $<TARGET_PROPERTY:glog,INCLUDE_DIRECTORIES>)
-target_compile_definitions (glogbase PUBLIC
-  $<TARGET_PROPERTY:glog,COMPILE_DEFINITIONS>
-  PRIVATE GOOGLE_GLOG_IS_A_DLL)
-
-generate_export_header (glog
-  EXPORT_MACRO_NAME GLOG_EXPORT
-  EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/glog/export.h)
-
-string (STRIP "${glog_libraries_options_for_static_linking}" glog_libraries_options_for_static_linking)
-
-if (WITH_PKGCONFIG)
-  set (VERSION ${PROJECT_VERSION})
-  set (prefix ${CMAKE_INSTALL_PREFIX})
-  set (exec_prefix ${CMAKE_INSTALL_FULL_BINDIR})
-  set (libdir ${CMAKE_INSTALL_FULL_LIBDIR})
-  set (includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
-
-  configure_file (
-    "${PROJECT_SOURCE_DIR}/libglog.pc.in"
-    "${PROJECT_BINARY_DIR}/libglog.pc"
-    @ONLY
-  )
-
-  unset (VERSION)
-  unset (prefix)
-  unset (exec_prefix)
-  unset (libdir)
-  unset (includedir)
-endif (WITH_PKGCONFIG)
-
-# Unit testing
-
-if (BUILD_TESTING)
-  add_library (glogtest STATIC
-    $<TARGET_OBJECTS:glogbase>
-  )
-
-  target_include_directories (glogtest PUBLIC
-    $<TARGET_PROPERTY:glog,INCLUDE_DIRECTORIES>)
-  target_compile_definitions (glogtest PUBLIC
-    $<TARGET_PROPERTY:glog,COMPILE_DEFINITIONS> GLOG_STATIC_DEFINE)
-  target_link_libraries (glogtest PUBLIC
-    $<TARGET_PROPERTY:glog,LINK_LIBRARIES>)
-
-  set (_GLOG_TEST_LIBS glogtest)
-
-  if (HAVE_LIB_GTEST)
-    list (APPEND _GLOG_TEST_LIBS GTest::gtest)
-  endif (HAVE_LIB_GTEST)
-
-  if (HAVE_LIB_GMOCK)
-    list (APPEND _GLOG_TEST_LIBS GTest::gmock)
-  endif (HAVE_LIB_GMOCK)
-
-  add_executable (logging_unittest
-    src/logging_unittest.cc
-  )
-
-  target_link_libraries (logging_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  if (WITH_CUSTOM_PREFIX)
-    add_executable (logging_custom_prefix_unittest
-      src/logging_custom_prefix_unittest.cc
-    )
-
-    target_link_libraries (logging_custom_prefix_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-    add_test (NAME logging_custom_prefix
-              COMMAND logging_custom_prefix_unittest)
-
-    # FIXME: Skip flaky test
-    set_tests_properties (logging_custom_prefix PROPERTIES SKIP_REGULAR_EXPRESSION
-      "Check failed: time_ns within LogTimes::LOG_PERIOD_TOL_NS of LogTimes::LOG_PERIOD_NS")
-
-    if (APPLE)
-      # FIXME: Skip flaky test
-      set_property (TEST logging_custom_prefix APPEND PROPERTY SKIP_REGULAR_EXPRESSION
-        "unexpected new.*PASS\nTest with golden file failed. We'll try to show the diff:")
-    endif (APPLE)
-  endif (WITH_CUSTOM_PREFIX)
-
-  add_executable (stl_logging_unittest
-    src/stl_logging_unittest.cc
-  )
-
-  target_link_libraries (stl_logging_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  if (HAVE_NO_DEPRECATED)
-    set_property (TARGET stl_logging_unittest APPEND PROPERTY COMPILE_OPTIONS
-      -Wno-deprecated)
-  endif (HAVE_NO_DEPRECATED)
-
-  if (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
-    target_compile_definitions (stl_logging_unittest PRIVATE
-      GLOG_STL_LOGGING_FOR_UNORDERED)
-  endif (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
-
-  if (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
-    target_compile_definitions (stl_logging_unittest PRIVATE
-      GLOG_STL_LOGGING_FOR_TR1_UNORDERED)
-  endif (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
-
-  if (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
-    target_compile_definitions (stl_logging_unittest PRIVATE
-      GLOG_STL_LOGGING_FOR_EXT_HASH)
-  endif (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
-
-  if (HAVE_EXT_SLIST)
-    target_compile_definitions (stl_logging_unittest PRIVATE
-      GLOG_STL_LOGGING_FOR_EXT_SLIST)
-  endif (HAVE_EXT_SLIST)
-
-  if (HAVE_SYMBOLIZE)
-    add_executable (symbolize_unittest
-      src/symbolize_unittest.cc
-    )
-
-    target_link_libraries (symbolize_unittest PRIVATE ${_GLOG_TEST_LIBS})
-  endif (HAVE_SYMBOLIZE)
-
-  add_executable (demangle_unittest
-    src/demangle_unittest.cc
-  )
-
-  target_link_libraries (demangle_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  if (HAVE_STACKTRACE)
-    add_executable (stacktrace_unittest
-      src/stacktrace_unittest.cc
-    )
-
-    target_link_libraries (stacktrace_unittest PRIVATE ${_GLOG_TEST_LIBS})
-  endif (HAVE_STACKTRACE)
-
-  add_executable (utilities_unittest
-    src/utilities_unittest.cc
-  )
-
-  target_link_libraries (utilities_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  if (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
-    add_executable (signalhandler_unittest
-      src/signalhandler_unittest.cc
-    )
-
-    target_link_libraries (signalhandler_unittest PRIVATE ${_GLOG_TEST_LIBS})
-  endif (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
-
-  add_test (NAME demangle COMMAND demangle_unittest)
-  add_test (NAME logging COMMAND logging_unittest)
-
-  set_tests_properties (logging PROPERTIES TIMEOUT 30)
-  # MacOS diff is not deterministic: use the output to determine whether the
-  # test passed.
-  set_tests_properties (logging PROPERTIES PASS_REGULAR_EXPRESSION ".*\nPASS\n.*")
-
-  # FIXME: Skip flaky test
-  set_tests_properties (logging PROPERTIES SKIP_REGULAR_EXPRESSION
-    "Check failed: time_ns within LogTimes::LOG_PERIOD_TOL_NS of LogTimes::LOG_PERIOD_NS")
-
-  if (APPLE)
-    # FIXME: Skip flaky test
-    set_property (TEST logging APPEND PROPERTY SKIP_REGULAR_EXPRESSION
-      "unexpected new.*PASS\nTest with golden file failed. We'll try to show the diff:")
-  endif (APPLE)
-
-  if (TARGET signalhandler_unittest)
-    add_test (NAME signalhandler COMMAND signalhandler_unittest)
-  endif (TARGET signalhandler_unittest)
-
-  if (TARGET stacktrace_unittest)
-    add_test (NAME stacktrace COMMAND stacktrace_unittest)
-    set_tests_properties (stacktrace PROPERTIES TIMEOUT 30)
-  endif (TARGET stacktrace_unittest)
-
-  add_test (NAME stl_logging COMMAND stl_logging_unittest)
-
-  if (TARGET symbolize_unittest)
-    add_test (NAME symbolize COMMAND symbolize_unittest)
-  endif (TARGET symbolize_unittest)
-
-  if (HAVE_LIB_GMOCK)
-    add_executable (mock-log_unittest
-      src/mock-log_unittest.cc
-      src/mock-log.h
-    )
-
-    target_link_libraries (mock-log_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-    add_test (NAME mock-log COMMAND mock-log_unittest)
-  endif (HAVE_LIB_GMOCK)
-
-  # Generate an initial cache
-
-  get_cache_variables (_CACHEVARS)
-
-  set (_INITIAL_CACHE
-    ${CMAKE_CURRENT_BINARY_DIR}/test_package_config/glog_package_config_initial_cache.cmake)
-
-  # Package config test
-
-  add_test (NAME cmake_package_config_init COMMAND ${CMAKE_COMMAND}
-    -DTEST_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/test_package_config
-    -DINITIAL_CACHE=${_INITIAL_CACHE}
-    -DCACHEVARS=${_CACHEVARS}
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TestInitPackageConfig.cmake
-  )
-
-  add_test (NAME cmake_package_config_generate COMMAND ${CMAKE_COMMAND}
-    -DGENERATOR=${CMAKE_GENERATOR}
-    -DGENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
-    -DGENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
-    -DINITIAL_CACHE=${_INITIAL_CACHE}
-    -DPACKAGE_DIR=${CMAKE_CURRENT_BINARY_DIR}
-    -DPATH=$ENV{PATH}
-    -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/src/package_config_unittest/working_config
-    -DTEST_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/test_package_config/working_config
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TestPackageConfig.cmake
-  )
-
-  add_test (NAME cmake_package_config_build COMMAND
-    ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/test_package_config/working_config
-                     --config $<CONFIG>
-  )
-
-  add_test (NAME cmake_package_config_cleanup COMMAND ${CMAKE_COMMAND} -E
-    remove_directory
-    ${CMAKE_CURRENT_BINARY_DIR}/test_package_config
-  )
-
-  # Fixtures setup
-  set_tests_properties (cmake_package_config_init PROPERTIES FIXTURES_SETUP
-    cmake_package_config)
-  set_tests_properties (cmake_package_config_generate PROPERTIES FIXTURES_SETUP
-    cmake_package_config_working)
-
-  # Fixtures cleanup
-  set_tests_properties (cmake_package_config_cleanup PROPERTIES FIXTURES_CLEANUP
-    cmake_package_config)
-
-  # Fixture requirements
-  set_tests_properties (cmake_package_config_generate PROPERTIES
-    FIXTURES_REQUIRED cmake_package_config)
-  set_tests_properties (cmake_package_config_build PROPERTIES
-    FIXTURES_REQUIRED "cmake_package_config;cmake_package_config_working")
-
-  add_executable (cleanup_immediately_unittest
-    src/cleanup_immediately_unittest.cc)
-
-  target_link_libraries (cleanup_immediately_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  add_executable (cleanup_with_absolute_prefix_unittest
-    src/cleanup_with_absolute_prefix_unittest.cc)
-
-  target_link_libraries (cleanup_with_absolute_prefix_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  add_executable (cleanup_with_relative_prefix_unittest
-    src/cleanup_with_relative_prefix_unittest.cc)
-
-  target_link_libraries (cleanup_with_relative_prefix_unittest PRIVATE ${_GLOG_TEST_LIBS})
-
-  set (CLEANUP_LOG_DIR ${CMAKE_CURRENT_BINARY_DIR}/cleanup_tests)
-
-  add_test (NAME cleanup_init COMMAND
-    ${CMAKE_COMMAND} -E make_directory ${CLEANUP_LOG_DIR})
-  add_test (NAME cleanup_logdir COMMAND
-    ${CMAKE_COMMAND} -E remove_directory ${CLEANUP_LOG_DIR})
-  add_test (NAME cleanup_immediately COMMAND
-    ${CMAKE_COMMAND}
-    -DLOGCLEANUP=$<TARGET_FILE:cleanup_immediately_unittest>
-    # NOTE The trailing slash is important
-    -DTEST_DIR=${CLEANUP_LOG_DIR}/
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunCleanerTest1.cmake
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-  add_test (NAME cleanup_with_absolute_prefix COMMAND
-    ${CMAKE_COMMAND}
-    -DLOGCLEANUP=$<TARGET_FILE:cleanup_with_absolute_prefix_unittest>
-    -DTEST_DIR=${CMAKE_CURRENT_BINARY_DIR}/
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunCleanerTest2.cmake
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-  add_test (NAME cleanup_with_relative_prefix COMMAND
-    ${CMAKE_COMMAND}
-    -DLOGCLEANUP=$<TARGET_FILE:cleanup_with_relative_prefix_unittest>
-    -DTEST_DIR=${CMAKE_CURRENT_BINARY_DIR}/
-    -DTEST_SUBDIR=test_subdir/
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunCleanerTest3.cmake
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
-  # Fixtures setup
-  set_tests_properties (cleanup_init PROPERTIES FIXTURES_SETUP logcleanuptest)
-  ## Fixtures cleanup
-  set_tests_properties (cleanup_logdir PROPERTIES FIXTURES_CLEANUP logcleanuptest)
-  # Fixture requirements
-  set_tests_properties (cleanup_immediately PROPERTIES FIXTURES_REQUIRED logcleanuptest)
-  set_tests_properties (cleanup_with_absolute_prefix PROPERTIES FIXTURES_REQUIRED logcleanuptest)
-  set_tests_properties (cleanup_with_relative_prefix PROPERTIES FIXTURES_REQUIRED logcleanuptest)
-endif (BUILD_TESTING)
-
-install (TARGETS glog
-  EXPORT glog-targets
-  RUNTIME DESTINATION ${_glog_CMake_BINDIR}
-  PUBLIC_HEADER DESTINATION ${_glog_CMake_INCLUDE_DIR}/glog
-  LIBRARY DESTINATION ${_glog_CMake_LIBDIR}
-  ARCHIVE DESTINATION ${_glog_CMake_LIBDIR})
-
-if (WITH_PKGCONFIG)
-  install (
-    FILES "${PROJECT_BINARY_DIR}/libglog.pc"
-    DESTINATION "${_glog_CMake_LIBDIR}/pkgconfig"
-  )
-endif (WITH_PKGCONFIG)
-
-set (glog_CMake_VERSION 3.0)
-
-if (gflags_FOUND)
-  # Ensure clients locate only the package config and not third party find
-  # modules having the same name. This avoid cmake_policy PUSH/POP errors.
-  if (CMAKE_VERSION VERSION_LESS 3.9)
-    set (gflags_DEPENDENCY "find_dependency (gflags ${gflags_VERSION})")
-  else (CMAKE_VERSION VERSION_LESS 3.9)
-    # Passing additional find_package arguments to find_dependency is possible
-    # starting with CMake 3.9.
-    set (glog_CMake_VERSION 3.9)
-    set (gflags_DEPENDENCY "find_dependency (gflags ${gflags_VERSION} NO_MODULE)")
-  endif (CMAKE_VERSION VERSION_LESS 3.9)
-endif (gflags_FOUND)
-
-configure_package_config_file (glog-config.cmake.in
-  ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
-  INSTALL_DESTINATION ${_glog_CMake_INSTALLDIR}
-  NO_CHECK_REQUIRED_COMPONENTS_MACRO)
-
-write_basic_package_version_file (
-  ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake
-  COMPATIBILITY SameMajorVersion)
-
-export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake)
-export (PACKAGE glog)
-
-get_filename_component (_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
-
-# Directory containing the find modules relative to the config install
-# directory.
-file (RELATIVE_PATH glog_REL_CMake_MODULES
-  ${_PREFIX}/${_glog_CMake_INSTALLDIR}
-  ${_PREFIX}/${_glog_CMake_DATADIR}/glog-modules.cmake)
-
-get_filename_component (glog_REL_CMake_DATADIR ${glog_REL_CMake_MODULES}
-  DIRECTORY)
-
-set (glog_FULL_CMake_DATADIR
-  ${CMAKE_CURRENT_BINARY_DIR}/${_glog_CMake_DATADIR})
-
-configure_file (glog-modules.cmake.in
-  ${CMAKE_CURRENT_BINARY_DIR}/glog-modules.cmake @ONLY)
-
-install (CODE
-"
-set (glog_FULL_CMake_DATADIR \"\\\${CMAKE_CURRENT_LIST_DIR}/${glog_REL_CMake_DATADIR}\")
-set (glog_DATADIR_DESTINATION ${_glog_CMake_INSTALLDIR})
-
-if (NOT IS_ABSOLUTE ${_glog_CMake_INSTALLDIR})
-  set (glog_DATADIR_DESTINATION \"\${CMAKE_INSTALL_PREFIX}/\${glog_DATADIR_DESTINATION}\")
-endif (NOT IS_ABSOLUTE ${_glog_CMake_INSTALLDIR})
-
-configure_file (\"${CMAKE_CURRENT_SOURCE_DIR}/glog-modules.cmake.in\"
-  \"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/glog-modules.cmake\" @ONLY)
-file (INSTALL
-  \"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/glog-modules.cmake\"
-  DESTINATION
-  \"\${glog_DATADIR_DESTINATION}\")
-"
-  COMPONENT Development
-)
-
-install (FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
-  ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake
-  DESTINATION ${_glog_CMake_INSTALLDIR})
-
-# Find modules in share/glog/cmake
-install (DIRECTORY ${_glog_BINARY_CMake_DATADIR}
-  DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/glog
-  COMPONENT Development
-  FILES_MATCHING PATTERN "*.cmake"
-)
-
-install (EXPORT glog-targets NAMESPACE glog:: DESTINATION
-  ${_glog_CMake_INSTALLDIR})
diff --git a/third_party/google-glog/CONTRIBUTORS b/third_party/google-glog/CONTRIBUTORS
deleted file mode 100644
index 05cb688..0000000
--- a/third_party/google-glog/CONTRIBUTORS
+++ /dev/null
@@ -1,52 +0,0 @@
-# People who have agreed to one of the CLAs and can contribute patches.
-# The AUTHORS file lists the copyright holders; this file
-# lists people.  For example, Google employees are listed here
-# but not in AUTHORS, because Google holds the copyright.
-#
-# Names should be added to this file only after verifying that
-# the individual or the individual's organization has agreed to
-# the appropriate Contributor License Agreement, found here:
-#
-# https://developers.google.com/open-source/cla/individual
-# https://developers.google.com/open-source/cla/corporate
-#
-# The agreement for individuals can be filled out on the web.
-#
-# When adding J Random Contributor's name to this file,
-# either J's name or J's organization's name should be
-# added to the AUTHORS file, depending on whether the
-# individual or corporate CLA was used.
-#
-# Names should be added to this file as:
-#     Name <email address>
-#
-# Please keep the list sorted.
-
-Abhishek Dasgupta <abhi2743@gmail.com>
-Abhishek Parmar <abhishek@orng.net>
-Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
-Andy Ying <andy@trailofbits.com>
-Bret McKee <bretmckee@google.com>
-Brian Silverman <bsilver16384@gmail.com>
-Dmitriy Arbitman <d.arbitman@gmail.com>
-Fumitoshi Ukai <ukai@google.com>
-Guillaume Dumont <dumont.guillaume@gmail.com>
-Håkan L. S. Younes <hyounes@google.com>
-Ivan Penkov <ivanpe@google.com>
-Jacob Trimble <modmaker@google.com>
-Jim Ray <jimray@google.com>
-Marco Wang <m.aesophor@gmail.com>
-Michael Darr <mdarr@matician.com>
-Michael Tanner <michael@tannertaxpro.com>
-MiniLight <MiniLightAR@Gmail.com>
-Peter Collingbourne <pcc@google.com>
-Rodrigo Queiro <rodrigoq@google.com>
-romange <romange@users.noreply.github.com>
-Roman Perepelitsa <roman.perepelitsa@gmail.com>
-Sergiu Deitsch <sergiu.deitsch@gmail.com>
-Shinichiro Hamaji <hamaji@google.com>
-tbennun <tbennun@gmail.com>
-Teddy Reed <teddy@prosauce.org>
-Vijaymahantesh Sattigeri <vijaymahantesh016@gmail.com>
-Zhongming Qu <qzmfranklin@gmail.com>
-Zhuoran Shen <cmsflash99@gmail.com>
diff --git a/third_party/google-glog/COPYING b/third_party/google-glog/COPYING
deleted file mode 100644
index 38396b5..0000000
--- a/third_party/google-glog/COPYING
+++ /dev/null
@@ -1,65 +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.
-
-
-A function gettimeofday in utilities.cc is based on
-
-http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd
-
-The license of this code is:
-
-Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and 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:
-
-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.
-
-3. Neither the name(s) of the above-listed copyright holder(s) nor the
-   names of its contributors may be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(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/google-glog/ChangeLog b/third_party/google-glog/ChangeLog
deleted file mode 100644
index a107e93..0000000
--- a/third_party/google-glog/ChangeLog
+++ /dev/null
@@ -1,109 +0,0 @@
-2022-04-05  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.6.0.
-	* See git log for the details.
-
-2021-05-08  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.5.0.
-	* See git log for the details.
-
-2019-01-22  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.4.0.
-	* See git log for the details.
-
-2017-05-09  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.3.5
-	* See git log for the details.
-
-2015-03-09  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.3.4
-	* See git log for the details.
-
-2013-02-01  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.3.3
-	* Add --disable-rtti option for configure.
-	* Visual Studio build and test fix.
-	* QNX build fix (thanks vanuan).
-	* Reduce warnings.
-	* Fixed LOG_SYSRESULT (thanks ukai).
-	* FreeBSD build fix (thanks yyanagisawa).
-	* Clang build fix.
-	* Now users can re-initialize glog after ShutdownGoogleLogging.
-	* Color output support by GLOG_colorlogtostderr (thanks alexs).
-	* Now glog's ABI around flags are compatible with gflags.
-	* Document mentions how to modify flags from user programs.
-
-2012-01-12  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.3.2
-	* Clang support.
-	* Demangler and stacktrace improvement for newer GCCs.
-	* Now fork(2) doesn't mess up log files.
-	* Make valgrind happier.
-	* Reduce warnings for more -W options.
-	* Provide a workaround for ERROR defined by windows.h.
-
-2010-06-15  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.3.1
-	* GLOG_* environment variables now work even when gflags is installed.
-	* Snow leopard support.
-	* Now we can build and test from out side tree.
-	* Add DCHECK_NOTNULL.
-	* Add ShutdownGoogleLogging to close syslog (thanks DGunchev)
-	* Fix --enable-frame-pointers option (thanks kazuki.ohta)
-	* Fix libunwind detection (thanks giantchen)
-
-2009-07-30  Google Inc. <opensource@google.com>
-
-	* google-glog: version 0.3.0
-	* Fix a deadlock happened when user uses glog with recent gflags.
-	* Suppress several unnecessary warnings (thanks keir).
-	* NetBSD and OpenBSD support.
-	* Use Win32API GetComputeNameA properly (thanks magila).
-	* Fix user name detection for Windows (thanks ademin).
-	* Fix several minor bugs.
-
-2009-04-10  Google Inc. <opensource@google.com>
-	* google-glog: version 0.2.1
-	* Fix timestamps of VC++ version.
-	* Add pkg-config support (thanks Tomasz)
-	* Fix build problem when building with gtest (thanks Michael)
-	* Add --with-gflags option for configure (thanks Michael)
-	* Fixes for GCC 4.4 (thanks John)
-
-2009-01-23  Google Inc. <opensource@google.com>
-	* google-glog: version 0.2
-	* Add initial Windows VC++ support.
-	* Google testing/mocking frameworks integration.
-	* Link pthread library automatically.
-	* Flush logs in signal handlers.
-	* Add macros LOG_TO_STRING, LOG_AT_LEVEL, DVLOG, and LOG_TO_SINK_ONLY.
-	* Log microseconds.
-	* Add --log_backtrace_at option.
-	* Fix some minor bugs.
-
-2008-11-18  Google Inc. <opensource@google.com>
-	* google-glog: version 0.1.2
-	* Add InstallFailureSignalHandler(). (satorux)
-	* Re-organize the way to produce stacktraces.
-	* Don't define unnecessary macro DISALLOW_EVIL_CONSTRUCTORS.
-
-2008-10-15  Google Inc. <opensource@google.com>
-	* google-glog: version 0.1.1
-	* Support symbolize for MacOSX 10.5.
-	* BUG FIX: --vmodule didn't work with gflags.
-	* BUG FIX: symbolize_unittest failed with GCC 4.3.
-	* Several fixes on the document.
-
-2008-10-07  Google Inc. <opensource@google.com>
-
-	* google-glog: initial release:
-	The glog package contains a library that implements application-level
-	logging.  This library provides logging APIs based on C++-style
-	streams and various helper macros.
diff --git a/third_party/google-glog/README.rst b/third_party/google-glog/README.rst
deleted file mode 100644
index d2c69a6..0000000
--- a/third_party/google-glog/README.rst
+++ /dev/null
@@ -1,879 +0,0 @@
-Google Logging Library
-======================
-
-|Linux Github actions| |Windows Github actions| |macOS Github actions| |Total alerts| |Language grade: C++| |Codecov|
-
-Google Logging (glog) is a C++98 library that implements application-level
-logging. The library provides logging APIs based on C++-style streams and
-various helper macros.
-
-.. role:: cmake(code)
-   :language: cmake
-
-.. role:: cmd(code)
-   :language: bash
-
-.. role:: cpp(code)
-   :language: cpp
-
-.. role:: bazel(code)
-   :language: starlark
-
-
-Getting Started
----------------
-
-You can log a message by simply streaming things to ``LOG``\ (<a
-particular `severity level <#severity-levels>`__>), e.g.,
-
-.. code:: cpp
-
-   #include <glog/logging.h>
-
-   int main(int argc, char* argv[]) {
-       // Initialize Google’s logging library.
-       google::InitGoogleLogging(argv[0]);
-
-       // ...
-       LOG(INFO) << "Found " << num_cookies << " cookies";
-   }
-
-
-For a detailed overview of glog features and their usage, please refer
-to the `user guide <#user-guide>`__.
-
-.. contents:: Table of Contents
-
-
-Building from Source
---------------------
-
-glog supports multiple build systems for compiling the project from
-source: `Bazel <#bazel>`__, `CMake <#cmake>`__, and `vcpkg <#vcpkg>`__.
-
-Bazel
-~~~~~
-
-To use glog within a project which uses the
-`Bazel <https://bazel.build/>`__ build tool, add the following lines to
-your ``WORKSPACE`` file:
-
-.. code:: bazel
-
-   load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-   http_archive(
-       name = "com_github_gflags_gflags",
-       sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf",
-       strip_prefix = "gflags-2.2.2",
-       urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"],
-   )
-
-   http_archive(
-       name = "com_github_google_glog",
-       sha256 = "122fb6b712808ef43fbf80f75c52a21c9760683dae470154f02bddfc61135022",
-       strip_prefix = "glog-0.6.0",
-       urls = ["https://github.com/google/glog/archive/v0.6.0.zip"],
-   )
-
-You can then add :bazel:`@com_github_google_glog//:glog` to the deps section
-of a :bazel:`cc_binary` or :bazel:`cc_library` rule, and :code:`#include
-<glog/logging.h>` to include it in your source code. Here’s a simple example:
-
-.. code:: bazel
-
-   cc_binary(
-       name = "main",
-       srcs = ["main.cc"],
-       deps = ["@com_github_google_glog//:glog"],
-   )
-
-CMake
-~~~~~
-
-glog also supports CMake that can be used to build the project on a wide
-range of platforms. If you don’t have CMake installed already, you can
-download it for from CMake’s `official
-website <http://www.cmake.org>`__.
-
-CMake works by generating native makefiles or build projects that can be
-used in the compiler environment of your choice. You can either build
-glog with CMake as a standalone project or it can be incorporated into
-an existing CMake build for another project.
-
-Building glog with CMake
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-When building glog as a standalone project, on Unix-like systems with
-GNU Make as build tool, the typical workflow is:
-
-1. Get the source code and change to it. e.g., cloning with git:
-
-  .. code:: bash
-
-     git clone https://github.com/google/glog.git
-     cd glog
-
-2. Run CMake to configure the build tree.
-
-  .. code:: bash
-
-     cmake -S . -B build -G "Unix Makefiles"
-
-  CMake provides different generators, and by default will pick the most
-  relevant one to your environment. If you need a specific version of Visual
-  Studio, use :cmd:`cmake . -G <generator-name>`, and see :cmd:`cmake --help`
-  for the available generators. Also see :cmd:`-T <toolset-name>`, which can
-  be used to request the native x64 toolchain with :cmd:`-T host=x64`.
-
-3. Afterwards, generated files can be used to compile the project.
-
-  .. code:: bash
-
-     cmake --build build
-
-4. Test the build software (optional).
-
-  .. code:: bash
-
-     cmake --build build --target test
-
-5. Install the built files (optional).
-
-  .. code:: bash
-
-     cmake --build build --target install
-
-Consuming glog in a CMake Project
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If you have glog installed in your system, you can use the CMake command
-:cmake:`find_package` to build against glog in your CMake Project as follows:
-
-.. code:: cmake
-
-   cmake_minimum_required (VERSION 3.16)
-   project (myproj VERSION 1.0)
-
-   find_package (glog 0.6.0 REQUIRED)
-
-   add_executable (myapp main.cpp)
-   target_link_libraries (myapp glog::glog)
-
-Compile definitions and options will be added automatically to your
-target as needed.
-
-Incorporating glog into a CMake Project
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can also use the CMake command :cmake:`add_subdirectory` to include glog
-directly from a subdirectory of your project by replacing the
-:cmake:`find_package` call from the previous example by
-:cmake:`add_subdirectory`. The :cmake:`glog::glog` target is in this case an
-:cmake:`ALIAS` library target for the ``glog`` library target.
-
-Again, compile definitions and options will be added automatically to
-your target as needed.
-
-vcpkg
-~~~~~
-
-You can download and install glog using the `vcpkg
-<https://github.com/Microsoft/vcpkg>`__ dependency manager:
-
-.. code:: bash
-
-   git clone https://github.com/Microsoft/vcpkg.git
-   cd vcpkg
-   ./bootstrap-vcpkg.sh
-   ./vcpkg integrate install
-   ./vcpkg install glog
-
-The glog port in vcpkg is kept up to date by Microsoft team members and
-community contributors. If the version is out of date, please create an
-issue or pull request on the vcpkg repository.
-
-User Guide
-----------
-
-glog defines a series of macros that simplify many common logging tasks.
-You can log messages by severity level, control logging behavior from
-the command line, log based on conditionals, abort the program when
-expected conditions are not met, introduce your own verbose logging
-levels, customize the prefix attached to log messages, and more.
-
-Following sections describe the functionality supported by glog. Please note
-this description may not be complete but limited to the most useful ones. If you
-want to find less common features, please check header files under `src/glog
-<src/glog>`__ directory.
-
-Severity Levels
-~~~~~~~~~~~~~~~
-
-You can specify one of the following severity levels (in increasing
-order of severity): ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL``.
-Logging a ``FATAL`` message terminates the program (after the message is
-logged). Note that messages of a given severity are logged not only in
-the logfile for that severity, but also in all logfiles of lower
-severity. E.g., a message of severity ``FATAL`` will be logged to the
-logfiles of severity ``FATAL``, ``ERROR``, ``WARNING``, and ``INFO``.
-
-The ``DFATAL`` severity logs a ``FATAL`` error in debug mode (i.e.,
-there is no ``NDEBUG`` macro defined), but avoids halting the program in
-production by automatically reducing the severity to ``ERROR``.
-
-Unless otherwise specified, glog writes to the filename
-``/tmp/\<program name\>.\<hostname\>.\<user name\>.log.\<severity level\>.\<date\>-\<time\>.\<pid\>``
-(e.g.,
-``/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474``).
-By default, glog copies the log messages of severity level ``ERROR`` or
-``FATAL`` to standard error (``stderr``) in addition to log files.
-
-Setting Flags
-~~~~~~~~~~~~~
-
-Several flags influence glog’s output behavior. If the `Google gflags library
-<https://github.com/gflags/gflags>`__ is installed on your machine, the build
-system will automatically detect and use it, allowing you to pass flags on the
-command line. For example, if you want to turn the flag :cmd:`--logtostderr` on,
-you can start your application with the following command line:
-
-.. code:: bash
-
-   ./your_application --logtostderr=1
-
-If the Google gflags library isn’t installed, you set flags via
-environment variables, prefixing the flag name with ``GLOG_``, e.g.,
-
-.. code:: bash
-
-   GLOG_logtostderr=1 ./your_application
-
-The following flags are most commonly used:
-
-``logtostderr`` (``bool``, default=\ ``false``)
-   Log messages to ``stderr`` instead of logfiles. Note: you can set
-   binary flags to ``true`` by specifying ``1``, ``true``, or ``yes``
-   (case insensitive). Also, you can set binary flags to ``false`` by
-   specifying ``0``, ``false``, or ``no`` (again, case insensitive).
-
-``stderrthreshold`` (``int``, default=2, which is ``ERROR``)
-   Copy log messages at or above this level to stderr in addition to
-   logfiles. The numbers of severity levels ``INFO``, ``WARNING``,
-   ``ERROR``, and ``FATAL`` are 0, 1, 2, and 3, respectively.
-
-``minloglevel`` (``int``, default=0, which is ``INFO``)
-   Log messages at or above this level. Again, the numbers of severity
-   levels ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL`` are 0, 1, 2,
-   and 3, respectively.
-
-``log_dir`` (``string``, default="")
-   If specified, logfiles are written into this directory instead of the
-   default logging directory.
-
-``v`` (``int``, default=0)
-   Show all ``VLOG(m)`` messages for ``m`` less or equal the value of
-   this flag. Overridable by :cmd:`--vmodule`. See `the section about
-   verbose logging <#verbose-logging>`__ for more detail.
-
-``vmodule`` (``string``, default="")
-   Per-module verbose level. The argument has to contain a
-   comma-separated list of <module name>=<log level>. <module name> is a
-   glob pattern (e.g., ``gfs*`` for all modules whose name starts with
-   "gfs"), matched against the filename base (that is, name ignoring
-   .cc/.h./-inl.h). <log level> overrides any value given by :cmd:`--v`.
-   See also `the section about verbose logging <#verbose-logging>`__.
-
-There are some other flags defined in logging.cc. Please grep the source
-code for ``DEFINE_`` to see a complete list of all flags.
-
-You can also modify flag values in your program by modifying global
-variables ``FLAGS_*`` . Most settings start working immediately after
-you update ``FLAGS_*`` . The exceptions are the flags related to
-destination files. For example, you might want to set ``FLAGS_log_dir``
-before calling :cpp:`google::InitGoogleLogging` . Here is an example:
-
-.. code:: cpp
-
-   LOG(INFO) << "file";
-   // Most flags work immediately after updating values.
-   FLAGS_logtostderr = 1;
-   LOG(INFO) << "stderr";
-   FLAGS_logtostderr = 0;
-   // This won’t change the log destination. If you want to set this
-   // value, you should do this before google::InitGoogleLogging .
-   FLAGS_log_dir = "/some/log/directory";
-   LOG(INFO) << "the same file";
-
-Conditional / Occasional Logging
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes, you may only want to log a message under certain conditions.
-You can use the following macros to perform conditional logging:
-
-.. code:: cpp
-
-   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-
-The "Got lots of cookies" message is logged only when the variable
-``num_cookies`` exceeds 10. If a line of code is executed many times, it
-may be useful to only log a message at certain intervals. This kind of
-logging is most useful for informational messages.
-
-.. code:: cpp
-
-   LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
-
-The above line outputs a log messages on the 1st, 11th, 21st, ... times
-it is executed. Note that the special ``google::COUNTER`` value is used
-to identify which repetition is happening.
-
-You can combine conditional and occasional logging with the following
-macro.
-
-.. code:: cpp
-
-   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER
-                                           << "th big cookie";
-
-Instead of outputting a message every nth time, you can also limit the
-output to the first n occurrences:
-
-.. code:: cpp
-
-   LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie";
-
-Outputs log messages for the first 20 times it is executed. Again, the
-``google::COUNTER`` identifier indicates which repetition is happening.
-
-Other times, it is desired to only log a message periodically based on a time.
-So for example, to log a message every 10ms:
-
-.. code:: cpp
-
-   LOG_EVERY_T(INFO, 0.01) << "Got a cookie";
-
-Or every 2.35s:
-
-.. code:: cpp
-
-   LOG_EVERY_T(INFO, 2.35) << "Got a cookie";
-
-Debug Mode Support
-~~~~~~~~~~~~~~~~~~
-
-Special "debug mode" logging macros only have an effect in debug mode
-and are compiled away to nothing for non-debug mode compiles. Use these
-macros to avoid slowing down your production application due to
-excessive logging.
-
-.. code:: cpp
-
-   DLOG(INFO) << "Found cookies";
-   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-   DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
-
-
-``CHECK`` Macros
-~~~~~~~~~~~~~~~~
-
-It is a good practice to check expected conditions in your program
-frequently to detect errors as early as possible. The ``CHECK`` macro
-provides the ability to abort the application when a condition is not
-met, similar to the ``assert`` macro defined in the standard C library.
-
-``CHECK`` aborts the application if a condition is not true. Unlike
-``assert``, it is \*not\* controlled by ``NDEBUG``, so the check will be
-executed regardless of compilation mode. Therefore, ``fp->Write(x)`` in
-the following example is always executed:
-
-.. code:: cpp
-
-   CHECK(fp->Write(x) == 4) << "Write failed!";
-
-There are various helper macros for equality/inequality checks -
-``CHECK_EQ``, ``CHECK_NE``, ``CHECK_LE``, ``CHECK_LT``, ``CHECK_GE``,
-and ``CHECK_GT``. They compare two values, and log a ``FATAL`` message
-including the two values when the result is not as expected. The values
-must have :cpp:`operator<<(ostream, ...)` defined.
-
-You may append to the error message like so:
-
-.. code:: cpp
-
-   CHECK_NE(1, 2) << ": The world must be ending!";
-
-We are very careful to ensure that each argument is evaluated exactly
-once, and that anything which is legal to pass as a function argument is
-legal here. In particular, the arguments may be temporary expressions
-which will end up being destroyed at the end of the apparent statement,
-for example:
-
-.. code:: cpp
-
-   CHECK_EQ(string("abc")[1], ’b’);
-
-The compiler reports an error if one of the arguments is a pointer and the other
-is :cpp:`NULL`. To work around this, simply :cpp:`static_cast` :cpp:`NULL` to
-the type of the desired pointer.
-
-.. code:: cpp
-
-   CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL));
-
-Better yet, use the ``CHECK_NOTNULL`` macro:
-
-.. code:: cpp
-
-   CHECK_NOTNULL(some_ptr);
-   some_ptr->DoSomething();
-
-Since this macro returns the given pointer, this is very useful in
-constructor initializer lists.
-
-.. code:: cpp
-
-   struct S {
-       S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {}
-       Something* ptr_;
-   };
-
-Note that you cannot use this macro as a C++ stream due to this feature.
-Please use ``CHECK_EQ`` described above to log a custom message before
-aborting the application.
-
-If you are comparing C strings (:cpp:`char *`), a handy set of macros performs
-case sensitive as well as case insensitive comparisons - ``CHECK_STREQ``,
-``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The CASE versions
-are case-insensitive. You can safely pass :cpp:`NULL` pointers for this macro. They
-treat :cpp:`NULL` and any non-:cpp:`NULL` string as not equal. Two :cpp:`NULL`\
-s are equal.
-
-Note that both arguments may be temporary strings which are destructed
-at the end of the current "full expression" (e.g.,
-:cpp:`CHECK_STREQ(Foo().c_str(), Bar().c_str())` where ``Foo`` and ``Bar``
-return C++’s :cpp:`std::string`).
-
-The ``CHECK_DOUBLE_EQ`` macro checks the equality of two floating point
-values, accepting a small error margin. ``CHECK_NEAR`` accepts a third
-floating point argument, which specifies the acceptable error margin.
-
-Verbose Logging
-~~~~~~~~~~~~~~~
-
-When you are chasing difficult bugs, thorough log messages are very useful.
-However, you may want to ignore too verbose messages in usual development. For
-such verbose logging, glog provides the ``VLOG`` macro, which allows you to
-define your own numeric logging levels. The :cmd:`--v` command line option
-controls which verbose messages are logged:
-
-.. code:: cpp
-
-   VLOG(1) << "I’m printed when you run the program with --v=1 or higher";
-   VLOG(2) << "I’m printed when you run the program with --v=2 or higher";
-
-With ``VLOG``, the lower the verbose level, the more likely messages are to be
-logged. For example, if :cmd:`--v==1`, ``VLOG(1)`` will log, but ``VLOG(2)``
-will not log. This is opposite of the severity level, where ``INFO`` is 0, and
-``ERROR`` is 2. :cmd:`--minloglevel` of 1 will log ``WARNING`` and above. Though
-you can specify any integers for both ``VLOG`` macro and :cmd:`--v` flag, the
-common values for them are small positive integers. For example, if you write
-``VLOG(0)``, you should specify :cmd:`--v=-1` or lower to silence it. This is
-less useful since we may not want verbose logs by default in most cases. The
-``VLOG`` macros always log at the ``INFO`` log level (when they log at all).
-
-Verbose logging can be controlled from the command line on a per-module
-basis:
-
-.. code:: bash
-
-   --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
-
-will:
-
-(a) Print ``VLOG(2)`` and lower messages from mapreduce.{h,cc}
-(b) Print ``VLOG(1)`` and lower messages from file.{h,cc}
-(c) Print ``VLOG(3)`` and lower messages from files prefixed with "gfs"
-(d) Print ``VLOG(0)`` and lower messages from elsewhere
-
-The wildcarding functionality shown by (c) supports both ’*’ (matches 0
-or more characters) and ’?’ (matches any single character) wildcards.
-Please also check the section about `command line flags <#setting-flags>`__.
-
-There’s also ``VLOG_IS_ON(n)`` "verbose level" condition macro. This
-macro returns true when the :cmd:`--v` is equal or greater than ``n``. To
-be used as
-
-.. code:: cpp
-
-   if (VLOG_IS_ON(2)) {
-       // do some logging preparation and logging
-       // that can’t be accomplished with just VLOG(2) << ...;
-   }
-
-Verbose level condition macros ``VLOG_IF``, ``VLOG_EVERY_N`` and
-``VLOG_IF_EVERY_N`` behave analogous to ``LOG_IF``, ``LOG_EVERY_N``,
-``LOF_IF_EVERY``, but accept a numeric verbosity level as opposed to a
-severity level.
-
-.. code:: cpp
-
-   VLOG_IF(1, (size > 1024))
-      << "I’m printed when size is more than 1024 and when you run the "
-         "program with --v=1 or more";
-   VLOG_EVERY_N(1, 10)
-      << "I’m printed every 10th occurrence, and when you run the program "
-         "with --v=1 or more. Present occurence is " << google::COUNTER;
-   VLOG_IF_EVERY_N(1, (size > 1024), 10)
-      << "I’m printed on every 10th occurence of case when size is more "
-         " than 1024, when you run the program with --v=1 or more. ";
-         "Present occurence is " << google::COUNTER;
-
-
-Custom Log Prefix Format
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-glog supports changing the format of the prefix attached to log messages by
-receiving a user-provided callback to be used to generate such strings.  That
-feature must be enabled at compile time by the ``WITH_CUSTOM_PREFIX`` flag.
-
-For each log entry, the callback will be invoked with a ``LogMessageInfo``
-struct containing the severity, filename, line number, thread ID, and time of
-the event. It will also be given a reference to the output stream, whose
-contents will be prepended to the actual message in the final log line.
-
-For example:
-
-.. code:: cpp
-
-    /* This function writes a prefix that matches glog's default format.
-     * (The third parameter can be used to receive user-supplied data, and is
-     * NULL by default.)
-     */
-    void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) {
-       s << l.severity[0]
-       << setw(4) << 1900 + l.time.year()
-       << setw(2) << 1 + l.time.month()
-       << setw(2) << l.time.day()
-       << ' '
-       << setw(2) << l.time.hour() << ':'
-       << setw(2) << l.time.min()  << ':'
-       << setw(2) << l.time.sec() << "."
-       << setw(6) << l.time.usec()
-       << ' '
-       << setfill(' ') << setw(5)
-       << l.thread_id << setfill('0')
-       << ' '
-       << l.filename << ':' << l.line_number << "]";
-    }
-
-
-To enable the use of ``CustomPrefix()``, simply give glog a pointer to it
-during initialization: ``InitGoogleLogging(argv[0], &CustomPrefix);``.
-
-Optionally, ``InitGoogleLogging()`` takes a third argument of type  ``void*``
-to pass on to the callback function.
-
-Failure Signal Handler
-~~~~~~~~~~~~~~~~~~~~~~
-
-The library provides a convenient signal handler that will dump useful
-information when the program crashes on certain signals such as ``SIGSEGV``. The
-signal handler can be installed by :cpp:`google::InstallFailureSignalHandler()`.
-The following is an example of output from the signal handler.
-
-::
-
-   *** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date ***
-   *** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: ***
-   PC: @           0x412eb1 TestWaitingLogSink::send()
-       @     0x7f892fb417d0 (unknown)
-       @           0x412eb1 TestWaitingLogSink::send()
-       @     0x7f89304f7f06 google::LogMessage::SendToLog()
-       @     0x7f89304f35af google::LogMessage::Flush()
-       @     0x7f89304f3739 google::LogMessage::~LogMessage()
-       @           0x408cf4 TestLogSinkWaitTillSent()
-       @           0x4115de main
-       @     0x7f892f7ef1c4 (unknown)
-       @           0x4046f9 (unknown)
-
-By default, the signal handler writes the failure dump to the standard
-error. You can customize the destination by :cpp:`InstallFailureWriter()`.
-
-Performance of Messages
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The conditional logging macros provided by glog (e.g., ``CHECK``,
-``LOG_IF``, ``VLOG``, etc.) are carefully implemented and don’t execute
-the right hand side expressions when the conditions are false. So, the
-following check may not sacrifice the performance of your application.
-
-.. code:: cpp
-
-   CHECK(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow();
-
-User-defined Failure Function
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-``FATAL`` severity level messages or unsatisfied ``CHECK`` condition
-terminate your program. You can change the behavior of the termination
-by :cpp:`InstallFailureFunction`.
-
-.. code:: cpp
-
-   void YourFailureFunction() {
-     // Reports something...
-     exit(EXIT_FAILURE);
-   }
-
-   int main(int argc, char* argv[]) {
-     google::InstallFailureFunction(&YourFailureFunction);
-   }
-
-By default, glog tries to dump stacktrace and makes the program exit
-with status 1. The stacktrace is produced only when you run the program
-on an architecture for which glog supports stack tracing (as of
-September 2008, glog supports stack tracing for x86 and x86_64).
-
-Raw Logging
-~~~~~~~~~~~
-
-The header file ``<glog/raw_logging.h>`` can be used for thread-safe logging,
-which does not allocate any memory or acquire any locks. Therefore, the macros
-defined in this header file can be used by low-level memory allocation and
-synchronization code. Please check `src/glog/raw_logging.h.in
-<src/glog/raw_logging.h.in>`__ for detail.
-
-Google Style ``perror()``
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-``PLOG()`` and ``PLOG_IF()`` and ``PCHECK()`` behave exactly like their
-``LOG*`` and ``CHECK`` equivalents with the addition that they append a
-description of the current state of errno to their output lines. E.g.
-
-.. code:: cpp
-
-   PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed";
-
-This check fails with the following error message.
-
-::
-
-   F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) >= 0 Write NULL failed: Bad address [14]
-
-Syslog
-~~~~~~
-
-``SYSLOG``, ``SYSLOG_IF``, and ``SYSLOG_EVERY_N`` macros are available.
-These log to syslog in addition to the normal logs. Be aware that
-logging to syslog can drastically impact performance, especially if
-syslog is configured for remote logging! Make sure you understand the
-implications of outputting to syslog before you use these macros. In
-general, it’s wise to use these macros sparingly.
-
-Strip Logging Messages
-~~~~~~~~~~~~~~~~~~~~~~
-
-Strings used in log messages can increase the size of your binary and
-present a privacy concern. You can therefore instruct glog to remove all
-strings which fall below a certain severity level by using the
-``GOOGLE_STRIP_LOG`` macro:
-
-If your application has code like this:
-
-.. code:: cpp
-
-   #define GOOGLE_STRIP_LOG 1    // this must go before the #include!
-   #include <glog/logging.h>
-
-The compiler will remove the log messages whose severities are less than
-the specified integer value. Since ``VLOG`` logs at the severity level
-``INFO`` (numeric value ``0``), setting ``GOOGLE_STRIP_LOG`` to 1 or
-greater removes all log messages associated with ``VLOG``\ s as well as
-``INFO`` log statements.
-
-Automatically Remove Old Logs
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To enable the log cleaner:
-
-.. code:: cpp
-
-   google::EnableLogCleaner(3); // keep your logs for 3 days
-
-And then glog will check if there are overdue logs whenever a flush is
-performed. In this example, any log file from your project whose last
-modified time is greater than 3 days will be unlink()ed.
-
-This feature can be disabled at any time (if it has been enabled)
-
-.. code:: cpp
-
-   google::DisableLogCleaner();
-
-Notes for Windows Users
-~~~~~~~~~~~~~~~~~~~~~~~
-
-glog defines a severity level ``ERROR``, which is also defined in
-``windows.h`` . You can make glog not define ``INFO``, ``WARNING``,
-``ERROR``, and ``FATAL`` by defining ``GLOG_NO_ABBREVIATED_SEVERITIES``
-before including ``glog/logging.h`` . Even with this macro, you can
-still use the iostream like logging facilities:
-
-.. code:: cpp
-
-   #define GLOG_NO_ABBREVIATED_SEVERITIES
-   #include <windows.h>
-   #include <glog/logging.h>
-
-   // ...
-
-   LOG(ERROR) << "This should work";
-   LOG_IF(ERROR, x > y) << "This should be also OK";
-
-However, you cannot use ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL``
-anymore for functions defined in ``glog/logging.h`` .
-
-.. code:: cpp
-
-   #define GLOG_NO_ABBREVIATED_SEVERITIES
-   #include <windows.h>
-   #include <glog/logging.h>
-
-   // ...
-
-   // This won’t work.
-   // google::FlushLogFiles(google::ERROR);
-
-   // Use this instead.
-   google::FlushLogFiles(google::GLOG_ERROR);
-
-If you don’t need ``ERROR`` defined by ``windows.h``, there are a couple
-of more workarounds which sometimes don’t work:
-
--  ``#define WIN32_LEAN_AND_MEAN`` or ``NOGDI`` **before** you
-   ``#include windows.h``.
--  ``#undef ERROR`` **after** you ``#include windows.h`` .
-
-See `this
-issue <http://code.google.com/p/google-glog/issues/detail?id=33>`__ for
-more detail.
-
-
-Installation Notes for 64-bit Linux Systems
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The glibc built-in stack-unwinder on 64-bit systems has some problems with glog.
-(In particular, if you are using :cpp:`InstallFailureSignalHandler()`, the
-signal may be raised 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 and you need
-:cpp:`InstallFailureSignalHandler()`, we strongly recommend you install
-``libunwind`` before trying to configure or install google glog.
-libunwind can be found
-`here <http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz>`__.
-
-Even if you already have ``libunwind`` installed, you will probably
-still need to install from the snapshot to get the latest version.
-
-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 glog:
-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
-:cmd:`-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 :cmd:`-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 two kinds of stack-unwinder: 1. glibc built-in stack-unwinder and 2.
-frame pointer based stack-unwinder.
-
-1. As we already mentioned, glibc’s unwinder has a deadlock issue.
-   However, if you don’t use :cpp:`InstallFailureSignalHandler()` or you
-   don’t worry about the rare possibilities of deadlocks, you can use
-   this stack-unwinder. If you specify no options and ``libunwind``
-   isn’t detected on your system, the configure script chooses this
-   unwinder by default.
-
-2. The frame pointer based stack unwinder requires that your
-   application, the glog library, and system libraries like libc, all be
-   compiled with a frame pointer. This is *not* the default for x86-64.
-
-
-How to Contribute
------------------
-
-We’d love to accept your patches and contributions to this project.
-There are a just a few small guidelines you need to follow.
-
-Contributor License Agreement (CLA)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Contributions to any Google project must be accompanied by a Contributor
-License Agreement. This is not a copyright **assignment**, it simply
-gives Google permission to use and redistribute your contributions as
-part of the project.
-
-* If you are an individual writing original source code and you’re sure
-  you own the intellectual property, then you’ll need to sign an
-  `individual
-  CLA <https://developers.google.com/open-source/cla/individual>`__.
-* If you work for a company that wants to allow you to contribute your
-  work, then you’ll need to sign a `corporate
-  CLA <https://developers.google.com/open-source/cla/corporate>`__.
-
-You generally only need to submit a CLA once, so if you’ve already
-submitted one (even if it was for a different project), you probably
-don’t need to do it again.
-
-Once your CLA is submitted (or if you already submitted one for another
-Google project), make a commit adding yourself to the
-`AUTHORS <./AUTHORS>`__ and `CONTRIBUTORS <./CONTRIBUTORS>`__ files. This
-commit can be part of your first `pull
-request <https://help.github.com/articles/creating-a-pull-request>`__.
-
-Submitting a Patch
-~~~~~~~~~~~~~~~~~~
-
-1. It’s generally best to start by opening a new issue describing the
-   bug or feature you’re intending to fix. Even if you think it’s
-   relatively minor, it’s helpful to know what people are working on.
-   Mention in the initial issue that you are planning to work on that
-   bug or feature so that it can be assigned to you.
-2. Follow the normal process of
-   `forking <https://help.github.com/articles/fork-a-repo>`__ the
-   project, and setup a new branch to work in. It’s important that each
-   group of changes be done in separate branches in order to ensure that
-   a pull request only includes the commits related to that bug or
-   feature.
-3. Do your best to have `well-formed commit
-   messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`__
-   for each change. This provides consistency throughout the project,
-   and ensures that commit messages are able to be formatted properly by
-   various git tools.
-4. Finally, push the commits to your fork and submit a `pull
-   request <https://help.github.com/articles/creating-a-pull-request>`__.
-
-
-.. |Linux Github actions| image:: https://github.com/google/glog/actions/workflows/linux.yml/badge.svg
-   :target: https://github.com/google/glog/actions
-.. |Windows Github actions| image:: https://github.com/google/glog/actions/workflows/windows.yml/badge.svg
-   :target: https://github.com/google/glog/actions
-.. |macOS Github actions| image:: https://github.com/google/glog/actions/workflows/macos.yml/badge.svg
-   :target: https://github.com/google/glog/actions
-.. |Total alerts| image:: https://img.shields.io/lgtm/alerts/g/google/glog.svg?logo=lgtm&logoWidth=18
-   :target: https://lgtm.com/projects/g/google/glog/alerts/
-.. |Language grade: C++| image:: https://img.shields.io/lgtm/grade/cpp/g/google/glog.svg?logo=lgtm&logoWidth=18)
-   :target: https://lgtm.com/projects/g/google/glog/context:cpp
-.. |Codecov| image:: https://codecov.io/gh/google/glog/branch/master/graph/badge.svg?token=8an420vNju
-   :target: https://codecov.io/gh/google/glog
diff --git a/third_party/google-glog/WORKSPACE b/third_party/google-glog/WORKSPACE
deleted file mode 100644
index 10c89f6..0000000
--- a/third_party/google-glog/WORKSPACE
+++ /dev/null
@@ -1,11 +0,0 @@
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-http_archive(
-    name = "com_github_gflags_gflags",
-    sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf",
-    strip_prefix = "gflags-2.2.2",
-    urls = [
-        "https://mirror.bazel.build/github.com/gflags/gflags/archive/v2.2.2.tar.gz",
-        "https://github.com/gflags/gflags/archive/v2.2.2.tar.gz",
-    ],
-)
diff --git a/third_party/google-glog/bazel/example/BUILD.bazel b/third_party/google-glog/bazel/example/BUILD.bazel
deleted file mode 100644
index 05ab0f3..0000000
--- a/third_party/google-glog/bazel/example/BUILD.bazel
+++ /dev/null
@@ -1,9 +0,0 @@
-cc_test(
-    name = "main",
-    size = "small",
-    srcs = ["main.cc"],
-    deps = [
-        "//:glog",
-        "@com_github_gflags_gflags//:gflags",
-    ],
-)
diff --git a/third_party/google-glog/bazel/example/main.cc b/third_party/google-glog/bazel/example/main.cc
deleted file mode 100644
index fef01dc..0000000
--- a/third_party/google-glog/bazel/example/main.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-#include <glog/stl_logging.h>
-
-int main(int argc, char* argv[]) {
-  // Initialize Google's logging library.
-  google::InitGoogleLogging(argv[0]);
-
-  // Optional: parse command line flags
-  gflags::ParseCommandLineFlags(&argc, &argv, true);
-
-  LOG(INFO) << "Hello, world!";
-
-  // glog/stl_logging.h allows logging STL containers.
-  std::vector<int> x;
-  x.push_back(1);
-  x.push_back(2);
-  x.push_back(3);
-  LOG(INFO) << "ABC, it's easy as " << x;
-
-  return 0;
-}
diff --git a/third_party/google-glog/bazel/glog.bzl b/third_party/google-glog/bazel/glog.bzl
deleted file mode 100644
index 63f40d3..0000000
--- a/third_party/google-glog/bazel/glog.bzl
+++ /dev/null
@@ -1,289 +0,0 @@
-# Implement a macro glog_library() that the BUILD.bazel file can load.
-
-# By default, glog is built with gflags support.  You can change this behavior
-# by using glog_library(with_gflags=0)
-#
-# This file is inspired by the following sample BUILD files:
-#       https://github.com/google/glog/issues/61
-#       https://github.com/google/glog/files/393474/BUILD.txt
-#
-# Known issue: the namespace parameter is not supported on Win32.
-
-def expand_template_impl(ctx):
-    ctx.actions.expand_template(
-        template = ctx.file.template,
-        output = ctx.outputs.out,
-        substitutions = ctx.attr.substitutions,
-    )
-
-expand_template = rule(
-    implementation = expand_template_impl,
-    attrs = {
-        "template": attr.label(mandatory = True, allow_single_file = True),
-        "substitutions": attr.string_dict(mandatory = True),
-        "out": attr.output(mandatory = True),
-    },
-)
-
-def dict_union(x, y):
-    z = {}
-    z.update(x)
-    z.update(y)
-    return z
-
-def glog_library(namespace = "google", with_gflags = 1, **kwargs):
-    if native.repository_name() != "@":
-        repo_name = native.repository_name()[1:]  # Strip the first leading @
-        gendir = "$(GENDIR)/external/" + repo_name
-        src_windows = "external/%s/src/windows" % repo_name
-    else:
-        gendir = "$(GENDIR)"
-        src_windows = "src/windows"
-
-    # Config setting for WebAssembly target.
-    native.config_setting(
-        name = "wasm",
-        values = {"cpu": "wasm"},
-    )
-
-    # Detect when building with clang-cl on Windows.
-    native.config_setting(
-        name = "clang-cl",
-        values = {"compiler": "clang-cl"},
-    )
-
-    common_copts = [
-        # Disable warnings that exists in glog.
-        "-Wno-sign-compare",
-        "-Wno-unused-function",
-        "-Wno-unused-local-typedefs",
-        "-Wno-unused-variable",
-        "-Wno-format-nonliteral",
-        "-DGLOG_BAZEL_BUILD",
-        # Inject a C++ namespace.
-        "-DGOOGLE_NAMESPACE='%s'" % namespace,
-        "-DHAVE_CXX11_NULLPTR_T",
-        "-DHAVE_STDINT_H",
-        "-DHAVE_STRING_H",
-        "-DGLOG_CUSTOM_PREFIX_SUPPORT",
-        "-I%s/glog_internal" % gendir,
-    ] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else [])
-
-    wasm_copts = [
-        # Disable warnings that exists in glog.
-        "-Wno-sign-compare",
-        "-Wno-unused-function",
-        "-Wno-unused-local-typedefs",
-        "-Wno-unused-variable",
-        # Allows src/base/mutex.h to include pthread.h.
-        "-DHAVE_PTHREAD",
-        # Allows src/logging.cc to determine the host name.
-        "-DHAVE_SYS_UTSNAME_H",
-        # For src/utilities.cc.
-        "-DHAVE_SYS_TIME_H",
-        "-DHAVE_UNWIND_H",
-        # Enable dumping stacktrace upon sigaction.
-        "-DHAVE_SIGACTION",
-        # For logging.cc.
-        "-DHAVE_PREAD",
-        "-DHAVE___ATTRIBUTE__",
-    ]
-
-    linux_or_darwin_copts = wasm_copts + [
-        "-Wno-unused-but-set-variable",
-        "-DGLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
-        # For src/utilities.cc.
-        "-DHAVE_SYS_SYSCALL_H",
-        # For src/logging.cc to create symlinks.
-        "-DHAVE_UNISTD_H",
-        "-DHAVE_EXECINFO_H",
-        "-DHAVE_EXECINFO_BACKTRACE",
-        "-fvisibility-inlines-hidden",
-        "-fvisibility=hidden",
-    ]
-
-    freebsd_only_copts = [
-        # Enable declaration of _Unwind_Backtrace
-        "-D_GNU_SOURCE",
-    ]
-
-    darwin_only_copts = [
-        # For stacktrace.
-        "-DHAVE_DLADDR",
-        # Avoid deprecated syscall().
-        "-DHAVE_PTHREAD_THREADID_NP",
-    ]
-
-    windows_only_copts = [
-        # Override -DGLOG_EXPORT= from the cc_library's defines.
-        "-DGLOG_EXPORT=__declspec(dllexport)",
-        "-DGLOG_NO_ABBREVIATED_SEVERITIES",
-        "-DHAVE_SNPRINTF",
-        "-I" + src_windows,
-    ]
-
-    clang_cl_only_copts = [
-        # Allow the override of -DGLOG_EXPORT.
-        "-Wno-macro-redefined",
-    ]
-
-    windows_only_srcs = [
-        "src/glog/log_severity.h",
-        "src/windows/dirent.h",
-        "src/windows/port.cc",
-        "src/windows/port.h",
-    ]
-
-    gflags_deps = ["@com_github_gflags_gflags//:gflags"] if with_gflags else []
-
-    native.cc_library(
-        name = "glog",
-        visibility = ["//visibility:public"],
-        srcs = [
-            ":config_h",
-            "src/base/commandlineflags.h",
-            "src/base/googleinit.h",
-            "src/base/mutex.h",
-            "src/demangle.cc",
-            "src/demangle.h",
-            "src/logging.cc",
-            "src/raw_logging.cc",
-            "src/signalhandler.cc",
-            "src/stacktrace.h",
-            "src/stacktrace_generic-inl.h",
-            "src/stacktrace_libunwind-inl.h",
-            "src/stacktrace_powerpc-inl.h",
-            "src/stacktrace_unwind-inl.h",
-            "src/stacktrace_windows-inl.h",
-            "src/stacktrace_x86-inl.h",
-            "src/symbolize.cc",
-            "src/symbolize.h",
-            "src/utilities.cc",
-            "src/utilities.h",
-            "src/vlog_is_on.cc",
-        ] + select({
-            "@bazel_tools//src/conditions:windows": windows_only_srcs,
-            "//conditions:default": [],
-        }),
-        hdrs = [
-            "src/glog/log_severity.h",
-            "src/glog/platform.h",
-            ":logging_h",
-            ":raw_logging_h",
-            ":stl_logging_h",
-            ":vlog_is_on_h",
-        ],
-        strip_include_prefix = "src",
-        defines = select({
-            # GLOG_EXPORT is normally set by export.h, but that's not
-            # generated for Bazel.
-            "@bazel_tools//src/conditions:windows": [
-                "GLOG_EXPORT=",
-                "GLOG_DEPRECATED=__declspec(deprecated)",
-                "GLOG_NO_ABBREVIATED_SEVERITIES",
-            ],
-            "//conditions:default": [
-                "GLOG_DEPRECATED=__attribute__((deprecated))",
-                "GLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
-            ],
-        }),
-        deps = gflags_deps + select({
-            "@bazel_tools//src/conditions:windows": [":strip_include_prefix_hack"],
-            "//conditions:default": [],
-        }),
-        copts =
-            select({
-                "@bazel_tools//src/conditions:windows": common_copts + windows_only_copts,
-                "@bazel_tools//src/conditions:darwin": common_copts + linux_or_darwin_copts + darwin_only_copts,
-                "@bazel_tools//src/conditions:freebsd": common_copts + linux_or_darwin_copts + freebsd_only_copts,
-                ":wasm": common_copts + wasm_copts,
-                "//conditions:default": common_copts + linux_or_darwin_copts,
-            }) +
-            select({
-                ":clang-cl": clang_cl_only_copts,
-                "//conditions:default": [],
-            }),
-        **kwargs
-    )
-
-    # Workaround https://github.com/bazelbuild/bazel/issues/6337 by declaring
-    # the dependencies without strip_include_prefix.
-    native.cc_library(
-        name = "strip_include_prefix_hack",
-        hdrs = [
-            "src/glog/log_severity.h",
-            ":logging_h",
-            ":raw_logging_h",
-            ":stl_logging_h",
-            ":vlog_is_on_h",
-        ],
-    )
-
-    expand_template(
-        name = "config_h",
-        template = "src/config.h.cmake.in",
-        out = "glog_internal/config.h",
-        substitutions = {"#cmakedefine": "//cmakedefine"},
-    )
-
-    common_config = {
-        "@ac_cv_cxx11_atomic@": "1",
-        "@ac_cv_cxx11_constexpr@": "1",
-        "@ac_cv_cxx11_chrono@": "1",
-        "@ac_cv_cxx11_nullptr_t@": "1",
-        "@ac_cv_cxx_using_operator@": "1",
-        "@ac_cv_have_inttypes_h@": "0",
-        "@ac_cv_have_u_int16_t@": "0",
-        "@ac_cv_have_glog_export@": "0",
-        "@ac_google_start_namespace@": "namespace google {",
-        "@ac_google_end_namespace@": "}",
-        "@ac_google_namespace@": "google",
-    }
-
-    posix_config = dict_union(common_config, {
-        "@ac_cv___attribute___noinline@": "__attribute__((noinline))",
-        "@ac_cv___attribute___noreturn@": "__attribute__((noreturn))",
-        "@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))",
-        "@ac_cv_have___builtin_expect@": "1",
-        "@ac_cv_have___uint16@": "0",
-        "@ac_cv_have_libgflags@": "1" if with_gflags else "0",
-        "@ac_cv_have_mode_t@": "1",
-        "@ac_cv_have_ssize_t@": "1",
-        "@ac_cv_have_stdint_h@": "1",
-        "@ac_cv_have_systypes_h@": "1",
-        "@ac_cv_have_uint16_t@": "1",
-        "@ac_cv_have_unistd_h@": "1",
-    })
-
-    windows_config = dict_union(common_config, {
-        "@ac_cv___attribute___noinline@": "",
-        "@ac_cv___attribute___noreturn@": "__declspec(noreturn)",
-        "@ac_cv___attribute___printf_4_5@": "",
-        "@ac_cv_have___builtin_expect@": "0",
-        "@ac_cv_have___uint16@": "1",
-        "@ac_cv_have_libgflags@": "0",
-        "@ac_cv_have_mode_t@": "0",
-        "@ac_cv_have_ssize_t@": "0",
-        "@ac_cv_have_stdint_h@": "0",
-        "@ac_cv_have_systypes_h@": "0",
-        "@ac_cv_have_uint16_t@": "0",
-        "@ac_cv_have_unistd_h@": "0",
-    })
-
-    [
-        expand_template(
-            name = "%s_h" % f,
-            template = "src/glog/%s.h.in" % f,
-            out = "src/glog/%s.h" % f,
-            substitutions = select({
-                "@bazel_tools//src/conditions:windows": windows_config,
-                "//conditions:default": posix_config,
-            }),
-        )
-        for f in [
-            "vlog_is_on",
-            "stl_logging",
-            "raw_logging",
-            "logging",
-        ]
-    ]
diff --git a/third_party/google-glog/cmake/DetermineGflagsNamespace.cmake b/third_party/google-glog/cmake/DetermineGflagsNamespace.cmake
deleted file mode 100644
index 3dde42b..0000000
--- a/third_party/google-glog/cmake/DetermineGflagsNamespace.cmake
+++ /dev/null
@@ -1,69 +0,0 @@
-macro(determine_gflags_namespace VARIABLE)
-  if (NOT DEFINED "${VARIABLE}")
-    if (CMAKE_REQUIRED_INCLUDES)
-      set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
-    else ()
-      set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS)
-    endif ()
-
-    set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
-
-    set(_NAMESPACES gflags google)
-    set(_check_code
-"
-#include <gflags/gflags.h>
-
-int main(int argc, char**argv)
-{
-  GLOG_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
-}
-")
-    if (NOT CMAKE_REQUIRED_QUIET)
-      message (STATUS "Looking for gflags namespace")
-    endif ()
-    if (${ARGC} EQUAL 3)
-      set (CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
-      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGV2}")
-    endif ()
-
-    set (_check_file
-        ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/DetermineGflagsNamespace.cxx)
-
-    foreach (_namespace ${_NAMESPACES})
-      file (WRITE "${_check_file}" "${_check_code}")
-      try_compile (${VARIABLE}
-        "${CMAKE_BINARY_DIR}" "${_check_file}"
-        COMPILE_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}" -DGLOG_GFLAGS_NAMESPACE=${_namespace}
-        LINK_LIBRARIES gflags
-        CMAKE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-        OUTPUT_VARIABLE OUTPUT)
-
-      if (${VARIABLE})
-        set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace" FORCE)
-        break ()
-      else ()
-        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-          "Determining the gflags namespace ${_namespace} failed with the following output:\n"
-          "${OUTPUT}\n\n")
-      endif ()
-    endforeach (_namespace)
-
-    if (${ARGC} EQUAL 3)
-      set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
-    endif ()
-
-    if (${VARIABLE})
-      if (NOT CMAKE_REQUIRED_QUIET)
-        message (STATUS "Looking for gflags namespace - ${${VARIABLE}}")
-      endif ()
-      file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Determining the gflags namespace passed with the following output:\n"
-        "${OUTPUT}\n\n")
-    else ()
-      if (NOT CMAKE_REQUIRED_QUIET)
-        message (STATUS "Looking for gflags namespace - failed")
-      endif ()
-      set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace")
-    endif ()
-  endif ()
-endmacro ()
diff --git a/third_party/google-glog/cmake/FindUnwind.cmake b/third_party/google-glog/cmake/FindUnwind.cmake
deleted file mode 100644
index a7a976b..0000000
--- a/third_party/google-glog/cmake/FindUnwind.cmake
+++ /dev/null
@@ -1,61 +0,0 @@
-# - Try to find libunwind
-# Once done this will define
-#
-#  Unwind_FOUND - system has libunwind
-#  unwind::unwind - cmake target for libunwind
-
-include (FindPackageHandleStandardArgs)
-
-find_path (Unwind_INCLUDE_DIR NAMES unwind.h libunwind.h DOC "unwind include directory")
-find_library (Unwind_LIBRARY NAMES unwind DOC "unwind library")
-
-mark_as_advanced (Unwind_INCLUDE_DIR Unwind_LIBRARY)
-
-# Extract version information
-if (Unwind_LIBRARY)
-  set (_Unwind_VERSION_HEADER ${Unwind_INCLUDE_DIR}/libunwind-common.h)
-
-  if (EXISTS ${_Unwind_VERSION_HEADER})
-    file (READ ${_Unwind_VERSION_HEADER} _Unwind_VERSION_CONTENTS)
-
-    string (REGEX REPLACE ".*#define UNW_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1"
-      Unwind_VERSION_MAJOR "${_Unwind_VERSION_CONTENTS}")
-    string (REGEX REPLACE ".*#define UNW_VERSION_MINOR[ \t]+([0-9]+).*" "\\1"
-      Unwind_VERSION_MINOR "${_Unwind_VERSION_CONTENTS}")
-    string (REGEX REPLACE ".*#define UNW_VERSION_EXTRA[ \t]+([0-9]+).*" "\\1"
-      Unwind_VERSION_PATCH "${_Unwind_VERSION_CONTENTS}")
-
-    set (Unwind_VERSION ${Unwind_VERSION_MAJOR}.${Unwind_VERSION_MINOR})
-
-    if (CMAKE_MATCH_0)
-      # Third version component may be empty
-      set (Unwind_VERSION ${Unwind_VERSION}.${Unwind_VERSION_PATCH})
-      set (Unwind_VERSION_COMPONENTS 3)
-    else (CMAKE_MATCH_0)
-      set (Unwind_VERSION_COMPONENTS 2)
-    endif (CMAKE_MATCH_0)
-  endif (EXISTS ${_Unwind_VERSION_HEADER})
-endif (Unwind_LIBRARY)
-
-# handle the QUIETLY and REQUIRED arguments and set Unwind_FOUND to TRUE
-# if all listed variables are TRUE
-find_package_handle_standard_args (Unwind
-  REQUIRED_VARS Unwind_INCLUDE_DIR Unwind_LIBRARY
-  VERSION_VAR Unwind_VERSION
-)
-
-if (Unwind_FOUND)
-  if (NOT TARGET unwind::unwind)
-    add_library (unwind::unwind INTERFACE IMPORTED)
-
-    set_property (TARGET unwind::unwind PROPERTY
-      INTERFACE_INCLUDE_DIRECTORIES ${Unwind_INCLUDE_DIR}
-    )
-    set_property (TARGET unwind::unwind PROPERTY
-      INTERFACE_LINK_LIBRARIES ${Unwind_LIBRARY}
-    )
-    set_property (TARGET unwind::unwind PROPERTY
-      IMPORTED_CONFIGURATIONS RELEASE
-    )
-  endif (NOT TARGET unwind::unwind)
-endif (Unwind_FOUND)
diff --git a/third_party/google-glog/cmake/GetCacheVariables.cmake b/third_party/google-glog/cmake/GetCacheVariables.cmake
deleted file mode 100644
index ead3589..0000000
--- a/third_party/google-glog/cmake/GetCacheVariables.cmake
+++ /dev/null
@@ -1,70 +0,0 @@
-cmake_policy (PUSH)
-cmake_policy (VERSION 3.3)
-
-include (CMakeParseArguments)
-
-function (get_cache_variables _CACHEVARS)
-  set (_SINGLE)
-  set (_MULTI EXCLUDE)
-  set (_OPTIONS)
-
-  cmake_parse_arguments (_ARGS "${_OPTIONS}" "${_SINGLE}" "${_MULTI}" ${ARGS} ${ARGN})
-
-  get_cmake_property (_VARIABLES VARIABLES)
-
-  set (CACHEVARS)
-
-  foreach (_VAR ${_VARIABLES})
-    if (DEFINED _ARGS_EXCLUDE)
-      if ("${_VAR}" IN_LIST _ARGS_EXCLUDE)
-        continue ()
-      endif ("${_VAR}" IN_LIST _ARGS_EXCLUDE)
-    endif (DEFINED _ARGS_EXCLUDE)
-
-    get_property (_CACHEVARTYPE CACHE ${_VAR} PROPERTY TYPE)
-
-    if ("${_CACHEVARTYPE}" STREQUAL INTERNAL OR
-        "${_CACHEVARTYPE}" STREQUAL STATIC OR
-        "${_CACHEVARTYPE}" STREQUAL UNINITIALIZED)
-        continue ()
-    endif ("${_CACHEVARTYPE}" STREQUAL INTERNAL OR
-        "${_CACHEVARTYPE}" STREQUAL STATIC OR
-        "${_CACHEVARTYPE}" STREQUAL UNINITIALIZED)
-
-    get_property (_CACHEVARVAL CACHE ${_VAR} PROPERTY VALUE)
-
-    if ("${_CACHEVARVAL}" STREQUAL "")
-      continue ()
-    endif ("${_CACHEVARVAL}" STREQUAL "")
-
-    get_property (_CACHEVARDOC CACHE ${_VAR} PROPERTY HELPSTRING)
-
-    # Escape " in values
-    string (REPLACE "\"" "\\\"" _CACHEVARVAL "${_CACHEVARVAL}")
-    # Escape " in help strings
-    string (REPLACE "\"" "\\\"" _CACHEVARDOC "${_CACHEVARDOC}")
-    # Escape ; in values
-    string (REPLACE ";" "\\\;" _CACHEVARVAL "${_CACHEVARVAL}")
-    # Escape ; in help strings
-    string (REPLACE ";" "\\\;" _CACHEVARDOC "${_CACHEVARDOC}")
-    # Escape backslashes in values except those that are followed by a
-    # quote.
-    string (REGEX REPLACE "\\\\([^\"])" "\\\\\\1" _CACHEVARVAL "${_CACHEVARVAL}")
-    # Escape backslashes in values that are followed by a letter to avoid
-    # invalid escape sequence errors.
-    string (REGEX REPLACE "\\\\([a-zA-Z])" "\\\\\\\\1" _CACHEVARVAL "${_CACHEVARVAL}")
-    string (REPLACE "\\\\" "\\\\\\\\" _CACHEVARDOC "${_CACHEVARDOC}")
-
-    if (NOT "${_CACHEVARTYPE}" STREQUAL BOOL)
-      set (_CACHEVARVAL "\"${_CACHEVARVAL}\"")
-    endif (NOT "${_CACHEVARTYPE}" STREQUAL BOOL)
-
-    if (NOT "${_CACHEVARTYPE}" STREQUAL "" AND NOT "${_CACHEVARVAL}" STREQUAL "")
-      set (CACHEVARS "${CACHEVARS}set (${_VAR} ${_CACHEVARVAL} CACHE ${_CACHEVARTYPE} \"${_CACHEVARDOC}\")\n")
-    endif (NOT "${_CACHEVARTYPE}" STREQUAL "" AND NOT "${_CACHEVARVAL}" STREQUAL "")
-  endforeach (_VAR)
-
-  set (${_CACHEVARS} ${CACHEVARS} PARENT_SCOPE)
-endfunction (get_cache_variables)
-
-cmake_policy (POP)
diff --git a/third_party/google-glog/cmake/RunCleanerTest1.cmake b/third_party/google-glog/cmake/RunCleanerTest1.cmake
deleted file mode 100644
index 7fbf463..0000000
--- a/third_party/google-glog/cmake/RunCleanerTest1.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-set (RUNS 3)
-
-foreach (iter RANGE 1 ${RUNS})
-  set (ENV{GOOGLE_LOG_DIR} ${TEST_DIR})
-  execute_process (COMMAND ${LOGCLEANUP} RESULT_VARIABLE _RESULT)
-
-  if (NOT _RESULT EQUAL 0)
-    message (FATAL_ERROR "Failed to run logcleanup_unittest (error: ${_RESULT})")
-  endif (NOT _RESULT EQUAL 0)
-
-  # Ensure the log files to have different modification timestamps such that
-  # exactly one log file remains at the end. Otherwise all log files will be
-  # retained.
-  execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 1)
-endforeach (iter)
-
-file (GLOB LOG_FILES ${TEST_DIR}/*.foobar)
-list (LENGTH LOG_FILES NUM_FILES)
-
-if (NOT NUM_FILES EQUAL 1)
-  message (SEND_ERROR "Expected 1 log file in log directory but found ${NUM_FILES}")
-endif (NOT NUM_FILES EQUAL 1)
diff --git a/third_party/google-glog/cmake/RunCleanerTest2.cmake b/third_party/google-glog/cmake/RunCleanerTest2.cmake
deleted file mode 100644
index d3b51e3..0000000
--- a/third_party/google-glog/cmake/RunCleanerTest2.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-set (RUNS 3)
-
-foreach (iter RANGE 1 ${RUNS})
-  execute_process (COMMAND ${LOGCLEANUP} -log_dir=${TEST_DIR}
-    RESULT_VARIABLE _RESULT)
-
-  if (NOT _RESULT EQUAL 0)
-    message (FATAL_ERROR "Failed to run logcleanup_unittest (error: ${_RESULT})")
-  endif (NOT _RESULT EQUAL 0)
-
-  # Ensure the log files to have different modification timestamps such that
-  # exactly one log file remains at the end. Otherwise all log files will be
-  # retained.
-  execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 1)
-endforeach (iter)
-
-file (GLOB LOG_FILES ${TEST_DIR}/test_cleanup_*.barfoo)
-list (LENGTH LOG_FILES NUM_FILES)
-
-if (NOT NUM_FILES EQUAL 1)
-  message (SEND_ERROR "Expected 1 log file in build directory ${TEST_DIR} but found ${NUM_FILES}")
-endif (NOT NUM_FILES EQUAL 1)
diff --git a/third_party/google-glog/cmake/RunCleanerTest3.cmake b/third_party/google-glog/cmake/RunCleanerTest3.cmake
deleted file mode 100644
index e8105d1..0000000
--- a/third_party/google-glog/cmake/RunCleanerTest3.cmake
+++ /dev/null
@@ -1,28 +0,0 @@
-set (RUNS 3)
-
-# Create the subdirectory required by this unit test.
-file (MAKE_DIRECTORY ${TEST_DIR}/${TEST_SUBDIR})
-
-foreach (iter RANGE 1 ${RUNS})
-  execute_process (COMMAND ${LOGCLEANUP} -log_dir=${TEST_DIR}
-    RESULT_VARIABLE _RESULT)
-
-  if (NOT _RESULT EQUAL 0)
-    message (FATAL_ERROR "Failed to run logcleanup_unittest (error: ${_RESULT})")
-  endif (NOT _RESULT EQUAL 0)
-
-  # Ensure the log files to have different modification timestamps such that
-  # exactly one log file remains at the end. Otherwise all log files will be
-  # retained.
-  execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 2)
-endforeach (iter)
-
-file (GLOB LOG_FILES ${TEST_DIR}/${TEST_SUBDIR}/test_cleanup_*.relativefoo)
-list (LENGTH LOG_FILES NUM_FILES)
-
-if (NOT NUM_FILES EQUAL 1)
-  message (SEND_ERROR "Expected 1 log file in build directory ${TEST_DIR}${TEST_SUBDIR} but found ${NUM_FILES}")
-endif (NOT NUM_FILES EQUAL 1)
-
-# Remove the subdirectory required by this unit test.
-file (REMOVE_RECURSE ${TEST_DIR}/${TEST_SUBDIR})
diff --git a/third_party/google-glog/cmake/TestInitPackageConfig.cmake b/third_party/google-glog/cmake/TestInitPackageConfig.cmake
deleted file mode 100644
index 01d3a40..0000000
--- a/third_party/google-glog/cmake/TestInitPackageConfig.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-# Create the build directory
-execute_process (
-  COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_BINARY_DIR}
-  RESULT_VARIABLE _DIRECTORY_CREATED_SUCCEEDED
-)
-
-if (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0)
-  message (FATAL_ERROR "Failed to create build directory")
-endif (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0)
-
-file (WRITE ${INITIAL_CACHE} "${CACHEVARS}")
diff --git a/third_party/google-glog/cmake/TestPackageConfig.cmake b/third_party/google-glog/cmake/TestPackageConfig.cmake
deleted file mode 100644
index 97244ab..0000000
--- a/third_party/google-glog/cmake/TestPackageConfig.cmake
+++ /dev/null
@@ -1,40 +0,0 @@
-# Create the build directory
-execute_process (
-  COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_BINARY_DIR}
-  RESULT_VARIABLE _DIRECTORY_CREATED_SUCCEEDED
-)
-
-if (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0)
-  message (FATAL_ERROR "Failed to create build directory")
-endif (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0)
-
-if (GENERATOR_TOOLSET)
-  list (APPEND _ADDITIONAL_ARGS -T ${GENERATOR_TOOLSET})
-endif (GENERATOR_TOOLSET)
-
-if (GENERATOR_PLATFORM)
-  list (APPEND _ADDITIONAL_ARGS -A ${GENERATOR_PLATFORM})
-endif (GENERATOR_PLATFORM)
-
-# Run CMake
-execute_process (
-  # Capture the PATH environment variable content set during project generation
-  # stage. This is required because later during the build stage the PATH is
-  # modified again (e.g., for MinGW AppVeyor CI builds) by adding back the
-  # directory containing git.exe. Incidently, the Git installation directory
-  # also contains sh.exe which causes MinGW Makefile generation to fail.
-  COMMAND ${CMAKE_COMMAND} -E env PATH=${PATH}
-  ${CMAKE_COMMAND} -C ${INITIAL_CACHE}
-    -G ${GENERATOR}
-    ${_ADDITIONAL_ARGS}
-    -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
-    -DCMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY=ON
-    -DCMAKE_PREFIX_PATH=${PACKAGE_DIR}
-    ${SOURCE_DIR}
-  WORKING_DIRECTORY ${TEST_BINARY_DIR}
-  RESULT_VARIABLE _GENERATE_SUCCEEDED
-)
-
-if (NOT _GENERATE_SUCCEEDED EQUAL 0)
-  message (FATAL_ERROR "Failed to generate project files using CMake")
-endif (NOT _GENERATE_SUCCEEDED EQUAL 0)
diff --git a/third_party/google-glog/glog-config.cmake.in b/third_party/google-glog/glog-config.cmake.in
deleted file mode 100644
index 5c5c9c0..0000000
--- a/third_party/google-glog/glog-config.cmake.in
+++ /dev/null
@@ -1,13 +0,0 @@
-if (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@)
-  message (FATAL_ERROR "CMake >= @glog_CMake_VERSION@ required")
-endif (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@)
-
-@PACKAGE_INIT@
-
-include (CMakeFindDependencyMacro)
-include (${CMAKE_CURRENT_LIST_DIR}/glog-modules.cmake)
-
-@gflags_DEPENDENCY@
-@Unwind_DEPENDENCY@
-
-include (${CMAKE_CURRENT_LIST_DIR}/glog-targets.cmake)
diff --git a/third_party/google-glog/glog-modules.cmake.in b/third_party/google-glog/glog-modules.cmake.in
deleted file mode 100644
index 71c5160..0000000
--- a/third_party/google-glog/glog-modules.cmake.in
+++ /dev/null
@@ -1,18 +0,0 @@
-cmake_policy (PUSH)
-cmake_policy (SET CMP0057 NEW)
-
-if (CMAKE_VERSION VERSION_LESS 3.3)
-  message (FATAL_ERROR "glog-modules.cmake requires the consumer "
-    "to use CMake 3.3 (or newer)")
-endif (CMAKE_VERSION VERSION_LESS 3.3)
-
-set (glog_MODULE_PATH "@glog_FULL_CMake_DATADIR@")
-list (APPEND CMAKE_MODULE_PATH ${glog_MODULE_PATH})
-
-if (NOT glog_MODULE_PATH IN_LIST CMAKE_MODULE_PATH)
-  message (FATAL_ERROR "Cannot add '${glog_MODULE_PATH}' to "
-    "CMAKE_MODULE_PATH. This will cause glog-config.cmake to fail at "
-    "locating required find modules. Make sure CMAKE_MODULE_PATH is not a cache variable.")
-endif (NOT glog_MODULE_PATH IN_LIST CMAKE_MODULE_PATH)
-
-cmake_policy (POP)
diff --git a/third_party/google-glog/libglog.pc.in b/third_party/google-glog/libglog.pc.in
deleted file mode 100644
index 2303e2e..0000000
--- a/third_party/google-glog/libglog.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libglog
-Description: Google Log (glog) C++ logging framework
-Version: @VERSION@
-Libs: -L${libdir} -lglog
-Libs.private: @glog_libraries_options_for_static_linking@
-Cflags: -I${includedir}
diff --git a/third_party/google-glog/src/base/commandlineflags.h b/third_party/google-glog/src/base/commandlineflags.h
deleted file mode 100644
index bcb12de..0000000
--- a/third_party/google-glog/src/base/commandlineflags.h
+++ /dev/null
@@ -1,147 +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.
-
-// ---
-// 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 <cstdlib>               // for getenv
-#include <cstring>               // for memchr
-#include <string>
-
-#ifdef HAVE_LIB_GFLAGS
-
-#include <gflags/gflags.h>
-
-#else
-
-#include <glog/logging.h>
-
-#define DECLARE_VARIABLE(type, shorttype, name, tn) \
-  namespace fL##shorttype {                         \
-    extern GLOG_EXPORT type FLAGS_##name;           \
-  }                                                 \
-  using fL##shorttype::FLAGS_##name
-#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \
-  namespace fL##shorttype {                                        \
-    GLOG_EXPORT type FLAGS_##name(value);                          \
-    char FLAGS_no##name;                                           \
-  }                                                                \
-  using fL##shorttype::FLAGS_##name
-
-// bool specialization
-#define DECLARE_bool(name) \
-  DECLARE_VARIABLE(bool, B, name, bool)
-#define DEFINE_bool(name, value, meaning) \
-  DEFINE_VARIABLE(bool, B, name, value, meaning, bool)
-
-// int32 specialization
-#define DECLARE_int32(name) \
-  DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32)
-#define DEFINE_int32(name, value, meaning) \
-  DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32)
-
-// uint32 specialization
-#ifndef DECLARE_uint32
-#define DECLARE_uint32(name) \
-  DECLARE_VARIABLE(GOOGLE_NAMESPACE::uint32, U, name, uint32)
-#endif // DECLARE_uint64
-#define DEFINE_uint32(name, value, meaning) \
-  DEFINE_VARIABLE(GOOGLE_NAMESPACE::uint32, U, name, value, meaning, uint32)
-
-// 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 fLS {                               \
-  extern GLOG_EXPORT std::string& FLAGS_##name; \
-  }                                             \
-  using fLS::FLAGS_##name
-#define DEFINE_string(name, value, meaning)                   \
-  namespace fLS {                                             \
-  std::string FLAGS_##name##_buf(value);                      \
-  GLOG_EXPORT std::string& FLAGS_##name = FLAGS_##name##_buf; \
-  char FLAGS_no##name;                                        \
-  }                                                           \
-  using fLS::FLAGS_##name
-
-#endif  // HAVE_LIB_GFLAGS
-
-// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we
-// have GLOG_* environ variables even if we have gflags installed.
-//
-// If both an environment variable and a flag are specified, the value
-// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the
-// verbosity will be 1, not 0.
-
-#define GLOG_DEFINE_bool(name, value, meaning) \
-  DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning)
-
-#define GLOG_DEFINE_int32(name, value, meaning) \
-  DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning)
-
-#define GLOG_DEFINE_uint32(name, value, meaning) \
-  DEFINE_uint32(name, EnvToUInt("GLOG_" #name, value), meaning)
-
-#define GLOG_DEFINE_string(name, value, meaning) \
-  DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning)
-
-// 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)   \
-  (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL)
-
-#define EnvToInt(envname, dflt)  \
-  (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))
-
-#define EnvToUInt(envname, dflt)  \
-  (!getenv(envname) ? (dflt) : strtoul(getenv(envname), NULL, 10))
-
-#endif  // BASE_COMMANDLINEFLAGS_H__
diff --git a/third_party/google-glog/src/base/googleinit.h b/third_party/google-glog/src/base/googleinit.h
deleted file mode 100644
index 5a8b515..0000000
--- a/third_party/google-glog/src/base/googleinit.h
+++ /dev/null
@@ -1,51 +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: Jacob Hoffman-Andrews
-
-#ifndef _GOOGLEINIT_H
-#define _GOOGLEINIT_H
-
-class GoogleInitializer {
- public:
-  typedef void (*void_function)(void);
-  GoogleInitializer(const char*, void_function f) {
-    f();
-  }
-};
-
-#define REGISTER_MODULE_INITIALIZER(name, body)                 \
-  namespace {                                                   \
-    static void google_init_module_##name () { body; }          \
-    GoogleInitializer google_initializer_module_##name(#name,   \
-            google_init_module_##name);                         \
-  }
-
-#endif /* _GOOGLEINIT_H */
diff --git a/third_party/google-glog/src/base/mutex.h b/third_party/google-glog/src/base/mutex.h
deleted file mode 100644
index e82c597..0000000
--- a/third_party/google-glog/src/base/mutex.h
+++ /dev/null
@@ -1,333 +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.
-//
-// 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: by default, we have #ifdef'ed out the TryLock() method.
-//       This is for two reasons:
-// 1) TryLock() under Windows is a bit annoying (it requires a
-//    #define to be defined very early).
-// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG
-//    mode.
-// If you need TryLock(), and either these two caveats are not a
-// problem for you, or you're willing to work around them, then
-// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs
-// in the code below.
-//
-// 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.
-
-#ifndef GOOGLE_MUTEX_H_
-#define GOOGLE_MUTEX_H_
-
-#include "config.h"           // to figure out pthreads support
-
-#if defined(NO_THREADS)
-  typedef int MutexType;      // to keep a lock-count
-#elif defined(_WIN32) || defined(__CYGWIN__)
-# ifndef WIN32_LEAN_AND_MEAN
-#  define WIN32_LEAN_AND_MEAN  // We only need minimal includes
-# endif
-# ifdef GMUTEX_TRYLOCK
-  // 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
-# endif
-// To avoid macro definition of ERROR.
-# ifndef NOGDI
-#  define NOGDI
-# endif
-// To avoid macro definition of min/max.
-# ifndef NOMINMAX
-#  define NOMINMAX
-# 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__
-#   ifndef _XOPEN_SOURCE  // Some other header might have already set it for us.
-#     define _XOPEN_SOURCE 500  // may be needed to get the rwlock calls
-#   endif
-# 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
-
-// We need to include these header files after defining _XOPEN_SOURCE
-// as they may define the _XOPEN_SOURCE macro.
-#include <cassert>
-#include <cstdlib>      // for abort()
-
-#define MUTEX_NAMESPACE glog_internal_namespace_
-
-namespace MUTEX_NAMESPACE {
-
-class Mutex {
- public:
-  // Create a Mutex that is not held by anybody.  This constructor is
-  // typically used for Mutexes allocated on the heap or the stack.
-  // See below for a recommendation for constructing global Mutex
-  // objects.
-  inline Mutex();
-
-  // Destructor
-  inline ~Mutex();
-
-  inline void Lock();    // Block if needed until free then acquire exclusively
-  inline void Unlock();  // Release a lock acquired via Lock()
-#ifdef GMUTEX_TRYLOCK
-  inline bool TryLock(); // If free, Lock() and return true, else return false
-#endif
-  // 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()
-
-  // TODO(hamaji): Do nothing, implement correctly.
-  inline void AssertHeld() {}
-
- 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_;
-
-  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()            { assert(mutex_ == 0); }
-void Mutex::Lock()         { assert(--mutex_ == -1); }
-void Mutex::Unlock()       { assert(mutex_++ == -1); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }
-#endif
-void Mutex::ReaderLock()   { assert(++mutex_ > 0); }
-void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
-
-#elif defined(_WIN32) || defined(__CYGWIN__)
-
-Mutex::Mutex()             { InitializeCriticalSection(&mutex_); SetIsSafe(); }
-Mutex::~Mutex()            { DeleteCriticalSection(&mutex_); }
-void Mutex::Lock()         { if (is_safe_) EnterCriticalSection(&mutex_); }
-void Mutex::Unlock()       { if (is_safe_) LeaveCriticalSection(&mutex_); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 TryEnterCriticalSection(&mutex_) != 0 : true; }
-#endif
-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() {
-  SetIsSafe();
-  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
-}
-Mutex::~Mutex()            { SAFE_PTHREAD(pthread_rwlock_destroy); }
-void Mutex::Lock()         { SAFE_PTHREAD(pthread_rwlock_wrlock); }
-void Mutex::Unlock()       { SAFE_PTHREAD(pthread_rwlock_unlock); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { return is_safe_ ?
-                                    pthread_rwlock_trywrlock(&mutex_) == 0 :
-                                    true; }
-#endif
-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()             {
-  SetIsSafe();
-  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
-}
-Mutex::~Mutex()            { SAFE_PTHREAD(pthread_mutex_destroy); }
-void Mutex::Lock()         { SAFE_PTHREAD(pthread_mutex_lock); }
-void Mutex::Unlock()       { SAFE_PTHREAD(pthread_mutex_unlock); }
-#ifdef GMUTEX_TRYLOCK
-bool Mutex::TryLock()      { return is_safe_ ?
-                                 pthread_mutex_trylock(&mutex_) == 0 : true; }
-#endif
-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_MUTEX_H__ */
diff --git a/third_party/google-glog/src/cleanup_immediately_unittest.cc b/third_party/google-glog/src/cleanup_immediately_unittest.cc
deleted file mode 100644
index 89d008e..0000000
--- a/third_party/google-glog/src/cleanup_immediately_unittest.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2021, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (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 <glog/logging.h>
-#include <glog/raw_logging.h>
-
-#include "base/commandlineflags.h"
-#include "googletest.h"
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-#ifdef HAVE_LIB_GMOCK
-#include <gmock/gmock.h>
-
-#include "mock-log.h"
-// Introduce several symbols from gmock.
-using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
-using testing::_;
-using testing::AllOf;
-using testing::AnyNumber;
-using testing::HasSubstr;
-using testing::InitGoogleMock;
-using testing::StrictMock;
-using testing::StrNe;
-#endif
-
-using namespace GOOGLE_NAMESPACE;
-
-TEST(CleanImmediately, logging) {
-  google::SetLogFilenameExtension(".foobar");
-  google::EnableLogCleaner(0);
-
-  for (unsigned i = 0; i < 1000; ++i) {
-    LOG(INFO) << "cleanup test";
-  }
-
-  google::DisableLogCleaner();
-}
-
-int main(int argc, char **argv) {
-  FLAGS_colorlogtostderr = false;
-  FLAGS_timestamp_in_logfile_name = true;
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-  // Make sure stderr is not buffered as stderr seems to be buffered
-  // on recent windows.
-  setbuf(stderr, NULL);
-
-  // Test some basics before InitGoogleLogging:
-  CaptureTestStderr();
-  const string early_stderr = GetCapturedTestStderr();
-
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-
-  InitGoogleLogging(argv[0]);
-
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-
-  InitGoogleTest(&argc, argv);
-#ifdef HAVE_LIB_GMOCK
-  InitGoogleMock(&argc, argv);
-#endif
-
-  // so that death tests run before we use threads
-  CHECK_EQ(RUN_ALL_TESTS(), 0);
-}
diff --git a/third_party/google-glog/src/cleanup_with_absolute_prefix_unittest.cc b/third_party/google-glog/src/cleanup_with_absolute_prefix_unittest.cc
deleted file mode 100644
index d4bb47e..0000000
--- a/third_party/google-glog/src/cleanup_with_absolute_prefix_unittest.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2021, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (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 <glog/logging.h>
-#include <glog/raw_logging.h>
-
-#include "base/commandlineflags.h"
-#include "googletest.h"
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-#ifdef HAVE_LIB_GMOCK
-#include <gmock/gmock.h>
-
-#include "mock-log.h"
-// Introduce several symbols from gmock.
-using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
-using testing::_;
-using testing::AllOf;
-using testing::AnyNumber;
-using testing::HasSubstr;
-using testing::InitGoogleMock;
-using testing::StrictMock;
-using testing::StrNe;
-#endif
-
-using namespace GOOGLE_NAMESPACE;
-
-TEST(CleanImmediatelyWithAbsolutePrefix, logging) {
-  google::EnableLogCleaner(0);
-  google::SetLogFilenameExtension(".barfoo");
-  google::SetLogDestination(GLOG_INFO, "test_cleanup_");
-
-  for (unsigned i = 0; i < 1000; ++i) {
-    LOG(INFO) << "cleanup test";
-  }
-
-  for (unsigned i = 0; i < 10; ++i) {
-    LOG(ERROR) << "cleanup test";
-  }
-
-  google::DisableLogCleaner();
-}
-
-int main(int argc, char **argv) {
-  FLAGS_colorlogtostderr = false;
-  FLAGS_timestamp_in_logfile_name = true;
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-  // Make sure stderr is not buffered as stderr seems to be buffered
-  // on recent windows.
-  setbuf(stderr, NULL);
-
-  // Test some basics before InitGoogleLogging:
-  CaptureTestStderr();
-  const string early_stderr = GetCapturedTestStderr();
-
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-
-  InitGoogleLogging(argv[0]);
-
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-
-  InitGoogleTest(&argc, argv);
-#ifdef HAVE_LIB_GMOCK
-  InitGoogleMock(&argc, argv);
-#endif
-
-  // so that death tests run before we use threads
-  CHECK_EQ(RUN_ALL_TESTS(), 0);
-}
diff --git a/third_party/google-glog/src/cleanup_with_relative_prefix_unittest.cc b/third_party/google-glog/src/cleanup_with_relative_prefix_unittest.cc
deleted file mode 100644
index 330f465..0000000
--- a/third_party/google-glog/src/cleanup_with_relative_prefix_unittest.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2021, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (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 <glog/logging.h>
-#include <glog/raw_logging.h>
-
-#include "base/commandlineflags.h"
-#include "googletest.h"
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-#ifdef HAVE_LIB_GMOCK
-#include <gmock/gmock.h>
-
-#include "mock-log.h"
-// Introduce several symbols from gmock.
-using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
-using testing::_;
-using testing::AllOf;
-using testing::AnyNumber;
-using testing::HasSubstr;
-using testing::InitGoogleMock;
-using testing::StrictMock;
-using testing::StrNe;
-#endif
-
-using namespace GOOGLE_NAMESPACE;
-
-TEST(CleanImmediatelyWithRelativePrefix, logging) {
-  google::EnableLogCleaner(0);
-  google::SetLogFilenameExtension(".relativefoo");
-  google::SetLogDestination(GLOG_INFO, "test_subdir/test_cleanup_");
-
-  for (unsigned i = 0; i < 1000; ++i) {
-    LOG(INFO) << "cleanup test";
-  }
-
-  google::DisableLogCleaner();
-}
-
-int main(int argc, char **argv) {
-  FLAGS_colorlogtostderr = false;
-  FLAGS_timestamp_in_logfile_name = true;
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-  // Make sure stderr is not buffered as stderr seems to be buffered
-  // on recent windows.
-  setbuf(stderr, NULL);
-
-  // Test some basics before InitGoogleLogging:
-  CaptureTestStderr();
-  const string early_stderr = GetCapturedTestStderr();
-
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-
-  InitGoogleLogging(argv[0]);
-
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-
-  InitGoogleTest(&argc, argv);
-#ifdef HAVE_LIB_GMOCK
-  InitGoogleMock(&argc, argv);
-#endif
-
-  // so that death tests run before we use threads
-  CHECK_EQ(RUN_ALL_TESTS(), 0);
-}
diff --git a/third_party/google-glog/src/config.h.cmake.in b/third_party/google-glog/src/config.h.cmake.in
deleted file mode 100644
index 20b5f1c..0000000
--- a/third_party/google-glog/src/config.h.cmake.in
+++ /dev/null
@@ -1,231 +0,0 @@
-#ifndef GLOG_CONFIG_H
-#define GLOG_CONFIG_H
-
-/* define if glog doesn't use RTTI */
-#cmakedefine DISABLE_RTTI
-
-/* Namespace for Google classes */
-#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE}
-
-/* Define if you have the `dladdr' function */
-#cmakedefine HAVE_DLADDR
-
-/* Define if you have the `snprintf' function */
-#cmakedefine HAVE_SNPRINTF
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H
-
-/* Define if you have the `backtrace' function in <execinfo.h> */
-#cmakedefine HAVE_EXECINFO_BACKTRACE
-
-/* Define if you have the `backtrace_symbols' function in <execinfo.h> */
-#cmakedefine HAVE_EXECINFO_BACKTRACE_SYMBOLS
-
-/* Define if you have the `fcntl' function */
-#cmakedefine HAVE_FCNTL
-
-/* Define to 1 if you have the <glob.h> header file. */
-#cmakedefine HAVE_GLOB_H
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
-
-/* Define to 1 if you have the `pthread' library (-lpthread). */
-#cmakedefine HAVE_LIBPTHREAD
-
-/* define if you have google gflags library */
-#cmakedefine HAVE_LIB_GFLAGS
-
-/* define if you have google gmock library */
-#cmakedefine HAVE_LIB_GMOCK
-
-/* define if you have google gtest library */
-#cmakedefine HAVE_LIB_GTEST
-
-/* define if you have dbghelp library */
-#cmakedefine HAVE_DBGHELP
-
-/* define if you have libunwind */
-#cmakedefine HAVE_LIB_UNWIND
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H
-
-/* define to disable multithreading support. */
-#cmakedefine NO_THREADS
-
-/* define if the compiler implements namespaces */
-#cmakedefine HAVE_NAMESPACES
-
-/* Define if you have the 'pread' function */
-#cmakedefine HAVE_PREAD
-
-/* Define if you have POSIX threads libraries and header files. */
-#cmakedefine HAVE_PTHREAD
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#cmakedefine HAVE_PWD_H
-
-/* Define if you have the 'pwrite' function */
-#cmakedefine HAVE_PWRITE
-
-/* define if the compiler implements pthread_rwlock_* */
-#cmakedefine HAVE_RWLOCK
-
-/* Define if you have the 'sigaction' function */
-#cmakedefine HAVE_SIGACTION
-
-/* Define if you have the `sigaltstack' function */
-#cmakedefine HAVE_SIGALTSTACK
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
-
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H
-
-/* Define to 1 if you have the <syscall.h> header file. */
-#cmakedefine HAVE_SYSCALL_H
-
-/* Define to 1 if you have the <syslog.h> header file. */
-#cmakedefine HAVE_SYSLOG_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#cmakedefine HAVE_SYS_SYSCALL_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#cmakedefine HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
-
-/* Define to 1 if you have the <sys/ucontext.h> header file. */
-#cmakedefine HAVE_SYS_UCONTEXT_H
-
-/* Define to 1 if you have the <sys/utsname.h> header file. */
-#cmakedefine HAVE_SYS_UTSNAME_H
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#cmakedefine HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-#cmakedefine HAVE_UCONTEXT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
-
-/* Define if you linking to _Unwind_Backtrace is possible. */
-#cmakedefine HAVE__UNWIND_BACKTRACE
-
-/* Define if you linking to _Unwind_GetIP is possible. */
-#cmakedefine HAVE__UNWIND_GETIP
-
-/* define if the compiler supports using expression for operator */
-#cmakedefine HAVE_USING_OPERATOR
-
-/* define if your compiler has __attribute__ */
-#cmakedefine HAVE___ATTRIBUTE__
-
-/* define if your compiler has __builtin_expect */
-#cmakedefine HAVE___BUILTIN_EXPECT ${HAVE___BUILTIN_EXPECT}
-
-/* define if your compiler has __sync_val_compare_and_swap */
-#cmakedefine HAVE___SYNC_VAL_COMPARE_AND_SWAP
-
-/* define if symbolize support is available */
-#cmakedefine HAVE_SYMBOLIZE
-
-/* define if localtime_r is available in time.h */
-#cmakedefine HAVE_LOCALTIME_R
-
-/* define if gmtime_r is available in time.h */
-#cmakedefine HAVE_GMTIME_R
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#cmakedefine LT_OBJDIR
-
-/* Name of package */
-#cmakedefine PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#cmakedefine PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#cmakedefine PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#cmakedefine PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#cmakedefine PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#cmakedefine PACKAGE_URL
-
-/* Define to the version of this package. */
-#cmakedefine PACKAGE_VERSION
-
-/* How to access the PC from a struct ucontext */
-#cmakedefine PC_FROM_UCONTEXT
-
-/* define if we should print file offsets in traces instead of symbolizing. */
-#cmakedefine PRINT_UNSYMBOLIZED_STACK_TRACES
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-#cmakedefine PTHREAD_CREATE_JOINABLE
-
-/* The size of `void *', as computed by sizeof. */
-#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P}
-
-/* the namespace where STL code like vector<> is defined */
-#cmakedefine STL_NAMESPACE ${STL_NAMESPACE}
-
-/* location of source code */
-#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR}
-
-/* Define to necessary thread-local storage attribute. */
-#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE}
-
-/* Check whether aligned_storage and alignof present */
-#cmakedefine HAVE_ALIGNED_STORAGE ${HAVE_ALIGNED_STORAGE}
-
-/* Check whether C++11 atomic is available */
-#cmakedefine HAVE_CXX11_ATOMIC ${HAVE_CXX11_ATOMIC}
-
-/* Check whether C++11 chrono is available */
-#cmakedefine HAVE_CXX11_CHRONO ${HAVE_CXX11_CHRONO}
-
-/* Check whether C++11 nullptr_t is available */
-#cmakedefine HAVE_CXX11_NULLPTR_T ${HAVE_CXX11_NULLPTR_T}
-
-/* Version number of package */
-#cmakedefine VERSION
-
-#ifdef GLOG_BAZEL_BUILD
-
-/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved:
- * https://github.com/bazelbuild/bazel/issues/3979 */
-#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE {
-
-#define _END_GOOGLE_NAMESPACE_ }
-
-#else
-
-/* Stops putting the code inside the Google namespace */
-#cmakedefine _END_GOOGLE_NAMESPACE_ ${_END_GOOGLE_NAMESPACE_}
-
-/* Puts following code inside the Google namespace */
-#cmakedefine _START_GOOGLE_NAMESPACE_ ${_START_GOOGLE_NAMESPACE_}
-
-#endif
-
-/* Replacement for deprecated syscall(SYS_gettid) on macOS. */
-#cmakedefine HAVE_PTHREAD_THREADID_NP ${HAVE_PTHREAD_THREADID_NP}
-
-#endif  // GLOG_CONFIG_H
diff --git a/third_party/google-glog/src/demangle.cc b/third_party/google-glog/src/demangle.cc
deleted file mode 100644
index 9276c5b..0000000
--- a/third_party/google-glog/src/demangle.cc
+++ /dev/null
@@ -1,1363 +0,0 @@
-// 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: Satoru Takabayashi
-//
-// For reference check out:
-// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
-//
-// Note that we only have partial C++0x support yet.
-
-#include <cstdio>  // for NULL
-
-#include "demangle.h"
-#include "utilities.h"
-
-#if defined(GLOG_OS_WINDOWS)
-#include <dbghelp.h>
-#endif
-
-_START_GOOGLE_NAMESPACE_
-
-#if !defined(GLOG_OS_WINDOWS)
-typedef struct {
-  const char *abbrev;
-  const char *real_name;
-} AbbrevPair;
-
-// List of operators from Itanium C++ ABI.
-static const AbbrevPair kOperatorList[] = {
-  { "nw", "new" },
-  { "na", "new[]" },
-  { "dl", "delete" },
-  { "da", "delete[]" },
-  { "ps", "+" },
-  { "ng", "-" },
-  { "ad", "&" },
-  { "de", "*" },
-  { "co", "~" },
-  { "pl", "+" },
-  { "mi", "-" },
-  { "ml", "*" },
-  { "dv", "/" },
-  { "rm", "%" },
-  { "an", "&" },
-  { "or", "|" },
-  { "eo", "^" },
-  { "aS", "=" },
-  { "pL", "+=" },
-  { "mI", "-=" },
-  { "mL", "*=" },
-  { "dV", "/=" },
-  { "rM", "%=" },
-  { "aN", "&=" },
-  { "oR", "|=" },
-  { "eO", "^=" },
-  { "ls", "<<" },
-  { "rs", ">>" },
-  { "lS", "<<=" },
-  { "rS", ">>=" },
-  { "eq", "==" },
-  { "ne", "!=" },
-  { "lt", "<" },
-  { "gt", ">" },
-  { "le", "<=" },
-  { "ge", ">=" },
-  { "nt", "!" },
-  { "aa", "&&" },
-  { "oo", "||" },
-  { "pp", "++" },
-  { "mm", "--" },
-  { "cm", "," },
-  { "pm", "->*" },
-  { "pt", "->" },
-  { "cl", "()" },
-  { "ix", "[]" },
-  { "qu", "?" },
-  { "st", "sizeof" },
-  { "sz", "sizeof" },
-  { NULL, NULL },
-};
-
-// List of builtin types from Itanium C++ ABI.
-static const AbbrevPair kBuiltinTypeList[] = {
-  { "v", "void" },
-  { "w", "wchar_t" },
-  { "b", "bool" },
-  { "c", "char" },
-  { "a", "signed char" },
-  { "h", "unsigned char" },
-  { "s", "short" },
-  { "t", "unsigned short" },
-  { "i", "int" },
-  { "j", "unsigned int" },
-  { "l", "long" },
-  { "m", "unsigned long" },
-  { "x", "long long" },
-  { "y", "unsigned long long" },
-  { "n", "__int128" },
-  { "o", "unsigned __int128" },
-  { "f", "float" },
-  { "d", "double" },
-  { "e", "long double" },
-  { "g", "__float128" },
-  { "z", "ellipsis" },
-  { NULL, NULL }
-};
-
-// List of substitutions Itanium C++ ABI.
-static const AbbrevPair kSubstitutionList[] = {
-  { "St", "" },
-  { "Sa", "allocator" },
-  { "Sb", "basic_string" },
-  // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
-  { "Ss", "string"},
-  // std::basic_istream<char, std::char_traits<char> >
-  { "Si", "istream" },
-  // std::basic_ostream<char, std::char_traits<char> >
-  { "So", "ostream" },
-  // std::basic_iostream<char, std::char_traits<char> >
-  { "Sd", "iostream" },
-  { NULL, NULL }
-};
-
-// State needed for demangling.
-typedef struct {
-  const char *mangled_cur;   // Cursor of mangled name.
-  char *out_cur;             // Cursor of output string.
-  const char *out_begin;     // Beginning of output string.
-  const char *out_end;       // End of output string.
-  const char *prev_name;     // For constructors/destructors.
-  ssize_t prev_name_length;  // For constructors/destructors.
-  short nest_level;          // For nested names.
-  bool append;               // Append flag.
-  bool overflowed;           // True if output gets overflowed.
-} State;
-
-// We don't use strlen() in libc since it's not guaranteed to be async
-// signal safe.
-static size_t StrLen(const char *str) {
-  size_t len = 0;
-  while (*str != '\0') {
-    ++str;
-    ++len;
-  }
-  return len;
-}
-
-// Returns true if "str" has at least "n" characters remaining.
-static bool AtLeastNumCharsRemaining(const char *str, ssize_t n) {
-  for (ssize_t i = 0; i < n; ++i) {
-    if (str[i] == '\0') {
-      return false;
-    }
-  }
-  return true;
-}
-
-// Returns true if "str" has "prefix" as a prefix.
-static bool StrPrefix(const char *str, const char *prefix) {
-  size_t i = 0;
-  while (str[i] != '\0' && prefix[i] != '\0' &&
-         str[i] == prefix[i]) {
-    ++i;
-  }
-  return prefix[i] == '\0';  // Consumed everything in "prefix".
-}
-
-static void InitState(State *state, const char *mangled,
-                      char *out, size_t out_size) {
-  state->mangled_cur = mangled;
-  state->out_cur = out;
-  state->out_begin = out;
-  state->out_end = out + out_size;
-  state->prev_name  = NULL;
-  state->prev_name_length = -1;
-  state->nest_level = -1;
-  state->append = true;
-  state->overflowed = false;
-}
-
-// Returns true and advances "mangled_cur" if we find "one_char_token"
-// at "mangled_cur" position.  It is assumed that "one_char_token" does
-// not contain '\0'.
-static bool ParseOneCharToken(State *state, const char one_char_token) {
-  if (state->mangled_cur[0] == one_char_token) {
-    ++state->mangled_cur;
-    return true;
-  }
-  return false;
-}
-
-// Returns true and advances "mangled_cur" if we find "two_char_token"
-// at "mangled_cur" position.  It is assumed that "two_char_token" does
-// not contain '\0'.
-static bool ParseTwoCharToken(State *state, const char *two_char_token) {
-  if (state->mangled_cur[0] == two_char_token[0] &&
-      state->mangled_cur[1] == two_char_token[1]) {
-    state->mangled_cur += 2;
-    return true;
-  }
-  return false;
-}
-
-// Returns true and advances "mangled_cur" if we find any character in
-// "char_class" at "mangled_cur" position.
-static bool ParseCharClass(State *state, const char *char_class) {
-  const char *p = char_class;
-  for (; *p != '\0'; ++p) {
-    if (state->mangled_cur[0] == *p) {
-      ++state->mangled_cur;
-      return true;
-    }
-  }
-  return false;
-}
-
-// This function is used for handling an optional non-terminal.
-static bool Optional(bool) {
-  return true;
-}
-
-// This function is used for handling <non-terminal>+ syntax.
-typedef bool (*ParseFunc)(State *);
-static bool OneOrMore(ParseFunc parse_func, State *state) {
-  if (parse_func(state)) {
-    while (parse_func(state)) {
-    }
-    return true;
-  }
-  return false;
-}
-
-// This function is used for handling <non-terminal>* syntax. The function
-// always returns true and must be followed by a termination token or a
-// terminating sequence not handled by parse_func (e.g.
-// ParseOneCharToken(state, 'E')).
-static bool ZeroOrMore(ParseFunc parse_func, State *state) {
-  while (parse_func(state)) {
-  }
-  return true;
-}
-
-// Append "str" at "out_cur".  If there is an overflow, "overflowed"
-// is set to true for later use.  The output string is ensured to
-// always terminate with '\0' as long as there is no overflow.
-static void Append(State *state, const char * const str, ssize_t length) {
-  for (ssize_t i = 0; i < length; ++i) {
-    if (state->out_cur + 1 < state->out_end) {  // +1 for '\0'
-      *state->out_cur = str[i];
-      ++state->out_cur;
-    } else {
-      state->overflowed = true;
-      break;
-    }
-  }
-  if (!state->overflowed) {
-    *state->out_cur = '\0';  // Terminate it with '\0'
-  }
-}
-
-// We don't use equivalents in libc to avoid locale issues.
-static bool IsLower(char c) {
-  return c >= 'a' && c <= 'z';
-}
-
-static bool IsAlpha(char c) {
-  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-}
-
-static bool IsDigit(char c) {
-  return c >= '0' && c <= '9';
-}
-
-// Returns true if "str" is a function clone suffix.  These suffixes are used
-// by GCC 4.5.x and later versions to indicate functions which have been
-// cloned during optimization.  We treat any sequence (.<alpha>+.<digit>+)+ as
-// a function clone suffix.
-static bool IsFunctionCloneSuffix(const char *str) {
-  size_t i = 0;
-  while (str[i] != '\0') {
-    // Consume a single .<alpha>+.<digit>+ sequence.
-    if (str[i] != '.' || !IsAlpha(str[i + 1])) {
-      return false;
-    }
-    i += 2;
-    while (IsAlpha(str[i])) {
-      ++i;
-    }
-    if (str[i] != '.' || !IsDigit(str[i + 1])) {
-      return false;
-    }
-    i += 2;
-    while (IsDigit(str[i])) {
-      ++i;
-    }
-  }
-  return true;  // Consumed everything in "str".
-}
-
-// Append "str" with some tweaks, iff "append" state is true.
-// Returns true so that it can be placed in "if" conditions.
-static void MaybeAppendWithLength(State *state, const char * const str,
-                                  ssize_t length) {
-  if (state->append && length > 0) {
-    // Append a space if the output buffer ends with '<' and "str"
-    // starts with '<' to avoid <<<.
-    if (str[0] == '<' && state->out_begin < state->out_cur  &&
-        state->out_cur[-1] == '<') {
-      Append(state, " ", 1);
-    }
-    // Remember the last identifier name for ctors/dtors.
-    if (IsAlpha(str[0]) || str[0] == '_') {
-      state->prev_name = state->out_cur;
-      state->prev_name_length = length;
-    }
-    Append(state, str, length);
-  }
-}
-
-// A convenient wrapper arount MaybeAppendWithLength().
-static bool MaybeAppend(State *state, const char * const str) {
-  if (state->append) {
-    size_t length = StrLen(str);
-    MaybeAppendWithLength(state, str, static_cast<ssize_t>(length));
-  }
-  return true;
-}
-
-// This function is used for handling nested names.
-static bool EnterNestedName(State *state) {
-  state->nest_level = 0;
-  return true;
-}
-
-// This function is used for handling nested names.
-static bool LeaveNestedName(State *state, short prev_value) {
-  state->nest_level = prev_value;
-  return true;
-}
-
-// Disable the append mode not to print function parameters, etc.
-static bool DisableAppend(State *state) {
-  state->append = false;
-  return true;
-}
-
-// Restore the append mode to the previous state.
-static bool RestoreAppend(State *state, bool prev_value) {
-  state->append = prev_value;
-  return true;
-}
-
-// Increase the nest level for nested names.
-static void MaybeIncreaseNestLevel(State *state) {
-  if (state->nest_level > -1) {
-    ++state->nest_level;
-  }
-}
-
-// Appends :: for nested names if necessary.
-static void MaybeAppendSeparator(State *state) {
-  if (state->nest_level >= 1) {
-    MaybeAppend(state, "::");
-  }
-}
-
-// Cancel the last separator if necessary.
-static void MaybeCancelLastSeparator(State *state) {
-  if (state->nest_level >= 1 && state->append &&
-      state->out_begin <= state->out_cur - 2) {
-    state->out_cur -= 2;
-    *state->out_cur = '\0';
-  }
-}
-
-// Returns true if the identifier of the given length pointed to by
-// "mangled_cur" is anonymous namespace.
-static bool IdentifierIsAnonymousNamespace(State *state, ssize_t length) {
-  static const char anon_prefix[] = "_GLOBAL__N_";
-  return (length > static_cast<ssize_t>(sizeof(anon_prefix)) -
-                       1 &&  // Should be longer.
-          StrPrefix(state->mangled_cur, anon_prefix));
-}
-
-// Forward declarations of our parsing functions.
-static bool ParseMangledName(State *state);
-static bool ParseEncoding(State *state);
-static bool ParseName(State *state);
-static bool ParseUnscopedName(State *state);
-static bool ParseUnscopedTemplateName(State *state);
-static bool ParseNestedName(State *state);
-static bool ParsePrefix(State *state);
-static bool ParseUnqualifiedName(State *state);
-static bool ParseSourceName(State *state);
-static bool ParseLocalSourceName(State *state);
-static bool ParseNumber(State *state, int *number_out);
-static bool ParseFloatNumber(State *state);
-static bool ParseSeqId(State *state);
-static bool ParseIdentifier(State *state, ssize_t length);
-static bool ParseAbiTags(State *state);
-static bool ParseAbiTag(State *state);
-static bool ParseOperatorName(State *state);
-static bool ParseSpecialName(State *state);
-static bool ParseCallOffset(State *state);
-static bool ParseNVOffset(State *state);
-static bool ParseVOffset(State *state);
-static bool ParseCtorDtorName(State *state);
-static bool ParseType(State *state);
-static bool ParseCVQualifiers(State *state);
-static bool ParseBuiltinType(State *state);
-static bool ParseFunctionType(State *state);
-static bool ParseBareFunctionType(State *state);
-static bool ParseClassEnumType(State *state);
-static bool ParseArrayType(State *state);
-static bool ParsePointerToMemberType(State *state);
-static bool ParseTemplateParam(State *state);
-static bool ParseTemplateTemplateParam(State *state);
-static bool ParseTemplateArgs(State *state);
-static bool ParseTemplateArg(State *state);
-static bool ParseExpression(State *state);
-static bool ParseExprPrimary(State *state);
-static bool ParseLocalName(State *state);
-static bool ParseDiscriminator(State *state);
-static bool ParseSubstitution(State *state);
-
-// Implementation note: the following code is a straightforward
-// translation of the Itanium C++ ABI defined in BNF with a couple of
-// exceptions.
-//
-// - Support GNU extensions not defined in the Itanium C++ ABI
-// - <prefix> and <template-prefix> are combined to avoid infinite loop
-// - Reorder patterns to shorten the code
-// - Reorder patterns to give greedier functions precedence
-//   We'll mark "Less greedy than" for these cases in the code
-//
-// Each parsing function changes the state and returns true on
-// success.  Otherwise, don't change the state and returns false.  To
-// ensure that the state isn't changed in the latter case, we save the
-// original state before we call more than one parsing functions
-// consecutively with &&, and restore the state if unsuccessful.  See
-// ParseEncoding() as an example of this convention.  We follow the
-// convention throughout the code.
-//
-// Originally we tried to do demangling without following the full ABI
-// syntax but it turned out we needed to follow the full syntax to
-// parse complicated cases like nested template arguments.  Note that
-// implementing a full-fledged demangler isn't trivial (libiberty's
-// cp-demangle.c has +4300 lines).
-//
-// Note that (foo) in <(foo) ...> is a modifier to be ignored.
-//
-// Reference:
-// - Itanium C++ ABI
-//   <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
-
-// <mangled-name> ::= _Z <encoding>
-static bool ParseMangledName(State *state) {
-  return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
-}
-
-// <encoding> ::= <(function) name> <bare-function-type>
-//            ::= <(data) name>
-//            ::= <special-name>
-static bool ParseEncoding(State *state) {
-  State copy = *state;
-  if (ParseName(state) && ParseBareFunctionType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseName(state) || ParseSpecialName(state)) {
-    return true;
-  }
-  return false;
-}
-
-// <name> ::= <nested-name>
-//        ::= <unscoped-template-name> <template-args>
-//        ::= <unscoped-name>
-//        ::= <local-name>
-static bool ParseName(State *state) {
-  if (ParseNestedName(state) || ParseLocalName(state)) {
-    return true;
-  }
-
-  State copy = *state;
-  if (ParseUnscopedTemplateName(state) &&
-      ParseTemplateArgs(state)) {
-    return true;
-  }
-  *state = copy;
-
-  // Less greedy than <unscoped-template-name> <template-args>.
-  if (ParseUnscopedName(state)) {
-    return true;
-  }
-  return false;
-}
-
-// <unscoped-name> ::= <unqualified-name>
-//                 ::= St <unqualified-name>
-static bool ParseUnscopedName(State *state) {
-  if (ParseUnqualifiedName(state)) {
-    return true;
-  }
-
-  State copy = *state;
-  if (ParseTwoCharToken(state, "St") &&
-      MaybeAppend(state, "std::") &&
-      ParseUnqualifiedName(state)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <unscoped-template-name> ::= <unscoped-name>
-//                          ::= <substitution>
-static bool ParseUnscopedTemplateName(State *state) {
-  return ParseUnscopedName(state) || ParseSubstitution(state);
-}
-
-// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
-//               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
-static bool ParseNestedName(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'N') &&
-      EnterNestedName(state) &&
-      Optional(ParseCVQualifiers(state)) &&
-      ParsePrefix(state) &&
-      LeaveNestedName(state, copy.nest_level) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// This part is tricky.  If we literally translate them to code, we'll
-// end up infinite loop.  Hence we merge them to avoid the case.
-//
-// <prefix> ::= <prefix> <unqualified-name>
-//          ::= <template-prefix> <template-args>
-//          ::= <template-param>
-//          ::= <substitution>
-//          ::= # empty
-// <template-prefix> ::= <prefix> <(template) unqualified-name>
-//                   ::= <template-param>
-//                   ::= <substitution>
-static bool ParsePrefix(State *state) {
-  bool has_something = false;
-  while (true) {
-    MaybeAppendSeparator(state);
-    if (ParseTemplateParam(state) ||
-        ParseSubstitution(state) ||
-        ParseUnscopedName(state)) {
-      has_something = true;
-      MaybeIncreaseNestLevel(state);
-      continue;
-    }
-    MaybeCancelLastSeparator(state);
-    if (has_something && ParseTemplateArgs(state)) {
-      return ParsePrefix(state);
-    } else {
-      break;
-    }
-  }
-  return true;
-}
-
-// <unqualified-name> ::= <operator-name>
-//                    ::= <ctor-dtor-name>
-//                    ::= <source-name> [<abi-tags>]
-//                    ::= <local-source-name> [<abi-tags>]
-static bool ParseUnqualifiedName(State *state) {
-  return (ParseOperatorName(state) ||
-          ParseCtorDtorName(state) ||
-          (ParseSourceName(state) && Optional(ParseAbiTags(state))) ||
-          (ParseLocalSourceName(state) && Optional(ParseAbiTags(state))));
-}
-
-// <source-name> ::= <positive length number> <identifier>
-static bool ParseSourceName(State *state) {
-  State copy = *state;
-  int length = -1;
-  if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <local-source-name> ::= L <source-name> [<discriminator>]
-//
-// References:
-//   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
-//   http://gcc.gnu.org/viewcvs?view=rev&revision=124467
-static bool ParseLocalSourceName(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
-      Optional(ParseDiscriminator(state))) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <number> ::= [n] <non-negative decimal integer>
-// If "number_out" is non-null, then *number_out is set to the value of the
-// parsed number on success.
-static bool ParseNumber(State *state, int *number_out) {
-  int sign = 1;
-  if (ParseOneCharToken(state, 'n')) {
-    sign = -1;
-  }
-  const char *p = state->mangled_cur;
-  int number = 0;
-  for (;*p != '\0'; ++p) {
-    if (IsDigit(*p)) {
-      number = number * 10 + (*p - '0');
-    } else {
-      break;
-    }
-  }
-  if (p != state->mangled_cur) {  // Conversion succeeded.
-    state->mangled_cur = p;
-    if (number_out != NULL) {
-      *number_out = number * sign;
-    }
-    return true;
-  }
-  return false;
-}
-
-// Floating-point literals are encoded using a fixed-length lowercase
-// hexadecimal string.
-static bool ParseFloatNumber(State *state) {
-  const char *p = state->mangled_cur;
-  for (;*p != '\0'; ++p) {
-    if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) {
-      break;
-    }
-  }
-  if (p != state->mangled_cur) {  // Conversion succeeded.
-    state->mangled_cur = p;
-    return true;
-  }
-  return false;
-}
-
-// The <seq-id> is a sequence number in base 36,
-// using digits and upper case letters
-static bool ParseSeqId(State *state) {
-  const char *p = state->mangled_cur;
-  for (;*p != '\0'; ++p) {
-    if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
-      break;
-    }
-  }
-  if (p != state->mangled_cur) {  // Conversion succeeded.
-    state->mangled_cur = p;
-    return true;
-  }
-  return false;
-}
-
-// <identifier> ::= <unqualified source code identifier> (of given length)
-static bool ParseIdentifier(State *state, ssize_t length) {
-  if (length == -1 ||
-      !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
-    return false;
-  }
-  if (IdentifierIsAnonymousNamespace(state, length)) {
-    MaybeAppend(state, "(anonymous namespace)");
-  } else {
-    MaybeAppendWithLength(state, state->mangled_cur, length);
-  }
-  state->mangled_cur += length;
-  return true;
-}
-
-// <abi-tags> ::= <abi-tag> [<abi-tags>]
-static bool ParseAbiTags(State *state) {
-  State copy = *state;
-  DisableAppend(state);
-  if (OneOrMore(ParseAbiTag, state)) {
-    RestoreAppend(state, copy.append);
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <abi-tag> ::= B <source-name>
-static bool ParseAbiTag(State *state) {
-  return ParseOneCharToken(state, 'B') && ParseSourceName(state);
-}
-
-// <operator-name> ::= nw, and other two letters cases
-//                 ::= cv <type>  # (cast)
-//                 ::= v  <digit> <source-name> # vendor extended operator
-static bool ParseOperatorName(State *state) {
-  if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) {
-    return false;
-  }
-  // First check with "cv" (cast) case.
-  State copy = *state;
-  if (ParseTwoCharToken(state, "cv") &&
-      MaybeAppend(state, "operator ") &&
-      EnterNestedName(state) &&
-      ParseType(state) &&
-      LeaveNestedName(state, copy.nest_level)) {
-    return true;
-  }
-  *state = copy;
-
-  // Then vendor extended operators.
-  if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") &&
-      ParseSourceName(state)) {
-    return true;
-  }
-  *state = copy;
-
-  // Other operator names should start with a lower alphabet followed
-  // by a lower/upper alphabet.
-  if (!(IsLower(state->mangled_cur[0]) &&
-        IsAlpha(state->mangled_cur[1]))) {
-    return false;
-  }
-  // We may want to perform a binary search if we really need speed.
-  const AbbrevPair *p;
-  for (p = kOperatorList; p->abbrev != NULL; ++p) {
-    if (state->mangled_cur[0] == p->abbrev[0] &&
-        state->mangled_cur[1] == p->abbrev[1]) {
-      MaybeAppend(state, "operator");
-      if (IsLower(*p->real_name)) {  // new, delete, etc.
-        MaybeAppend(state, " ");
-      }
-      MaybeAppend(state, p->real_name);
-      state->mangled_cur += 2;
-      return true;
-    }
-  }
-  return false;
-}
-
-// <special-name> ::= TV <type>
-//                ::= TT <type>
-//                ::= TI <type>
-//                ::= TS <type>
-//                ::= Tc <call-offset> <call-offset> <(base) encoding>
-//                ::= GV <(object) name>
-//                ::= T <call-offset> <(base) encoding>
-// G++ extensions:
-//                ::= TC <type> <(offset) number> _ <(base) type>
-//                ::= TF <type>
-//                ::= TJ <type>
-//                ::= GR <name>
-//                ::= GA <encoding>
-//                ::= Th <call-offset> <(base) encoding>
-//                ::= Tv <call-offset> <(base) encoding>
-//
-// Note: we don't care much about them since they don't appear in
-// stack traces.  The are special data.
-static bool ParseSpecialName(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'T') &&
-      ParseCharClass(state, "VTIS") &&
-      ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) &&
-      ParseCallOffset(state) && ParseEncoding(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "GV") &&
-      ParseName(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) &&
-      ParseEncoding(state)) {
-    return true;
-  }
-  *state = copy;
-
-  // G++ extensions
-  if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
-      ParseNumber(state, NULL) && ParseOneCharToken(state, '_') &&
-      DisableAppend(state) &&
-      ParseType(state)) {
-    RestoreAppend(state, copy.append);
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") &&
-      ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "GR") && ParseName(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") &&
-      ParseCallOffset(state) && ParseEncoding(state)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <call-offset> ::= h <nv-offset> _
-//               ::= v <v-offset> _
-static bool ParseCallOffset(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'h') &&
-      ParseNVOffset(state) && ParseOneCharToken(state, '_')) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'v') &&
-      ParseVOffset(state) && ParseOneCharToken(state, '_')) {
-    return true;
-  }
-  *state = copy;
-
-  return false;
-}
-
-// <nv-offset> ::= <(offset) number>
-static bool ParseNVOffset(State *state) {
-  return ParseNumber(state, NULL);
-}
-
-// <v-offset>  ::= <(offset) number> _ <(virtual offset) number>
-static bool ParseVOffset(State *state) {
-  State copy = *state;
-  if (ParseNumber(state, NULL) && ParseOneCharToken(state, '_') &&
-      ParseNumber(state, NULL)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <ctor-dtor-name> ::= C1 | C2 | C3
-//                  ::= D0 | D1 | D2
-static bool ParseCtorDtorName(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'C') &&
-      ParseCharClass(state, "123")) {
-    const char * const prev_name = state->prev_name;
-    const ssize_t prev_name_length = state->prev_name_length;
-    MaybeAppendWithLength(state, prev_name, prev_name_length);
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'D') &&
-      ParseCharClass(state, "012")) {
-    const char * const prev_name = state->prev_name;
-    const ssize_t prev_name_length = state->prev_name_length;
-    MaybeAppend(state, "~");
-    MaybeAppendWithLength(state, prev_name, prev_name_length);
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <type> ::= <CV-qualifiers> <type>
-//        ::= P <type>   # pointer-to
-//        ::= R <type>   # reference-to
-//        ::= O <type>   # rvalue reference-to (C++0x)
-//        ::= C <type>   # complex pair (C 2000)
-//        ::= G <type>   # imaginary (C 2000)
-//        ::= U <source-name> <type>  # vendor extended type qualifier
-//        ::= <builtin-type>
-//        ::= <function-type>
-//        ::= <class-enum-type>
-//        ::= <array-type>
-//        ::= <pointer-to-member-type>
-//        ::= <template-template-param> <template-args>
-//        ::= <template-param>
-//        ::= <substitution>
-//        ::= Dp <type>          # pack expansion of (C++0x)
-//        ::= Dt <expression> E  # decltype of an id-expression or class
-//                               # member access (C++0x)
-//        ::= DT <expression> E  # decltype of an expression (C++0x)
-//
-static bool ParseType(State *state) {
-  // We should check CV-qualifers, and PRGC things first.
-  State copy = *state;
-  if (ParseCVQualifiers(state) && ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseCharClass(state, "OPRCG") && ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "Dp") && ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") &&
-      ParseExpression(state) && ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'U') && ParseSourceName(state) &&
-      ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseBuiltinType(state) ||
-      ParseFunctionType(state) ||
-      ParseClassEnumType(state) ||
-      ParseArrayType(state) ||
-      ParsePointerToMemberType(state) ||
-      ParseSubstitution(state)) {
-    return true;
-  }
-
-  if (ParseTemplateTemplateParam(state) &&
-      ParseTemplateArgs(state)) {
-    return true;
-  }
-  *state = copy;
-
-  // Less greedy than <template-template-param> <template-args>.
-  if (ParseTemplateParam(state)) {
-    return true;
-  }
-
-  return false;
-}
-
-// <CV-qualifiers> ::= [r] [V] [K]
-// We don't allow empty <CV-qualifiers> to avoid infinite loop in
-// ParseType().
-static bool ParseCVQualifiers(State *state) {
-  int num_cv_qualifiers = 0;
-  num_cv_qualifiers += ParseOneCharToken(state, 'r');
-  num_cv_qualifiers += ParseOneCharToken(state, 'V');
-  num_cv_qualifiers += ParseOneCharToken(state, 'K');
-  return num_cv_qualifiers > 0;
-}
-
-// <builtin-type> ::= v, etc.
-//                ::= u <source-name>
-static bool ParseBuiltinType(State *state) {
-  const AbbrevPair *p;
-  for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) {
-    if (state->mangled_cur[0] == p->abbrev[0]) {
-      MaybeAppend(state, p->real_name);
-      ++state->mangled_cur;
-      return true;
-    }
-  }
-
-  State copy = *state;
-  if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <function-type> ::= F [Y] <bare-function-type> E
-static bool ParseFunctionType(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'F') &&
-      Optional(ParseOneCharToken(state, 'Y')) &&
-      ParseBareFunctionType(state) && ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <bare-function-type> ::= <(signature) type>+
-static bool ParseBareFunctionType(State *state) {
-  State copy = *state;
-  DisableAppend(state);
-  if (OneOrMore(ParseType, state)) {
-    RestoreAppend(state, copy.append);
-    MaybeAppend(state, "()");
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <class-enum-type> ::= <name>
-static bool ParseClassEnumType(State *state) {
-  return ParseName(state);
-}
-
-// <array-type> ::= A <(positive dimension) number> _ <(element) type>
-//              ::= A [<(dimension) expression>] _ <(element) type>
-static bool ParseArrayType(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) &&
-      ParseOneCharToken(state, '_') && ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) &&
-      ParseOneCharToken(state, '_') && ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <pointer-to-member-type> ::= M <(class) type> <(member) type>
-static bool ParsePointerToMemberType(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'M') && ParseType(state) &&
-      ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <template-param> ::= T_
-//                  ::= T <parameter-2 non-negative number> _
-static bool ParseTemplateParam(State *state) {
-  if (ParseTwoCharToken(state, "T_")) {
-    MaybeAppend(state, "?");  // We don't support template substitutions.
-    return true;
-  }
-
-  State copy = *state;
-  if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) &&
-      ParseOneCharToken(state, '_')) {
-    MaybeAppend(state, "?");  // We don't support template substitutions.
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-
-// <template-template-param> ::= <template-param>
-//                           ::= <substitution>
-static bool ParseTemplateTemplateParam(State *state) {
-  return (ParseTemplateParam(state) ||
-          ParseSubstitution(state));
-}
-
-// <template-args> ::= I <template-arg>+ E
-static bool ParseTemplateArgs(State *state) {
-  State copy = *state;
-  DisableAppend(state);
-  if (ParseOneCharToken(state, 'I') &&
-      OneOrMore(ParseTemplateArg, state) &&
-      ParseOneCharToken(state, 'E')) {
-    RestoreAppend(state, copy.append);
-    MaybeAppend(state, "<>");
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <template-arg>  ::= <type>
-//                 ::= <expr-primary>
-//                 ::= I <template-arg>* E        # argument pack
-//                 ::= J <template-arg>* E        # argument pack
-//                 ::= X <expression> E
-static bool ParseTemplateArg(State *state) {
-  State copy = *state;
-  if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
-      ZeroOrMore(ParseTemplateArg, state) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseType(state) ||
-      ParseExprPrimary(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <expression> ::= <template-param>
-//              ::= <expr-primary>
-//              ::= <unary operator-name> <expression>
-//              ::= <binary operator-name> <expression> <expression>
-//              ::= <trinary operator-name> <expression> <expression>
-//                  <expression>
-//              ::= st <type>
-//              ::= sr <type> <unqualified-name> <template-args>
-//              ::= sr <type> <unqualified-name>
-static bool ParseExpression(State *state) {
-  if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
-    return true;
-  }
-
-  State copy = *state;
-  if (ParseOperatorName(state) &&
-      ParseExpression(state) &&
-      ParseExpression(state) &&
-      ParseExpression(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOperatorName(state) &&
-      ParseExpression(state) &&
-      ParseExpression(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOperatorName(state) &&
-      ParseExpression(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "st") && ParseType(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
-      ParseUnqualifiedName(state) &&
-      ParseTemplateArgs(state)) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
-      ParseUnqualifiedName(state)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <expr-primary> ::= L <type> <(value) number> E
-//                ::= L <type> <(value) float> E
-//                ::= L <mangled-name> E
-//                // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
-//                ::= LZ <encoding> E
-static bool ParseExprPrimary(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
-      ParseNumber(state, NULL) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
-      ParseFloatNumber(state) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'L') && ParseMangledName(state) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) &&
-      ParseOneCharToken(state, 'E')) {
-    return true;
-  }
-  *state = copy;
-
-  return false;
-}
-
-// <local-name> := Z <(function) encoding> E <(entity) name>
-//                 [<discriminator>]
-//              := Z <(function) encoding> E s [<discriminator>]
-static bool ParseLocalName(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
-      ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") &&
-      ParseName(state) && Optional(ParseDiscriminator(state))) {
-    return true;
-  }
-  *state = copy;
-
-  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
-      ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <discriminator> := _ <(non-negative) number>
-static bool ParseDiscriminator(State *state) {
-  State copy = *state;
-  if (ParseOneCharToken(state, '_') && ParseNumber(state, NULL)) {
-    return true;
-  }
-  *state = copy;
-  return false;
-}
-
-// <substitution> ::= S_
-//                ::= S <seq-id> _
-//                ::= St, etc.
-static bool ParseSubstitution(State *state) {
-  if (ParseTwoCharToken(state, "S_")) {
-    MaybeAppend(state, "?");  // We don't support substitutions.
-    return true;
-  }
-
-  State copy = *state;
-  if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
-      ParseOneCharToken(state, '_')) {
-    MaybeAppend(state, "?");  // We don't support substitutions.
-    return true;
-  }
-  *state = copy;
-
-  // Expand abbreviations like "St" => "std".
-  if (ParseOneCharToken(state, 'S')) {
-    const AbbrevPair *p;
-    for (p = kSubstitutionList; p->abbrev != NULL; ++p) {
-      if (state->mangled_cur[0] == p->abbrev[1]) {
-        MaybeAppend(state, "std");
-        if (p->real_name[0] != '\0') {
-          MaybeAppend(state, "::");
-          MaybeAppend(state, p->real_name);
-        }
-        ++state->mangled_cur;
-        return true;
-      }
-    }
-  }
-  *state = copy;
-  return false;
-}
-
-// Parse <mangled-name>, optionally followed by either a function-clone suffix
-// or version suffix.  Returns true only if all of "mangled_cur" was consumed.
-static bool ParseTopLevelMangledName(State *state) {
-  if (ParseMangledName(state)) {
-    if (state->mangled_cur[0] != '\0') {
-      // Drop trailing function clone suffix, if any.
-      if (IsFunctionCloneSuffix(state->mangled_cur)) {
-        return true;
-      }
-      // Append trailing version suffix if any.
-      // ex. _Z3foo@@GLIBCXX_3.4
-      if (state->mangled_cur[0] == '@') {
-        MaybeAppend(state, state->mangled_cur);
-        return true;
-      }
-      return false;  // Unconsumed suffix.
-    }
-    return true;
-  }
-  return false;
-}
-#endif
-
-// The demangler entry point.
-bool Demangle(const char *mangled, char *out, size_t out_size) {
-#if defined(GLOG_OS_WINDOWS)
-#if defined(HAVE_DBGHELP)
-  // When built with incremental linking, the Windows debugger
-  // library provides a more complicated `Symbol->Name` with the
-  // Incremental Linking Table offset, which looks like
-  // `@ILT+1105(?func@Foo@@SAXH@Z)`. However, the demangler expects
-  // only the mangled symbol, `?func@Foo@@SAXH@Z`. Fortunately, the
-  // mangled symbol is guaranteed not to have parentheses,
-  // so we search for `(` and extract up to `)`.
-  //
-  // Since we may be in a signal handler here, we cannot use `std::string`.
-  char buffer[1024];  // Big enough for a sane symbol.
-  const char *lparen = strchr(mangled, '(');
-  if (lparen) {
-    // Extract the string `(?...)`
-    const char *rparen = strchr(lparen, ')');
-    size_t length = static_cast<size_t>(rparen - lparen) - 1;
-    strncpy(buffer, lparen + 1, length);
-    buffer[length] = '\0';
-    mangled = buffer;
-  } // Else the symbol wasn't inside a set of parentheses
-  // We use the ANSI version to ensure the string type is always `char *`.
-  return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE);
-#else
-  (void)mangled;
-  (void)out;
-  (void)out_size;
-  return false;
-#endif
-#else
-  State state;
-  InitState(&state, mangled, out, out_size);
-  return ParseTopLevelMangledName(&state) && !state.overflowed;
-#endif
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/demangle.h b/third_party/google-glog/src/demangle.h
deleted file mode 100644
index f347b98..0000000
--- a/third_party/google-glog/src/demangle.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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: Satoru Takabayashi
-//
-// An async-signal-safe and thread-safe demangler for Itanium C++ ABI
-// (aka G++ V3 ABI).
-
-// The demangler is implemented to be used in async signal handlers to
-// symbolize stack traces.  We cannot use libstdc++'s
-// abi::__cxa_demangle() in such signal handlers since it's not async
-// signal safe (it uses malloc() internally).
-//
-// Note that this demangler doesn't support full demangling.  More
-// specifically, it doesn't print types of function parameters and
-// types of template arguments.  It just skips them.  However, it's
-// still very useful to extract basic information such as class,
-// function, constructor, destructor, and operator names.
-//
-// See the implementation note in demangle.cc if you are interested.
-//
-// Example:
-//
-// | Mangled Name  | The Demangler | abi::__cxa_demangle()
-// |---------------|---------------|-----------------------
-// | _Z1fv         | f()           | f()
-// | _Z1fi         | f()           | f(int)
-// | _Z3foo3bar    | foo()         | foo(bar)
-// | _Z1fIiEvi     | f<>()         | void f<int>(int)
-// | _ZN1N1fE      | N::f          | N::f
-// | _ZN3Foo3BarEv | Foo::Bar()    | Foo::Bar()
-// | _Zrm1XS_"     | operator%()   | operator%(X, X)
-// | _ZN3FooC1Ev   | Foo::Foo()    | Foo::Foo()
-// | _Z1fSs        | f()           | f(std::basic_string<char,
-// |               |               |   std::char_traits<char>,
-// |               |               |   std::allocator<char> >)
-//
-// See the unit test for more examples.
-//
-// Note: we might want to write demanglers for ABIs other than Itanium
-// C++ ABI in the future.
-//
-
-#ifndef BASE_DEMANGLE_H_
-#define BASE_DEMANGLE_H_
-
-#include "config.h"
-#include <glog/logging.h>
-
-_START_GOOGLE_NAMESPACE_
-
-// Demangle "mangled".  On success, return true and write the
-// demangled symbol name to "out".  Otherwise, return false.
-// "out" is modified even if demangling is unsuccessful.
-bool GLOG_EXPORT Demangle(const char *mangled, char *out, size_t out_size);
-
-_END_GOOGLE_NAMESPACE_
-
-#endif  // BASE_DEMANGLE_H_
diff --git a/third_party/google-glog/src/demangle_unittest.cc b/third_party/google-glog/src/demangle_unittest.cc
deleted file mode 100644
index ddc90b0..0000000
--- a/third_party/google-glog/src/demangle_unittest.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// 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: Satoru Takabayashi
-//
-// Unit tests for functions in demangle.c.
-
-#include "utilities.h"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <glog/logging.h>
-#include "demangle.h"
-#include "googletest.h"
-#include "config.h"
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-GLOG_DEFINE_bool(demangle_filter, false,
-                 "Run demangle_unittest in filter mode");
-
-using namespace std;
-using namespace GOOGLE_NAMESPACE;
-
-// A wrapper function for Demangle() to make the unit test simple.
-static const char *DemangleIt(const char * const mangled) {
-  static char demangled[4096];
-  if (Demangle(mangled, demangled, sizeof(demangled))) {
-    return demangled;
-  } else {
-    return mangled;
-  }
-}
-
-#if defined(GLOG_OS_WINDOWS)
-
-#if defined(HAVE_DBGHELP) && !defined(NDEBUG)
-TEST(Demangle, Windows) {
-  EXPECT_STREQ(
-    "public: static void __cdecl Foo::func(int)",
-    DemangleIt("?func@Foo@@SAXH@Z"));
-  EXPECT_STREQ(
-    "public: static void __cdecl Foo::func(int)",
-    DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)"));
-  EXPECT_STREQ(
-    "int __cdecl foobarArray(int * const)",
-    DemangleIt("?foobarArray@@YAHQAH@Z"));
-}
-#endif
-
-#else
-
-// Test corner cases of bounary conditions.
-TEST(Demangle, CornerCases) {
-  const size_t size = 10;
-  char tmp[size] = { 0 };
-  const char *demangled = "foobar()";
-  const char *mangled = "_Z6foobarv";
-  EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp)));
-  // sizeof("foobar()") == size - 1
-  EXPECT_STREQ(demangled, tmp);
-  EXPECT_TRUE(Demangle(mangled, tmp, size - 1));
-  EXPECT_STREQ(demangled, tmp);
-  EXPECT_FALSE(Demangle(mangled, tmp, size - 2));  // Not enough.
-  EXPECT_FALSE(Demangle(mangled, tmp, 1));
-  EXPECT_FALSE(Demangle(mangled, tmp, 0));
-  EXPECT_FALSE(Demangle(mangled, NULL, 0));  // Should not cause SEGV.
-}
-
-// Test handling of functions suffixed with .clone.N, which is used by GCC
-// 4.5.x, and .constprop.N and .isra.N, which are used by GCC 4.6.x.  These
-// suffixes are used to indicate functions which have been cloned during
-// optimization.  We ignore these suffixes.
-TEST(Demangle, Clones) {
-  char tmp[20];
-  EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp)));
-  EXPECT_STREQ("Foo()", tmp);
-  EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp)));
-  EXPECT_STREQ("Foo()", tmp);
-  EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp)));
-  EXPECT_STREQ("Foo()", tmp);
-  EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp)));
-  EXPECT_STREQ("Foo()", tmp);
-  EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
-  EXPECT_STREQ("Foo()", tmp);
-  // Invalid (truncated), should not demangle.
-  EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
-  // Invalid (.clone. not followed by number), should not demangle.
-  EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
-  // Invalid (.clone. followed by non-number), should not demangle.
-  EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
-  // Invalid (.constprop. not followed by number), should not demangle.
-  EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
-}
-
-TEST(Demangle, FromFile) {
-  string test_file = FLAGS_test_srcdir + "/src/demangle_unittest.txt";
-  ifstream f(test_file.c_str());  // The file should exist.
-  EXPECT_FALSE(f.fail());
-
-  string line;
-  while (getline(f, line)) {
-    // Lines start with '#' are considered as comments.
-    if (line.empty() || line[0] == '#') {
-      continue;
-    }
-    // Each line should contain a mangled name and a demangled name
-    // separated by '\t'.  Example: "_Z3foo\tfoo"
-    string::size_type tab_pos = line.find('\t');
-    EXPECT_NE(string::npos, tab_pos);
-    string mangled = line.substr(0, tab_pos);
-    string demangled = line.substr(tab_pos + 1);
-    EXPECT_EQ(demangled, DemangleIt(mangled.c_str()));
-  }
-}
-
-#endif
-
-int main(int argc, char **argv) {
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-  InitGoogleTest(&argc, argv);
-
-  FLAGS_logtostderr = true;
-  InitGoogleLogging(argv[0]);
-  if (FLAGS_demangle_filter) {
-    // Read from cin and write to cout.
-    string line;
-    while (getline(cin, line, '\n')) {
-      cout << DemangleIt(line.c_str()) << endl;
-    }
-    return 0;
-  } else if (argc > 1) {
-    cout << DemangleIt(argv[1]) << endl;
-    return 0;
-  } else {
-    return RUN_ALL_TESTS();
-  }
-}
diff --git a/third_party/google-glog/src/demangle_unittest.sh b/third_party/google-glog/src/demangle_unittest.sh
deleted file mode 100755
index 91deee2..0000000
--- a/third_party/google-glog/src/demangle_unittest.sh
+++ /dev/null
@@ -1,95 +0,0 @@
-#! /bin/sh
-#
-# 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: Satoru Takabayashi
-#
-# Unit tests for demangle.c with a real binary.
-
-set -e
-
-die () {
-    echo $1
-    exit 1
-}
-
-BINDIR=".libs"
-LIBGLOG="$BINDIR/libglog.so"
-
-DEMANGLER="$BINDIR/demangle_unittest"
-
-if test -e "$DEMANGLER"; then
-  # We need shared object.
-  export LD_LIBRARY_PATH=$BINDIR
-  export DYLD_LIBRARY_PATH=$BINDIR
-else
-  # For windows
-  DEMANGLER="./demangle_unittest.exe"
-  if ! test -e "$DEMANGLER"; then
-    echo "We coundn't find demangle_unittest binary."
-    exit 1
-  fi
-fi
-
-# Extract C++ mangled symbols from libbase.so.
-NM_OUTPUT="demangle.nm"
-nm "$LIBGLOG" | perl -nle 'print $1 if /\s(_Z\S+$)/' > "$NM_OUTPUT"
-
-# Check if mangled symbols exist. If there are none, we quit.
-# The binary is more likely compiled with GCC 2.95 or something old.
-if ! grep --quiet '^_Z' "$NM_OUTPUT"; then
-    echo "PASS"
-    exit 0
-fi
-
-# Demangle the symbols using our demangler.
-DM_OUTPUT="demangle.dm"
-GLOG_demangle_filter=1 "$DEMANGLER" --demangle_filter < "$NM_OUTPUT" > "$DM_OUTPUT"
-
-# Calculate the numbers of lines.
-NM_LINES=`wc -l "$NM_OUTPUT" | awk '{ print $1 }'`
-DM_LINES=`wc -l "$DM_OUTPUT" | awk '{ print $1 }'`
-
-# Compare the numbers of lines.  They must be the same.
-if test "$NM_LINES" != "$DM_LINES"; then
-    die "$NM_OUTPUT and $DM_OUTPUT don't have the same numbers of lines"
-fi
-
-# Check if mangled symbols exist.  They must not exist.
-if grep --quiet '^_Z' "$DM_OUTPUT"; then
-    MANGLED=`grep '^_Z' "$DM_OUTPUT" | wc -l | awk '{ print \$1 }'`
-    echo "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT:"
-    grep '^_Z' "$DM_OUTPUT"
-    die "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT"
-fi
-
-# All C++ symbols are demangled successfully.
-echo "PASS"
-exit 0
diff --git a/third_party/google-glog/src/demangle_unittest.txt b/third_party/google-glog/src/demangle_unittest.txt
deleted file mode 100644
index 07e28bc..0000000
--- a/third_party/google-glog/src/demangle_unittest.txt
+++ /dev/null
@@ -1,145 +0,0 @@
-# Test caces for demangle_unittest.  Each line consists of a
-# tab-separated pair of mangled and demangled symbol names.
-
-# Constructors and destructors.
-_ZN3FooC1Ev	Foo::Foo()
-_ZN3FooD1Ev	Foo::~Foo()
-_ZNSoD0Ev	std::ostream::~ostream()
-
-# G++ extensions.
-_ZTCN10LogMessage9LogStreamE0_So	LogMessage::LogStream
-_ZTv0_n12_N10LogMessage9LogStreamD0Ev	LogMessage::LogStream::~LogStream()
-_ZThn4_N7icu_3_410UnicodeSetD0Ev	icu_3_4::UnicodeSet::~UnicodeSet()
-
-# A bug in g++'s C++ ABI version 2 (-fabi-version=2).
-_ZN7NSSInfoI5groupjjXadL_Z10getgrgid_rEELZ19nss_getgrgid_r_nameEEC1Ei	NSSInfo<>::NSSInfo()
-
-# C linkage symbol names.  Should keep them untouched.
-main	main
-Demangle	Demangle
-_ZERO	_ZERO
-
-# Cast operator.
-_Zcviv	operator int()
-_ZN3foocviEv	foo::operator int()
-
-# Versioned symbols.
-_Z3Foo@GLIBCXX_3.4	Foo@GLIBCXX_3.4
-_Z3Foo@@GLIBCXX_3.4	Foo@@GLIBCXX_3.4
-
-# Abbreviations.
-_ZNSaE	std::allocator
-_ZNSbE	std::basic_string
-_ZNSdE	std::iostream
-_ZNSiE	std::istream
-_ZNSoE	std::ostream
-_ZNSsE	std::string
-
-# Substitutions.  We just replace them with ?.
-_ZN3fooS_E	foo::?
-_ZN3foo3barS0_E	foo::bar::?
-_ZNcvT_IiEEv	operator ?<>()
-
-# "<< <" case.
-_ZlsI3fooE	operator<< <>
-
-# ABI tags.
-_Z1AB3barB3foo	A
-_ZN3fooL3barB5cxx11E	foo::bar
-
-# Random things we found interesting.
-_ZN3FooISt6vectorISsSaISsEEEclEv	Foo<>::operator()()
-_ZTI9Callback1IiE	Callback1<>
-_ZN7icu_3_47UMemorynwEj	icu_3_4::UMemory::operator new()
-_ZNSt6vectorIbE9push_backE	std::vector<>::push_back
-_ZNSt6vectorIbSaIbEE9push_backEb	std::vector<>::push_back()
-_ZlsRSoRK15PRIVATE_Counter	operator<<()
-_ZSt6fill_nIPPN9__gnu_cxx15_Hashtable_nodeISt4pairIKPKcjEEEjS8_ET_SA_T0_RKT1_	std::fill_n<>()
-_ZZ3FoovE3Bar	Foo()::Bar
-_ZGVZ7UpTimervE8up_timer	UpTimer()::up_timer
-
-# Test cases from gcc-4.1.0/libstdc++-v3/testsuite/demangle.
-# Collected by:
-# % grep verify_demangle **/*.cc | perl -nle 'print $1 if /"(_Z.*?)"/' |
-#   sort | uniq
-#
-# Note that the following symbols are invalid.
-# That's why they are not demangled.
-# - _ZNZN1N1fEiE1X1gE
-# - _ZNZN1N1fEiE1X1gEv
-# - _Z1xINiEE
-_Z1fA37_iPS_	f()
-_Z1fAszL_ZZNK1N1A1fEvE3foo_0E_i	f()
-_Z1fI1APS0_PKS0_EvT_T0_T1_PA4_S3_M1CS8_	f<>()
-_Z1fI1XENT_1tES2_	f<>()
-_Z1fI1XEvPVN1AIT_E1TE	f<>()
-_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE	f<>()
-_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE	f<>()
-_Z1fILi5E1AEvN1CIXqugtT_Li0ELi1ELi2EEE1qE	f<>()
-_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE	f<>()
-_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE	f<>()
-_Z1fIiEvi	f<>()
-_Z1fKPFiiE	f()
-_Z1fM1AFivEPS0_	f()
-_Z1fM1AKFivE	f()
-_Z1fM1AKFvvE	f()
-_Z1fPFPA1_ivE	f()
-_Z1fPFYPFiiEiE	f()
-_Z1fPFvvEM1SFvvE	f()
-_Z1fPKM1AFivE	f()
-_Z1fi	f()
-_Z1fv	f()
-_Z1jM1AFivEPS1_	j()
-_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_	r()
-_Z1sPA37_iPS0_	s()
-_Z1xINiEE	_Z1xINiEE
-_Z3absILi11EEvv	abs<>()
-_Z3foo3bar	foo()
-_Z3foo5Hello5WorldS0_S_	foo()
-_Z3fooA30_A_i	foo()
-_Z3fooIA6_KiEvA9_KT_rVPrS4_	foo<>()
-_Z3fooILi2EEvRAplT_Li1E_i	foo<>()
-_Z3fooIiFvdEiEvv	foo<>()
-_Z3fooPM2ABi	foo()
-_Z3fooc	foo()
-_Z3fooiPiPS_PS0_PS1_PS2_PS3_PS4_PS5_PS6_PS7_PS8_PS9_PSA_PSB_PSC_	foo()
-_Z3kooPA28_A30_i	koo()
-_Z4makeI7FactoryiET_IT0_Ev	make<>()
-_Z5firstI3DuoEvS0_	first<>()
-_Z5firstI3DuoEvT_	first<>()
-_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE	hairyfunc()
-_ZGVN5libcw24_GLOBAL__N_cbll.cc0ZhUKa23compiler_bug_workaroundISt6vectorINS_13omanip_id_tctINS_5debug32memblk_types_manipulator_data_ctEEESaIS6_EEE3idsE	libcw::(anonymous namespace)::compiler_bug_workaround<>::ids
-_ZN12libcw_app_ct10add_optionIS_EEvMT_FvPKcES3_cS3_S3_	libcw_app_ct::add_option<>()
-_ZN1AIfEcvT_IiEEv	A<>::operator ?<>()
-_ZN1N1TIiiE2mfES0_IddE	N::T<>::mf()
-_ZN1N1fE	N::f
-_ZN1f1fE	f::f
-_ZN3FooIA4_iE3barE	Foo<>::bar
-_ZN5Arena5levelE	Arena::level
-_ZN5StackIiiE5levelE	Stack<>::level
-_ZN5libcw5debug13cwprint_usingINS_9_private_12GlobalObjectEEENS0_17cwprint_using_tctIT_EERKS5_MS5_KFvRSt7ostreamE	libcw::debug::cwprint_using<>()
-_ZN6System5Sound4beepEv	System::Sound::beep()
-_ZNKSt14priority_queueIP27timer_event_request_base_ctSt5dequeIS1_SaIS1_EE13timer_greaterE3topEv	std::priority_queue<>::top()
-_ZNKSt15_Deque_iteratorIP15memory_block_stRKS1_PS2_EeqERKS5_	std::_Deque_iterator<>::operator==()
-_ZNKSt17__normal_iteratorIPK6optionSt6vectorIS0_SaIS0_EEEmiERKS6_	std::__normal_iterator<>::operator-()
-_ZNSbIcSt11char_traitsIcEN5libcw5debug27no_alloc_checking_allocatorEE12_S_constructIPcEES6_T_S7_RKS3_	std::basic_string<>::_S_construct<>()
-_ZNSt13_Alloc_traitsISbIcSt18string_char_traitsIcEN5libcw5debug9_private_17allocator_adaptorIcSt24__default_alloc_templateILb0ELi327664EELb1EEEENS5_IS9_S7_Lb1EEEE15_S_instancelessE	std::_Alloc_traits<>::_S_instanceless
-_ZNSt3_In4wardE	std::_In::ward
-_ZNZN1N1fEiE1X1gE	_ZNZN1N1fEiE1X1gE
-_ZNZN1N1fEiE1X1gEv	_ZNZN1N1fEiE1X1gEv
-_ZSt1BISt1DIP1ARKS2_PS3_ES0_IS2_RS2_PS2_ES2_ET0_T_SB_SA_PT1_	std::B<>()
-_ZSt5state	std::state
-_ZTI7a_class	a_class
-_ZZN1N1fEiE1p	N::f()::p
-_ZZN1N1fEiEs	N::f()
-_ZlsRK1XS1_	operator<<()
-_ZlsRKU3fooU4bart1XS0_	operator<<()
-_ZlsRKU3fooU4bart1XS2_	operator<<()
-_ZlsRSoRKSs	operator<<()
-_ZngILi42EEvN1AIXplT_Li2EEE1TE	operator-<>()
-_ZplR1XS0_	operator+()
-_Zrm1XS_	operator%()
-
-# Template argument packs can start with I or J.
-_Z3addIIiEEvDpT_	add<>()
-_Z3addIJiEEvDpT_	add<>()
diff --git a/third_party/google-glog/src/glog/log_severity.h b/third_party/google-glog/src/glog/log_severity.h
deleted file mode 100644
index aa48f53..0000000
--- a/third_party/google-glog/src/glog/log_severity.h
+++ /dev/null
@@ -1,98 +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.
-
-#ifndef BASE_LOG_SEVERITY_H__
-#define BASE_LOG_SEVERITY_H__
-
-// The recommended semantics of the log levels are as follows:
-//
-// INFO:
-//   Use for state changes or other major events, or to aid debugging.
-// WARNING:
-//   Use for undesired but relatively expected events, which may indicate a
-//   problem
-// ERROR:
-//   Use for undesired and unexpected events that the program can recover from.
-//   All ERRORs should be actionable - it should be appropriate to file a bug
-//   whenever an ERROR occurs in production.
-// FATAL:
-//   Use for undesired and unexpected events that the program cannot recover
-//   from.
-
-// Variables of type LogSeverity are widely taken to lie in the range
-// [0, NUM_SEVERITIES-1].  Be careful to preserve this assumption if
-// you ever need to change their values or add a new severity.
-typedef int LogSeverity;
-
-const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
-  NUM_SEVERITIES = 4;
-#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
-# ifdef ERROR
-#  error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail.
-# endif
-const int INFO = GLOG_INFO, WARNING = GLOG_WARNING,
-  ERROR = GLOG_ERROR, FATAL = GLOG_FATAL;
-#endif
-
-// DFATAL is FATAL in debug mode, ERROR in normal mode
-#ifdef NDEBUG
-#define DFATAL_LEVEL ERROR
-#else
-#define DFATAL_LEVEL FATAL
-#endif
-
-extern GLOG_EXPORT const char* const LogSeverityNames[NUM_SEVERITIES];
-
-// NDEBUG usage helpers related to (RAW_)DCHECK:
-//
-// DEBUG_MODE is for small !NDEBUG uses like
-//   if (DEBUG_MODE) foo.CheckThatFoo();
-// instead of substantially more verbose
-//   #ifndef NDEBUG
-//     foo.CheckThatFoo();
-//   #endif
-//
-// IF_DEBUG_MODE is for small !NDEBUG uses like
-//   IF_DEBUG_MODE( string error; )
-//   DCHECK(Foo(&error)) << error;
-// instead of substantially more verbose
-//   #ifndef NDEBUG
-//     string error;
-//     DCHECK(Foo(&error)) << error;
-//   #endif
-//
-#ifdef NDEBUG
-enum { DEBUG_MODE = 0 };
-#define IF_DEBUG_MODE(x)
-#else
-enum { DEBUG_MODE = 1 };
-#define IF_DEBUG_MODE(x) x
-#endif
-
-#endif  // BASE_LOG_SEVERITY_H__
diff --git a/third_party/google-glog/src/glog/logging.h.in b/third_party/google-glog/src/glog/logging.h.in
deleted file mode 100644
index 8a26cbc..0000000
--- a/third_party/google-glog/src/glog/logging.h.in
+++ /dev/null
@@ -1,1979 +0,0 @@
-// Copyright (c) 2022, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Ray Sidney
-//
-// 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 GLOG_LOGGING_H
-#define GLOG_LOGGING_H
-
-#if @ac_cv_cxx11_chrono@ && __cplusplus >= 201103L
-#include <chrono>
-#endif
-
-#include <cerrno>
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-#include <iosfwd>
-#include <ostream>
-#include <sstream>
-#include <string>
-#if @ac_cv_have_unistd_h@
-# include <unistd.h>
-#endif
-#include <vector>
-
-#if defined(_MSC_VER)
-#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \
-                                     __pragma(warning(disable:n))
-#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
-#else
-#define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
-#define GLOG_MSVC_POP_WARNING()
-#endif
-
-#include <glog/platform.h>
-
-#if @ac_cv_have_glog_export@
-#include <glog/export.h>
-#endif
-
-// We care a lot about number of bits things take up.  Unfortunately,
-// systems define their bit-specific ints in a lot of different ways.
-// We use our own way, and have a typedef to get there.
-// Note: these commands below may look like "#if 1" or "#if 0", but
-// that's because they were constructed that way at ./configure time.
-// Look at logging.h.in to see how they're calculated (based on your config).
-#if @ac_cv_have_stdint_h@
-#include <stdint.h>             // the normal place uint16_t is defined
-#endif
-#if @ac_cv_have_systypes_h@
-#include <sys/types.h>          // the normal place u_int16_t is defined
-#endif
-#if @ac_cv_have_inttypes_h@
-#include <inttypes.h>           // a third place for uint16_t or u_int16_t
-#endif
-
-#if @ac_cv_have_libgflags@
-#include <gflags/gflags.h>
-#endif
-
-#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L
-#include <atomic>
-#elif defined(GLOG_OS_WINDOWS)
-#include <Windows.h>
-#endif
-
-@ac_google_start_namespace@
-
-#if @ac_cv_have_stdint_h@      // the C99 format
-typedef int32_t int32;
-typedef uint32_t uint32;
-typedef int64_t int64;
-typedef uint64_t uint64;
-#elif @ac_cv_have_u_int16_t@   // the BSD format
-typedef int32_t int32;
-typedef u_int32_t uint32;
-typedef int64_t int64;
-typedef u_int64_t uint64;
-#elif @ac_cv_have___uint16@    // the windows (vc7) format
-typedef __int32 int32;
-typedef unsigned __int32 uint32;
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
-#error Do not know how to define a 32-bit integer quantity on your system
-#endif
-
-#if !(@ac_cv_have_ssize_t@)
-typedef ptrdiff_t ssize_t;
-#endif
-
-#if !(@ac_cv_have_mode_t@)
-typedef int mode_t;
-#endif
-
-typedef double WallTime;
-
-struct GLOG_EXPORT LogMessageTime {
-  LogMessageTime();
-  LogMessageTime(std::tm t);
-  LogMessageTime(std::time_t timestamp, WallTime now);
-
-  const time_t& timestamp() const { return timestamp_; }
-  const int& sec() const { return time_struct_.tm_sec; }
-  const int32_t& usec() const { return usecs_; }
-  const int&(min)() const { return time_struct_.tm_min; }
-  const int& hour() const { return time_struct_.tm_hour; }
-  const int& day() const { return time_struct_.tm_mday; }
-  const int& month() const { return time_struct_.tm_mon; }
-  const int& year() const { return time_struct_.tm_year; }
-  const int& dayOfWeek() const { return time_struct_.tm_wday; }
-  const int& dayInYear() const { return time_struct_.tm_yday; }
-  const int& dst() const { return time_struct_.tm_isdst; }
-  const long int& gmtoff() const { return gmtoffset_; }
-  const std::tm& tm() const { return time_struct_; }
-
- private:
-  void init(const std::tm& t, std::time_t timestamp, WallTime now);
-  std::tm time_struct_;  // Time of creation of LogMessage
-  time_t timestamp_;     // Time of creation of LogMessage in seconds
-  int32_t usecs_;        // Time of creation of LogMessage - microseconds part
-  long int gmtoffset_;
-
-  void CalcGmtOffset();
-};
-
-#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
-struct LogMessageInfo {
-  explicit LogMessageInfo(const char* const severity_,
-                          const char* const filename_,
-                          const int& line_number_,
-                          const int& thread_id_,
-                          const LogMessageTime& time_):
-      severity(severity_), filename(filename_), line_number(line_number_),
-      thread_id(thread_id_), time(time_)
-  {}
-
-  const char* const severity;
-  const char* const filename;
-  const int &line_number;
-  const int &thread_id;
-  const LogMessageTime& time;
-};
-
-typedef void(*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l, void* data);
-
-#endif
-
-@ac_google_end_namespace@
-
-
-// The global value of GOOGLE_STRIP_LOG. All the messages logged to
-// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed.
-// If it can be determined at compile time that the message will not be
-// printed, the statement will be compiled out.
-//
-// Example: to strip out all INFO and WARNING messages, use the value
-// of 2 below. To make an exception for WARNING messages from a single
-// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including
-// base/logging.h
-#ifndef GOOGLE_STRIP_LOG
-#define GOOGLE_STRIP_LOG 0
-#endif
-
-// GCC can be told that a certain branch is not likely to be taken (for
-// instance, a CHECK failure), and use that information in static analysis.
-// Giving it this information can help it optimize for the common case in
-// the absence of better information (ie. -fprofile-arcs).
-//
-#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
-#if @ac_cv_have___builtin_expect@
-#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
-#else
-#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
-#endif
-#endif
-
-#ifndef GOOGLE_PREDICT_FALSE
-#if @ac_cv_have___builtin_expect@
-#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
-#else
-#define GOOGLE_PREDICT_FALSE(x) x
-#endif
-#endif
-
-#ifndef GOOGLE_PREDICT_TRUE
-#if @ac_cv_have___builtin_expect@
-#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
-#else
-#define GOOGLE_PREDICT_TRUE(x) x
-#endif
-#endif
-
-
-// Make a bunch of macros for logging.  The way to log things is to stream
-// things to LOG(<a particular severity level>).  E.g.,
-//
-//   LOG(INFO) << "Found " << num_cookies << " cookies";
-//
-// You can capture log messages in a string, rather than reporting them
-// immediately:
-//
-//   vector<string> errors;
-//   LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num;
-//
-// This pushes back the new error onto 'errors'; if given a NULL pointer,
-// it reports the error via LOG(ERROR).
-//
-// You can also do conditional logging:
-//
-//   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-//
-// You can also do occasional logging (log every n'th occurrence of an
-// event):
-//
-//   LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
-//
-// The above will cause log messages to be output on the 1st, 11th, 21st, ...
-// times it is executed.  Note that the special google::COUNTER value is used
-// to identify which repetition is happening.
-//
-// You can also do occasional conditional logging (log every n'th
-// occurrence of an event, when condition is satisfied):
-//
-//   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER
-//                                           << "th big cookie";
-//
-// You can log messages the first N times your code executes a line. E.g.
-//
-//   LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie";
-//
-// Outputs log messages for the first 20 times it is executed.
-//
-// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available.
-// These log to syslog as well as to the normal logs.  If you use these at
-// all, you need to be aware that syslog can drastically reduce performance,
-// especially if it is configured for remote logging!  Don't use these
-// unless you fully understand this and have a concrete need to use them.
-// Even then, try to minimize your use of them.
-//
-// There are also "debug mode" logging macros like the ones above:
-//
-//   DLOG(INFO) << "Found cookies";
-//
-//   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-//
-//   DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
-//
-// All "debug mode" logging is compiled away to nothing for non-debug mode
-// compiles.
-//
-// We also have
-//
-//   LOG_ASSERT(assertion);
-//   DLOG_ASSERT(assertion);
-//
-// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
-//
-// There are "verbose level" logging macros.  They look like
-//
-//   VLOG(1) << "I'm printed when you run the program with --v=1 or more";
-//   VLOG(2) << "I'm printed when you run the program with --v=2 or more";
-//
-// These always log at the INFO log level (when they log at all).
-// The verbose logging can also be turned on module-by-module.  For instance,
-//    --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
-// will cause:
-//   a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc}
-//   b. VLOG(1) and lower messages to be printed from file.{h,cc}
-//   c. VLOG(3) and lower messages to be printed from files prefixed with "gfs"
-//   d. VLOG(0) and lower messages to be printed from elsewhere
-//
-// The wildcarding functionality shown by (c) supports both '*' (match
-// 0 or more characters) and '?' (match any single character) wildcards.
-//
-// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
-//
-//   if (VLOG_IS_ON(2)) {
-//     // do some logging preparation and logging
-//     // that can't be accomplished with just VLOG(2) << ...;
-//   }
-//
-// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level"
-// condition macros for sample cases, when some extra computation and
-// preparation for logs is not needed.
-//   VLOG_IF(1, (size > 1024))
-//      << "I'm printed when size is more than 1024 and when you run the "
-//         "program with --v=1 or more";
-//   VLOG_EVERY_N(1, 10)
-//      << "I'm printed every 10th occurrence, and when you run the program "
-//         "with --v=1 or more. Present occurence is " << google::COUNTER;
-//   VLOG_IF_EVERY_N(1, (size > 1024), 10)
-//      << "I'm printed on every 10th occurence of case when size is more "
-//         " than 1024, when you run the program with --v=1 or more. ";
-//         "Present occurence is " << google::COUNTER;
-//
-// The supported severity levels for macros that allow you to specify one
-// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
-// Note that messages of a given severity are logged not only in the
-// logfile for that severity, but also in all logfiles of lower severity.
-// E.g., a message of severity FATAL will be logged to the logfiles of
-// severity FATAL, ERROR, WARNING, and INFO.
-//
-// There is also the special severity of DFATAL, which logs FATAL in
-// debug mode, ERROR in normal mode.
-//
-// Very important: logging a message at the FATAL severity level causes
-// the program to terminate (after the message is logged).
-//
-// Unless otherwise specified, logs will be written to the filename
-// "<program name>.<hostname>.<user name>.log.<severity level>.", followed
-// by the date, time, and pid (you can't prevent the date, time, and pid
-// from being in the filename).
-//
-// The logging code takes two flags:
-//     --v=#           set the verbose level
-//     --logtostderr   log all the messages to stderr instead of to logfiles
-
-// LOG LINE PREFIX FORMAT
-//
-// Log lines have this form:
-//
-//     Lyyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg...
-//
-// where the fields are defined as follows:
-//
-//   L                A single character, representing the log level
-//                    (eg 'I' for INFO)
-//   yyyy             The year
-//   mm               The month (zero padded; ie May is '05')
-//   dd               The day (zero padded)
-//   hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
-//   threadid         The space-padded thread ID as returned by GetTID()
-//                    (this matches the PID on Linux)
-//   file             The file name
-//   line             The line number
-//   msg              The user-supplied message
-//
-// Example:
-//
-//   I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog
-//   I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395
-//
-// NOTE: although the microseconds are useful for comparing events on
-// a single machine, clocks on different machines may not be well
-// synchronized.  Hence, use caution when comparing the low bits of
-// timestamps from different machines.
-
-#pragma push_macro("DECLARE_VARIABLE")
-#pragma push_macro("DECLARE_bool")
-#pragma push_macro("DECLARE_string")
-#pragma push_macro("DECLARE_int32")
-#pragma push_macro("DECLARE_uint32")
-
-#ifdef DECLARE_VARIABLE
-#undef DECLARE_VARIABLE
-#endif
-
-#ifdef DECLARE_bool
-#undef DECLARE_bool
-#endif
-
-#ifdef DECLARE_string
-#undef DECLARE_string
-#endif
-
-#ifdef DECLARE_int32
-#undef DECLARE_int32
-#endif
-
-#ifdef DECLARE_uint32
-#undef DECLARE_uint32
-#endif
-
-#ifndef DECLARE_VARIABLE
-#define DECLARE_VARIABLE(type, shorttype, name, tn)                     \
-  namespace fL##shorttype {                                             \
-    extern GLOG_EXPORT type FLAGS_##name;                      \
-  }                                                                     \
-  using fL##shorttype::FLAGS_##name
-
-// bool specialization
-#define DECLARE_bool(name) \
-  DECLARE_VARIABLE(bool, B, name, bool)
-
-// int32 specialization
-#define DECLARE_int32(name) \
-  DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name, int32)
-
-#if !defined(DECLARE_uint32)
-// uint32 specialization
-#define DECLARE_uint32(name) \
-  DECLARE_VARIABLE(@ac_google_namespace@::uint32, U, name, uint32)
-#endif // !defined(DECLARE_uint32) && !(@ac_cv_have_libgflags@)
-
-// 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 fLS {                                                       \
-    extern GLOG_EXPORT std::string& FLAGS_##name;              \
-  }                                                                     \
-  using fLS::FLAGS_##name
-#endif
-
-// Set whether appending a timestamp to the log file name
-DECLARE_bool(timestamp_in_logfile_name);
-
-// Set whether log messages go to stdout instead of logfiles
-DECLARE_bool(logtostdout);
-
-// Set color messages logged to stdout (if supported by terminal).
-DECLARE_bool(colorlogtostdout);
-
-// Set whether log messages go to stderr instead of logfiles
-DECLARE_bool(logtostderr);
-
-// Set whether log messages go to stderr in addition to logfiles.
-DECLARE_bool(alsologtostderr);
-
-// Set color messages logged to stderr (if supported by terminal).
-DECLARE_bool(colorlogtostderr);
-
-// Log messages at a level >= this flag are automatically sent to
-// stderr in addition to log files.
-DECLARE_int32(stderrthreshold);
-
-// Set whether the log prefix should be prepended to each line of output.
-DECLARE_bool(log_prefix);
-
-// Set whether the year should be included in the log prefix.
-DECLARE_bool(log_year_in_prefix);
-
-// Log messages at a level <= this flag are buffered.
-// Log messages at a higher level are flushed immediately.
-DECLARE_int32(logbuflevel);
-
-// Sets the maximum number of seconds which logs may be buffered for.
-DECLARE_int32(logbufsecs);
-
-// Log suppression level: messages logged at a lower level than this
-// are suppressed.
-DECLARE_int32(minloglevel);
-
-// If specified, logfiles are written into this directory instead of the
-// default logging directory.
-DECLARE_string(log_dir);
-
-// Set the log file mode.
-DECLARE_int32(logfile_mode);
-
-// Sets the path of the directory into which to put additional links
-// to the log files.
-DECLARE_string(log_link);
-
-DECLARE_int32(v);  // in vlog_is_on.cc
-
-DECLARE_string(vmodule); // also in vlog_is_on.cc
-
-// Sets the maximum log file size (in MB).
-DECLARE_uint32(max_log_size);
-
-// Sets whether to avoid logging to the disk if the disk is full.
-DECLARE_bool(stop_logging_if_full_disk);
-
-// Use UTC time for logging
-DECLARE_bool(log_utc_time);
-
-// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
-// security reasons. See LOG(severtiy) below.
-
-// A few definitions of macros that don't generate much code.  Since
-// LOG(INFO) and its ilk are used all over our code, it's
-// better to have compact code for these operations.
-
-#if GOOGLE_STRIP_LOG == 0
-#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__)
-#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, message)
-#else
-#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::NullStream()
-#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::NullStream()
-#endif
-
-#if GOOGLE_STRIP_LOG <= 1
-#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING)
-#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, message)
-#else
-#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::NullStream()
-#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::NullStream()
-#endif
-
-#if GOOGLE_STRIP_LOG <= 2
-#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR)
-#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, message)
-#else
-#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::NullStream()
-#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::NullStream()
-#endif
-
-#if GOOGLE_STRIP_LOG <= 3
-#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::LogMessageFatal( \
-      __FILE__, __LINE__)
-#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, message)
-#else
-#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::NullStreamFatal()
-#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::NullStreamFatal()
-#endif
-
-#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
-#define DCHECK_IS_ON() 0
-#else
-#define DCHECK_IS_ON() 1
-#endif
-
-// For DFATAL, we want to use LogMessage (as opposed to
-// LogMessageFatal), to be consistent with the original behavior.
-#if !DCHECK_IS_ON()
-#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
-#elif GOOGLE_STRIP_LOG <= 3
-#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::LogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL)
-#else
-#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::NullStreamFatal()
-#endif
-
-#define GOOGLE_LOG_INFO(counter) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, &@ac_google_namespace@::LogMessage::SendToLog)
-#define SYSLOG_INFO(counter) \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, \
-  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
-#define GOOGLE_LOG_WARNING(counter)  \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \
-  &@ac_google_namespace@::LogMessage::SendToLog)
-#define SYSLOG_WARNING(counter)  \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \
-  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
-#define GOOGLE_LOG_ERROR(counter)  \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \
-  &@ac_google_namespace@::LogMessage::SendToLog)
-#define SYSLOG_ERROR(counter)  \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \
-  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
-#define GOOGLE_LOG_FATAL(counter) \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \
-  &@ac_google_namespace@::LogMessage::SendToLog)
-#define SYSLOG_FATAL(counter) \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \
-  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
-#define GOOGLE_LOG_DFATAL(counter) \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \
-  &@ac_google_namespace@::LogMessage::SendToLog)
-#define SYSLOG_DFATAL(counter) \
-  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \
-  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
-
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-// A very useful logging macro to log windows errors:
-#define LOG_SYSRESULT(result) \
-  if (FAILED(HRESULT_FROM_WIN32(result))) { \
-    LPSTR message = NULL; \
-    LPSTR msg = reinterpret_cast<LPSTR>(&message); \
-    DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
-                         FORMAT_MESSAGE_FROM_SYSTEM | \
-                         FORMAT_MESSAGE_IGNORE_INSERTS, \
-                         0, result, 0, msg, 100, NULL); \
-    if (message_length > 0) { \
-      @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, 0, \
-          &@ac_google_namespace@::LogMessage::SendToLog).stream() \
-          << reinterpret_cast<const char*>(message); \
-      LocalFree(message); \
-    } \
-  }
-#endif
-
-// We use the preprocessor's merging operator, "##", so that, e.g.,
-// LOG(INFO) becomes the token GOOGLE_LOG_INFO.  There's some funny
-// subtle difference between ostream member streaming functions (e.g.,
-// ostream::operator<<(int) and ostream non-member streaming functions
-// (e.g., ::operator<<(ostream&, string&): it turns out that it's
-// impossible to stream something like a string directly to an unnamed
-// ostream. We employ a neat hack by calling the stream() member
-// function of LogMessage which seems to avoid the problem.
-#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
-#define SYSLOG(severity) SYSLOG_ ## severity(0).stream()
-
-@ac_google_start_namespace@
-
-// They need the definitions of integer types.
-#include <glog/log_severity.h>
-#include <glog/vlog_is_on.h>
-
-// Initialize google's logging library. You will see the program name
-// specified by argv0 in log outputs.
-GLOG_EXPORT void InitGoogleLogging(const char* argv0);
-
-#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
-GLOG_EXPORT void InitGoogleLogging(const char* argv0,
-                                   CustomPrefixCallback prefix_callback,
-                                   void* prefix_callback_data = NULL);
-#endif
-
-// Check if google's logging library has been initialized.
-GLOG_EXPORT bool IsGoogleLoggingInitialized();
-
-// Shutdown google's logging library.
-GLOG_EXPORT void ShutdownGoogleLogging();
-
-#if defined(__GNUC__)
-typedef void (*logging_fail_func_t)() __attribute__((noreturn));
-#else
-typedef void (*logging_fail_func_t)();
-#endif
-
-// Install a function which will be called after LOG(FATAL).
-GLOG_EXPORT void InstallFailureFunction(logging_fail_func_t fail_func);
-
-// Enable/Disable old log cleaner.
-GLOG_EXPORT void EnableLogCleaner(unsigned int overdue_days);
-GLOG_EXPORT void DisableLogCleaner();
-GLOG_EXPORT void SetApplicationFingerprint(const std::string& fingerprint);
-
-class LogSink;  // defined below
-
-// If a non-NULL sink pointer is given, we push this message to that sink.
-// For LOG_TO_SINK we then do normal LOG(severity) logging as well.
-// This is useful for capturing messages and passing/storing them
-// somewhere more specific than the global log of the process.
-// Argument types:
-//   LogSink* sink;
-//   LogSeverity severity;
-// The cast is to disambiguate NULL arguments.
-#define LOG_TO_SINK(sink, severity) \
-  @ac_google_namespace@::LogMessage(                                    \
-      __FILE__, __LINE__,                                               \
-      @ac_google_namespace@::GLOG_ ## severity,                         \
-      static_cast<@ac_google_namespace@::LogSink*>(sink), true).stream()
-#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity)                  \
-  @ac_google_namespace@::LogMessage(                                    \
-      __FILE__, __LINE__,                                               \
-      @ac_google_namespace@::GLOG_ ## severity,                         \
-      static_cast<@ac_google_namespace@::LogSink*>(sink), false).stream()
-
-// If a non-NULL string pointer is given, we write this message to that string.
-// We then do normal LOG(severity) logging as well.
-// This is useful for capturing messages and storing them somewhere more
-// specific than the global log of the process.
-// Argument types:
-//   string* message;
-//   LogSeverity severity;
-// The cast is to disambiguate NULL arguments.
-// NOTE: LOG(severity) expands to LogMessage().stream() for the specified
-// severity.
-#define LOG_TO_STRING(severity, message) \
-  LOG_TO_STRING_##severity(static_cast<std::string*>(message)).stream()
-
-// If a non-NULL pointer is given, we push the message onto the end
-// of a vector of strings; otherwise, we report it with LOG(severity).
-// This is handy for capturing messages and perhaps passing them back
-// to the caller, rather than reporting them immediately.
-// Argument types:
-//   LogSeverity severity;
-//   vector<string> *outvec;
-// The cast is to disambiguate NULL arguments.
-#define LOG_STRING(severity, outvec) \
-  LOG_TO_STRING_##severity(static_cast<std::vector<std::string>*>(outvec)).stream()
-
-#define LOG_IF(severity, condition) if(condition) LOG(severity)
-#define SYSLOG_IF(severity, condition) if(condition) SYSLOG(severity)
-
-#define LOG_ASSERT(condition)  \
-  LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
-#define SYSLOG_ASSERT(condition) \
-  SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
-
-// CHECK dies with a fatal error if condition is not true.  It is *not*
-// controlled by DCHECK_IS_ON(), so the check will be executed regardless of
-// compilation mode.  Therefore, it is safe to do things like:
-//    CHECK(fp->Write(x) == 4)
-#define CHECK(condition)  \
-      LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
-             << "Check failed: " #condition " "
-
-// A container for a string pointer which can be evaluated to a bool -
-// true iff the pointer is NULL.
-struct CheckOpString {
-  CheckOpString(std::string* str) : str_(str) { }
-  // No destructor: if str_ is non-NULL, we're about to LOG(FATAL),
-  // so there's no point in cleaning up str_.
-  operator bool() const {
-    return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL);
-  }
-  std::string* str_;
-};
-
-// Function is overloaded for integral types to allow static const
-// integrals declared in classes and not defined to be used as arguments to
-// CHECK* macros. It's not encouraged though.
-template <class T>
-inline const T&       GetReferenceableValue(const T&           t) { return t; }
-inline char           GetReferenceableValue(char               t) { return t; }
-inline unsigned char  GetReferenceableValue(unsigned char      t) { return t; }
-inline signed char    GetReferenceableValue(signed char        t) { return t; }
-inline short          GetReferenceableValue(short              t) { return t; }
-inline unsigned short GetReferenceableValue(unsigned short     t) { return t; }
-inline int            GetReferenceableValue(int                t) { return t; }
-inline unsigned int   GetReferenceableValue(unsigned int       t) { return t; }
-inline long           GetReferenceableValue(long               t) { return t; }
-inline unsigned long  GetReferenceableValue(unsigned long      t) { return t; }
-#if __cplusplus >= 201103L
-inline long long      GetReferenceableValue(long long          t) { return t; }
-inline unsigned long long GetReferenceableValue(unsigned long long t) {
-  return t;
-}
-#endif
-
-// This is a dummy class to define the following operator.
-struct DummyClassToDefineOperator {};
-
-@ac_google_end_namespace@
-
-// Define global operator<< to declare using ::operator<<.
-// This declaration will allow use to use CHECK macros for user
-// defined classes which have operator<< (e.g., stl_logging.h).
-inline std::ostream& operator<<(
-    std::ostream& out, const google::DummyClassToDefineOperator&) {
-  return out;
-}
-
-@ac_google_start_namespace@
-
-// This formats a value for a failing CHECK_XX statement.  Ordinarily,
-// it uses the definition for operator<<, with a few special cases below.
-template <typename T>
-inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
-  (*os) << v;
-}
-
-// Overrides for char types provide readable values for unprintable
-// characters.
-template <> GLOG_EXPORT
-void MakeCheckOpValueString(std::ostream* os, const char& v);
-template <> GLOG_EXPORT
-void MakeCheckOpValueString(std::ostream* os, const signed char& v);
-template <> GLOG_EXPORT
-void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
-
-// This is required because nullptr is only present in c++ 11 and later.
-#if @ac_cv_cxx11_nullptr_t@ && __cplusplus >= 201103L
-// Provide printable value for nullptr_t
-template <> GLOG_EXPORT
-void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& v);
-#endif
-
-// Build the error message string. Specify no inlining for code size.
-template <typename T1, typename T2>
-std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
-    @ac_cv___attribute___noinline@;
-
-namespace base {
-namespace internal {
-
-// If "s" is less than base_logging::INFO, returns base_logging::INFO.
-// If "s" is greater than base_logging::FATAL, returns
-// base_logging::ERROR.  Otherwise, returns "s".
-LogSeverity NormalizeSeverity(LogSeverity s);
-
-}  // namespace internal
-
-// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
-// statement.  See MakeCheckOpString for sample usage.  Other
-// approaches were considered: use of a template method (e.g.,
-// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
-// base::Print<T2>, &v2), however this approach has complications
-// related to volatile arguments and function-pointer arguments).
-class GLOG_EXPORT CheckOpMessageBuilder {
- public:
-  // Inserts "exprtext" and " (" to the stream.
-  explicit CheckOpMessageBuilder(const char *exprtext);
-  // Deletes "stream_".
-  ~CheckOpMessageBuilder();
-  // For inserting the first variable.
-  std::ostream* ForVar1() { return stream_; }
-  // For inserting the second variable (adds an intermediate " vs. ").
-  std::ostream* ForVar2();
-  // Get the result (inserts the closing ")").
-  std::string* NewString();
-
- private:
-  std::ostringstream *stream_;
-};
-
-}  // namespace base
-
-template <typename T1, typename T2>
-std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) {
-  base::CheckOpMessageBuilder comb(exprtext);
-  MakeCheckOpValueString(comb.ForVar1(), v1);
-  MakeCheckOpValueString(comb.ForVar2(), v2);
-  return comb.NewString();
-}
-
-// Helper functions for CHECK_OP macro.
-// The (int, int) specialization works around the issue that the compiler
-// will not instantiate the template version of the function on values of
-// unnamed enum type - see comment below.
-#define DEFINE_CHECK_OP_IMPL(name, op) \
-  template <typename T1, typename T2> \
-  inline std::string* name##Impl(const T1& v1, const T2& v2,    \
-                            const char* exprtext) { \
-    if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \
-    else return MakeCheckOpString(v1, v2, exprtext); \
-  } \
-  inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \
-    return name##Impl<int, int>(v1, v2, exprtext); \
-  }
-
-// We use the full name Check_EQ, Check_NE, etc. in case the file including
-// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
-// This happens if, for example, those are used as token names in a
-// yacc grammar.
-DEFINE_CHECK_OP_IMPL(Check_EQ, ==)  // Compilation error with CHECK_EQ(NULL, x)?
-DEFINE_CHECK_OP_IMPL(Check_NE, !=)  // Use CHECK(x == NULL) instead.
-DEFINE_CHECK_OP_IMPL(Check_LE, <=)
-DEFINE_CHECK_OP_IMPL(Check_LT, < )
-DEFINE_CHECK_OP_IMPL(Check_GE, >=)
-DEFINE_CHECK_OP_IMPL(Check_GT, > )
-#undef DEFINE_CHECK_OP_IMPL
-
-// Helper macro for binary operators.
-// Don't use this macro directly in your code, use CHECK_EQ et al below.
-
-#if defined(STATIC_ANALYSIS)
-// Only for static analysis tool to know that it is equivalent to assert
-#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2))
-#elif DCHECK_IS_ON()
-// In debug mode, avoid constructing CheckOpStrings if possible,
-// to reduce the overhead of CHECK statments by 2x.
-// Real DCHECK-heavy tests have seen 1.5x speedups.
-
-// The meaning of "string" might be different between now and
-// when this macro gets invoked (e.g., if someone is experimenting
-// with other string implementations that get defined after this
-// file is included).  Save the current meaning now and use it
-// in the macro.
-typedef std::string _Check_string;
-#define CHECK_OP_LOG(name, op, val1, val2, log)                         \
-  while (@ac_google_namespace@::_Check_string* _result =                \
-         @ac_google_namespace@::Check##name##Impl(                      \
-             @ac_google_namespace@::GetReferenceableValue(val1),        \
-             @ac_google_namespace@::GetReferenceableValue(val2),        \
-             #val1 " " #op " " #val2))                                  \
-    log(__FILE__, __LINE__,                                             \
-        @ac_google_namespace@::CheckOpString(_result)).stream()
-#else
-// In optimized mode, use CheckOpString to hint to compiler that
-// the while condition is unlikely.
-#define CHECK_OP_LOG(name, op, val1, val2, log)                         \
-  while (@ac_google_namespace@::CheckOpString _result =                 \
-         @ac_google_namespace@::Check##name##Impl(                      \
-             @ac_google_namespace@::GetReferenceableValue(val1),        \
-             @ac_google_namespace@::GetReferenceableValue(val2),        \
-             #val1 " " #op " " #val2))                                  \
-    log(__FILE__, __LINE__, _result).stream()
-#endif  // STATIC_ANALYSIS, DCHECK_IS_ON()
-
-#if GOOGLE_STRIP_LOG <= 3
-#define CHECK_OP(name, op, val1, val2) \
-  CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::LogMessageFatal)
-#else
-#define CHECK_OP(name, op, val1, val2) \
-  CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::NullStreamFatal)
-#endif // STRIP_LOG <= 3
-
-// Equality/Inequality checks - compare two values, and log a FATAL message
-// including the two values when the result is not as expected.  The values
-// must have operator<<(ostream, ...) defined.
-//
-// You may append to the error message like so:
-//   CHECK_NE(1, 2) << ": The world must be ending!";
-//
-// We are very careful to ensure that each argument is evaluated exactly
-// once, and that anything which is legal to pass as a function argument is
-// legal here.  In particular, the arguments may be temporary expressions
-// which will end up being destroyed at the end of the apparent statement,
-// for example:
-//   CHECK_EQ(string("abc")[1], 'b');
-//
-// 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.
-
-#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2)
-#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2)
-#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2)
-#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2)
-#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2)
-#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2)
-
-// Check that the input is non NULL.  This very useful in constructor
-// initializer lists.
-
-#define CHECK_NOTNULL(val) \
-  @ac_google_namespace@::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
-
-// Helper functions for string comparisons.
-// To avoid bloat, the definitions are in logging.cc.
-#define DECLARE_CHECK_STROP_IMPL(func, expected) \
-  GLOG_EXPORT std::string* Check##func##expected##Impl( \
-      const char* s1, const char* s2, const char* names);
-DECLARE_CHECK_STROP_IMPL(strcmp, true)
-DECLARE_CHECK_STROP_IMPL(strcmp, false)
-DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
-DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
-#undef DECLARE_CHECK_STROP_IMPL
-
-// Helper macro for string comparisons.
-// Don't use this macro directly in your code, use CHECK_STREQ et al below.
-#define CHECK_STROP(func, op, expected, s1, s2) \
-  while (@ac_google_namespace@::CheckOpString _result = \
-         @ac_google_namespace@::Check##func##expected##Impl((s1), (s2), \
-                                     #s1 " " #op " " #s2)) \
-    LOG(FATAL) << *_result.str_
-
-
-// String (char*) equality/inequality checks.
-// CASE versions are case-insensitive.
-//
-// Note that "s1" and "s2" may be temporary strings which are destroyed
-// by the compiler at the end of the current "full expression"
-// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())).
-
-#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2)
-#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2)
-#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2)
-#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2)
-
-#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0])))
-#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0])))
-
-#define CHECK_DOUBLE_EQ(val1, val2)              \
-  do {                                           \
-    CHECK_LE((val1), (val2)+0.000000000000001L); \
-    CHECK_GE((val1), (val2)-0.000000000000001L); \
-  } while (0)
-
-#define CHECK_NEAR(val1, val2, margin)           \
-  do {                                           \
-    CHECK_LE((val1), (val2)+(margin));           \
-    CHECK_GE((val1), (val2)-(margin));           \
-  } while (0)
-
-// perror()..googly style!
-//
-// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and
-// CHECK equivalents with the addition that they postpend a description
-// of the current state of errno to their output lines.
-
-#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream()
-
-#define GOOGLE_PLOG(severity, counter)  \
-  @ac_google_namespace@::ErrnoLogMessage( \
-      __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, counter, \
-      &@ac_google_namespace@::LogMessage::SendToLog)
-
-#define PLOG_IF(severity, condition) if(condition) PLOG(severity)
-
-// A CHECK() macro that postpends errno if the condition is false. E.g.
-//
-// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... }
-#define PCHECK(condition)  \
-      PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
-              << "Check failed: " #condition " "
-
-// A CHECK() macro that lets you assert the success of a function that
-// returns -1 and sets errno in case of an error. E.g.
-//
-// CHECK_ERR(mkdir(path, 0700));
-//
-// or
-//
-// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename;
-#define CHECK_ERR(invocation)                                          \
-PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1))    \
-        << #invocation
-
-// Use macro expansion to create, for each use of LOG_EVERY_N(), static
-// variables with the __LINE__ expansion as part of the variable name.
-#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line)
-#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line
-
-#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
-#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
-
-#if @ac_cv_cxx11_constexpr@ && __cplusplus >= 201103L
-#define GLOG_CONSTEXPR constexpr
-#else
-#define GLOG_CONSTEXPR const
-#endif
-
-#define LOG_TIME_PERIOD LOG_EVERY_N_VARNAME(timePeriod_, __LINE__)
-#define LOG_PREVIOUS_TIME_RAW LOG_EVERY_N_VARNAME(previousTimeRaw_, __LINE__)
-#define LOG_TIME_DELTA LOG_EVERY_N_VARNAME(deltaTime_, __LINE__)
-#define LOG_CURRENT_TIME LOG_EVERY_N_VARNAME(currentTime_, __LINE__)
-#define LOG_PREVIOUS_TIME LOG_EVERY_N_VARNAME(previousTime_, __LINE__)
-
-#if defined(__has_feature)
-#  if __has_feature(thread_sanitizer)
-#    define GLOG_SANITIZE_THREAD 1
-#  endif
-#endif
-
-#if !defined(GLOG_SANITIZE_THREAD) && defined(__SANITIZE_THREAD__) && __SANITIZE_THREAD__
-#  define GLOG_SANITIZE_THREAD 1
-#endif
-
-#if defined(GLOG_SANITIZE_THREAD)
-#define GLOG_IFDEF_THREAD_SANITIZER(X) X
-#else
-#define GLOG_IFDEF_THREAD_SANITIZER(X)
-#endif
-
-#if defined(GLOG_SANITIZE_THREAD)
-} // namespace google
-
-// We need to identify the static variables as "benign" races
-// to avoid noisy reports from TSAN.
-extern "C" void AnnotateBenignRaceSized(
-  const char *file,
-  int line,
-  const volatile void *mem,
-  size_t size,
-  const char *description);
-
-namespace google {
-#endif
-
-#if __cplusplus >= 201103L && @ac_cv_cxx11_chrono@ && @ac_cv_cxx11_atomic@ // Have <chrono> and <atomic>
-#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
-  GLOG_CONSTEXPR std::chrono::nanoseconds LOG_TIME_PERIOD = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>(seconds)); \
-  static std::atomic<@ac_google_namespace@::int64> LOG_PREVIOUS_TIME_RAW; \
-  GLOG_IFDEF_THREAD_SANITIZER( \
-          AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, sizeof(@ac_google_namespace@::int64), "")); \
-  GLOG_IFDEF_THREAD_SANITIZER( \
-          AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, sizeof(@ac_google_namespace@::int64), "")); \
-  const auto LOG_CURRENT_TIME = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()); \
-  const auto LOG_PREVIOUS_TIME = LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \
-  const auto LOG_TIME_DELTA = LOG_CURRENT_TIME - std::chrono::nanoseconds(LOG_PREVIOUS_TIME); \
-  if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
-    LOG_PREVIOUS_TIME_RAW.store(std::chrono::duration_cast<std::chrono::nanoseconds>(LOG_CURRENT_TIME).count(), std::memory_order_relaxed); \
-  if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
-#elif defined(GLOG_OS_WINDOWS)
-#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
-  GLOG_CONSTEXPR LONGLONG LOG_TIME_PERIOD = (seconds) * LONGLONG(1000000000); \
-  static LARGE_INTEGER LOG_PREVIOUS_TIME; \
-  LONGLONG LOG_TIME_DELTA; \
-  { \
-    LARGE_INTEGER currTime; \
-    LARGE_INTEGER freq; \
-    QueryPerformanceCounter(&currTime); \
-    QueryPerformanceFrequency(&freq); \
-    InterlockedCompareExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart, 0); \
-    LOG_TIME_DELTA = (currTime.QuadPart - LOG_PREVIOUS_TIME.QuadPart) * LONGLONG(1000000000) / freq.QuadPart; \
-    if (LOG_TIME_DELTA > LOG_TIME_PERIOD) InterlockedExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart); \
-  } \
-  if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
-#else
-#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
-  GLOG_CONSTEXPR @ac_google_namespace@::int64 LOG_TIME_PERIOD(seconds * 1000000000); \
-  static @ac_google_namespace@::int64 LOG_PREVIOUS_TIME; \
-  @ac_google_namespace@::int64 LOG_TIME_DELTA = 0; \
-  { \
-    timespec currentTime = {}; \
-    clock_gettime(CLOCK_MONOTONIC, &currentTime); \
-    LOG_TIME_DELTA = (currentTime.tv_sec * 1000000000 + currentTime.tv_nsec) - LOG_PREVIOUS_TIME; \
-  } \
-  if (LOG_TIME_DELTA > LOG_TIME_PERIOD) __sync_add_and_fetch(&LOG_PREVIOUS_TIME, LOG_TIME_DELTA); \
-  if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
-#endif
-
-#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L
-#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
-  static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \
-  ++LOG_OCCURRENCES; \
-  if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
-  if (LOG_OCCURRENCES_MOD_N == 1) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
-  static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \
-  ++LOG_OCCURRENCES; \
-  if ((condition) && \
-      ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-                 &what_to_do).stream()
-
-#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
-  static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \
-  ++LOG_OCCURRENCES; \
-  if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
-  if (LOG_OCCURRENCES_MOD_N == 1) \
-    @ac_google_namespace@::ErrnoLogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
-  static std::atomic<int> LOG_OCCURRENCES(0); \
-  GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
-  if (LOG_OCCURRENCES <= n) \
-    ++LOG_OCCURRENCES; \
-  if (LOG_OCCURRENCES <= n) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#elif defined(GLOG_OS_WINDOWS)
-
-#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
-  static volatile unsigned LOG_OCCURRENCES = 0; \
-  static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
-  InterlockedIncrement(&LOG_OCCURRENCES); \
-  if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \
-    InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \
-  if (LOG_OCCURRENCES_MOD_N == 1) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
-  static volatile unsigned LOG_OCCURRENCES = 0; \
-  static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
-  InterlockedIncrement(&LOG_OCCURRENCES); \
-  if ((condition) && \
-    ((InterlockedIncrement(&LOG_OCCURRENCES_MOD_N), \
-     (LOG_OCCURRENCES_MOD_N > n && InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n))), \
-     LOG_OCCURRENCES_MOD_N == 1)) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-                 &what_to_do).stream()
-
-#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
-  static volatile unsigned LOG_OCCURRENCES = 0; \
-  static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
-  InterlockedIncrement(&LOG_OCCURRENCES); \
-  if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \
-    InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \
-  if (LOG_OCCURRENCES_MOD_N == 1) \
-    @ac_google_namespace@::ErrnoLogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
-  static volatile unsigned LOG_OCCURRENCES = 0; \
-  if (LOG_OCCURRENCES <= n) \
-    InterlockedIncrement(&LOG_OCCURRENCES); \
-  if (LOG_OCCURRENCES <= n) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#else
-
-#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
-  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
-  __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
-  if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \
-    __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \
-  if (LOG_OCCURRENCES_MOD_N == 1) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
-  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
-  __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
-  if ((condition) && \
-      (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) || true) && \
-      ((LOG_OCCURRENCES_MOD_N >= n && __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n)) || true) && \
-      LOG_OCCURRENCES_MOD_N == (1 % n)) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-                 &what_to_do).stream()
-
-#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
-  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
-  __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
-  if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \
-    __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \
-  if (LOG_OCCURRENCES_MOD_N == 1) \
-    @ac_google_namespace@::ErrnoLogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-
-#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
-  static int LOG_OCCURRENCES = 0; \
-  if (LOG_OCCURRENCES <= n) \
-    __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
-  if (LOG_OCCURRENCES <= n) \
-    @ac_google_namespace@::LogMessage( \
-        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
-        &what_to_do).stream()
-#endif
-
-namespace glog_internal_namespace_ {
-template <bool>
-struct CompileAssert {
-};
-struct CrashReason;
-
-// Returns true if FailureSignalHandler is installed.
-// Needs to be exported since it's used by the signalhandler_unittest.
-GLOG_EXPORT bool IsFailureSignalHandlerInstalled();
-}  // namespace glog_internal_namespace_
-
-#define LOG_EVERY_N(severity, n)                                        \
-  SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog)
-
-#define LOG_EVERY_T(severity, T) SOME_KIND_OF_LOG_EVERY_T(severity, (T))
-
-#define SYSLOG_EVERY_N(severity, n) \
-  SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToSyslogAndLog)
-
-#define PLOG_EVERY_N(severity, n) \
-  SOME_KIND_OF_PLOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog)
-
-#define LOG_FIRST_N(severity, n) \
-  SOME_KIND_OF_LOG_FIRST_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog)
-
-#define LOG_IF_EVERY_N(severity, condition, n) \
-  SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), @ac_google_namespace@::LogMessage::SendToLog)
-
-// We want the special COUNTER value available for LOG_EVERY_X()'ed messages
-enum PRIVATE_Counter {COUNTER};
-
-#ifdef GLOG_NO_ABBREVIATED_SEVERITIES
-// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets
-// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us
-// to keep using this syntax, we define this macro to do the same thing
-// as COMPACT_GOOGLE_LOG_ERROR.
-#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
-#define SYSLOG_0 SYSLOG_ERROR
-#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR
-// Needed for LOG_IS_ON(ERROR).
-const LogSeverity GLOG_0 = GLOG_ERROR;
-#else
-// Users may include windows.h after logging.h without
-// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN.
-// For this case, we cannot detect if ERROR is defined before users
-// actually use ERROR. Let's make an undefined symbol to warn users.
-# define GLOG_ERROR_MSG ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail
-# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG
-# define SYSLOG_0 GLOG_ERROR_MSG
-# define LOG_TO_STRING_0 GLOG_ERROR_MSG
-# define GLOG_0 GLOG_ERROR_MSG
-#endif
-
-// Plus some debug-logging macros that get compiled to nothing for production
-
-#if DCHECK_IS_ON()
-
-#define DLOG(severity) LOG(severity)
-#define DVLOG(verboselevel) VLOG(verboselevel)
-#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
-#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
-#define DLOG_IF_EVERY_N(severity, condition, n) \
-  LOG_IF_EVERY_N(severity, condition, n)
-#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
-
-// debug-only checking.  executed if DCHECK_IS_ON().
-#define DCHECK(condition) CHECK(condition)
-#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)
-#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
-#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
-#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
-#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
-#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
-
-#else  // !DCHECK_IS_ON()
-
-#define DLOG(severity) if((false)) LOG(severity)
-
-#define DVLOG(verboselevel) if((false) && VLOG_IS_ON(verboselevel)) LOG(INFO)
-
-#define DLOG_IF(severity, condition) if((false) && (condition)) LOG(severity)
-
-#define DLOG_EVERY_N(severity, n) if((false)) LOG(severity)
-
-#define DLOG_IF_EVERY_N(severity, condition, n) if((false) && (condition)) LOG(severity)
-
-#define DLOG_ASSERT(condition) if((false)) LOG_ASSERT(condition)
-
-// MSVC warning C4127: conditional expression is constant
-#define DCHECK(condition) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK(condition)
-
-#define DCHECK_EQ(val1, val2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
-
-#define DCHECK_NE(val1, val2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
-
-#define DCHECK_LE(val1, val2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
-
-#define DCHECK_LT(val1, val2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
-
-#define DCHECK_GE(val1, val2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
-
-#define DCHECK_GT(val1, val2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
-
-// You may see warnings in release mode if you don't use the return
-// value of DCHECK_NOTNULL. Please just use DCHECK for such cases.
-#define DCHECK_NOTNULL(val) (val)
-
-#define DCHECK_STREQ(str1, str2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
-
-#define DCHECK_STRCASEEQ(str1, str2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
-
-#define DCHECK_STRNE(str1, str2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
-
-#define DCHECK_STRCASENE(str1, str2) \
-  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
-  while (false) \
-    GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
-
-#endif  // DCHECK_IS_ON()
-
-// Log only in verbose mode.
-
-#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
-
-#define VLOG_IF(verboselevel, condition) \
-  LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
-
-#define VLOG_EVERY_N(verboselevel, n) \
-  LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n)
-
-#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
-  LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
-
-namespace base_logging {
-
-// LogMessage::LogStream is a std::ostream backed by this streambuf.
-// This class ignores overflow and leaves two bytes at the end of the
-// buffer to allow for a '\n' and '\0'.
-class GLOG_EXPORT LogStreamBuf : public std::streambuf {
- public:
-  // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\0'.
-  LogStreamBuf(char *buf, int len) {
-    setp(buf, buf + len - 2);
-  }
-
-  // This effectively ignores overflow.
-  int_type overflow(int_type ch) {
-    return ch;
-  }
-
-  // Legacy public ostrstream method.
-  size_t pcount() const { return static_cast<size_t>(pptr() - pbase()); }
-  char* pbase() const { return std::streambuf::pbase(); }
-};
-
-}  // namespace base_logging
-
-//
-// This class more or less represents a particular log message.  You
-// create an instance of LogMessage and then stream stuff to it.
-// When you finish streaming to it, ~LogMessage is called and the
-// full message gets streamed to the appropriate destination.
-//
-// You shouldn't actually use LogMessage's constructor to log things,
-// though.  You should use the LOG() macro (and variants thereof)
-// above.
-class GLOG_EXPORT LogMessage {
-public:
-  enum {
-    // Passing kNoLogPrefix for the line number disables the
-    // log-message prefix. Useful for using the LogMessage
-    // infrastructure as a printing utility. See also the --log_prefix
-    // flag for controlling the log-message prefix on an
-    // application-wide basis.
-    kNoLogPrefix = -1
-  };
-
-  // LogStream inherit from non-DLL-exported class (std::ostrstream)
-  // and VC++ produces a warning for this situation.
-  // However, MSDN says "C4275 can be ignored in Microsoft Visual C++
-  // 2005 if you are deriving from a type in the Standard C++ Library"
-  // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
-  // Let's just ignore the warning.
-GLOG_MSVC_PUSH_DISABLE_WARNING(4275)
-  class GLOG_EXPORT LogStream : public std::ostream {
-GLOG_MSVC_POP_WARNING()
-  public:
-    LogStream(char *buf, int len, int64 ctr)
-        : std::ostream(NULL),
-          streambuf_(buf, len),
-          ctr_(ctr),
-          self_(this) {
-      rdbuf(&streambuf_);
-    }
-
-    int64 ctr() const { return ctr_; }
-    void set_ctr(int64 ctr) { ctr_ = ctr; }
-    LogStream* self() const { return self_; }
-
-    // Legacy std::streambuf methods.
-    size_t pcount() const { return streambuf_.pcount(); }
-    char* pbase() const { return streambuf_.pbase(); }
-    char* str() const { return pbase(); }
-
-  private:
-    LogStream(const LogStream&);
-    LogStream& operator=(const LogStream&);
-    base_logging::LogStreamBuf streambuf_;
-    int64 ctr_;  // Counter hack (for the LOG_EVERY_X() macro)
-    LogStream *self_;  // Consistency check hack
-  };
-
-public:
-  // icc 8 requires this typedef to avoid an internal compiler error.
-  typedef void (LogMessage::*SendMethod)();
-
-  LogMessage(const char* file, int line, LogSeverity severity, int64 ctr,
-             SendMethod send_method);
-
-  // Two special constructors that generate reduced amounts of code at
-  // LOG call sites for common cases.
-
-  // Used for LOG(INFO): Implied are:
-  // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog.
-  //
-  // Using this constructor instead of the more complex constructor above
-  // saves 19 bytes per call site.
-  LogMessage(const char* file, int line);
-
-  // Used for LOG(severity) where severity != INFO.  Implied
-  // are: ctr = 0, send_method = &LogMessage::SendToLog
-  //
-  // Using this constructor instead of the more complex constructor above
-  // saves 17 bytes per call site.
-  LogMessage(const char* file, int line, LogSeverity severity);
-
-  // Constructor to log this message to a specified sink (if not NULL).
-  // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if
-  // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise.
-  LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink,
-             bool also_send_to_log);
-
-  // Constructor where we also give a vector<string> pointer
-  // for storing the messages (if the pointer is not NULL).
-  // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog.
-  LogMessage(const char* file, int line, LogSeverity severity,
-             std::vector<std::string>* outvec);
-
-  // Constructor where we also give a string pointer for storing the
-  // message (if the pointer is not NULL).  Implied are: ctr = 0,
-  // send_method = &LogMessage::WriteToStringAndLog.
-  LogMessage(const char* file, int line, LogSeverity severity,
-             std::string* message);
-
-  // A special constructor used for check failures
-  LogMessage(const char* file, int line, const CheckOpString& result);
-
-  ~LogMessage();
-
-  // Flush a buffered message to the sink set in the constructor.  Always
-  // called by the destructor, it may also be called from elsewhere if
-  // needed.  Only the first call is actioned; any later ones are ignored.
-  void Flush();
-
-  // An arbitrary limit on the length of a single log message.  This
-  // is so that streaming can be done more efficiently.
-  static const size_t kMaxLogMessageLen;
-
-  // Theses should not be called directly outside of logging.*,
-  // only passed as SendMethod arguments to other LogMessage methods:
-  void SendToLog();  // Actually dispatch to the logs
-  void SendToSyslogAndLog();  // Actually dispatch to syslog and the logs
-
-  // Call abort() or similar to perform LOG(FATAL) crash.
-  static void @ac_cv___attribute___noreturn@ Fail();
-
-  std::ostream& stream();
-
-  int preserved_errno() const;
-
-  // Must be called without the log_mutex held.  (L < log_mutex)
-  static int64 num_messages(int severity);
-
-  const LogMessageTime& getLogMessageTime() const;
-
-  struct LogMessageData;
-
-private:
-  // Fully internal SendMethod cases:
-  void SendToSinkAndLog();  // Send to sink if provided and dispatch to the logs
-  void SendToSink();  // Send to sink if provided, do nothing otherwise.
-
-  // Write to string if provided and dispatch to the logs.
-  void WriteToStringAndLog();
-
-  void SaveOrSendToLog();  // Save to stringvec if provided, else to logs
-
-  void Init(const char* file, int line, LogSeverity severity,
-            void (LogMessage::*send_method)());
-
-  // Used to fill in crash information during LOG(FATAL) failures.
-  void RecordCrashReason(glog_internal_namespace_::CrashReason* reason);
-
-  // Counts of messages sent at each priority:
-  static int64 num_messages_[NUM_SEVERITIES];  // under log_mutex
-
-  // We keep the data in a separate struct so that each instance of
-  // LogMessage uses less stack space.
-  LogMessageData* allocated_;
-  LogMessageData* data_;
-  LogMessageTime logmsgtime_;
-
-  friend class LogDestination;
-
-  LogMessage(const LogMessage&);
-  void operator=(const LogMessage&);
-};
-
-// This class happens to be thread-hostile because all instances share
-// a single data buffer, but since it can only be created just before
-// the process dies, we don't worry so much.
-class GLOG_EXPORT LogMessageFatal : public LogMessage {
- public:
-  LogMessageFatal(const char* file, int line);
-  LogMessageFatal(const char* file, int line, const CheckOpString& result);
-  @ac_cv___attribute___noreturn@ ~LogMessageFatal();
-};
-
-// A non-macro interface to the log facility; (useful
-// when the logging level is not a compile-time constant).
-inline void LogAtLevel(int const severity, std::string const &msg) {
-  LogMessage(__FILE__, __LINE__, severity).stream() << msg;
-}
-
-// A macro alternative of LogAtLevel. New code may want to use this
-// version since there are two advantages: 1. this version outputs the
-// file name and the line number where this macro is put like other
-// LOG macros, 2. this macro can be used as C++ stream.
-#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream()
-
-// Check if it's compiled in C++11 mode.
-//
-// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least
-// gcc-4.7 and clang-3.1 (2011-12-13).  __cplusplus was defined to 1
-// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is
-// defined according to the language version in effect thereafter.
-// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite
-// reasonably good C++11 support, so we set LANG_CXX for it and
-// newer versions (_MSC_VER >= 1900).
-#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
-     (defined(_MSC_VER) && _MSC_VER >= 1900)) && !defined(__UCLIBCXX_MAJOR__)
-// Helper for CHECK_NOTNULL().
-//
-// In C++11, all cases can be handled by a single function. Since the value
-// category of the argument is preserved (also for rvalue references),
-// member initializer lists like the one below will compile correctly:
-//
-//   Foo()
-//     : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {}
-template <typename T>
-T CheckNotNull(const char* file, int line, const char* names, T&& t) {
- if (t == nullptr) {
-   LogMessageFatal(file, line, new std::string(names));
- }
- return std::forward<T>(t);
-}
-
-#else
-
-// A small helper for CHECK_NOTNULL().
-template <typename T>
-T* CheckNotNull(const char *file, int line, const char *names, T* t) {
-  if (t == NULL) {
-    LogMessageFatal(file, line, new std::string(names));
-  }
-  return t;
-}
-#endif
-
-// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
-// only works if ostream is a LogStream. If the ostream is not a
-// LogStream you'll get an assert saying as much at runtime.
-GLOG_EXPORT std::ostream& operator<<(std::ostream &os,
-                                              const PRIVATE_Counter&);
-
-
-// Derived class for PLOG*() above.
-class GLOG_EXPORT ErrnoLogMessage : public LogMessage {
- public:
-  ErrnoLogMessage(const char* file, int line, LogSeverity severity, int64 ctr,
-                  void (LogMessage::*send_method)());
-
-  // Postpends ": strerror(errno) [errno]".
-  ~ErrnoLogMessage();
-
- private:
-  ErrnoLogMessage(const ErrnoLogMessage&);
-  void operator=(const ErrnoLogMessage&);
-};
-
-
-// Flushes all log files that contains messages that are at least of
-// the specified severity level.  Thread-safe.
-GLOG_EXPORT void FlushLogFiles(LogSeverity min_severity);
-
-// Flushes all log files that contains messages that are at least of
-// the specified severity level. Thread-hostile because it ignores
-// locking -- used for catastrophic failures.
-GLOG_EXPORT void FlushLogFilesUnsafe(LogSeverity min_severity);
-
-//
-// Set the destination to which a particular severity level of log
-// messages is sent.  If base_filename is "", it means "don't log this
-// severity".  Thread-safe.
-//
-GLOG_EXPORT void SetLogDestination(LogSeverity severity,
-                                            const char* base_filename);
-
-//
-// Set the basename of the symlink to the latest log file at a given
-// severity.  If symlink_basename is empty, do not make a symlink.  If
-// you don't call this function, the symlink basename is the
-// invocation name of the program.  Thread-safe.
-//
-GLOG_EXPORT void SetLogSymlink(LogSeverity severity,
-                                        const char* symlink_basename);
-
-//
-// Used to send logs to some other kind of destination
-// Users should subclass LogSink and override send to do whatever they want.
-// Implementations must be thread-safe because a shared instance will
-// be called from whichever thread ran the LOG(XXX) line.
-class GLOG_EXPORT LogSink {
- public:
-  virtual ~LogSink();
-
-  // Sink's logging logic (message_len is such as to exclude '\n' at the end).
-  // This method can't use LOG() or CHECK() as logging system mutex(s) are held
-  // during this call.
-  virtual void send(LogSeverity severity, const char* full_filename,
-                    const char* base_filename, int line,
-                    const LogMessageTime& logmsgtime, const char* message,
-                    size_t message_len);
-  // Provide an overload for compatibility purposes
-  GLOG_DEPRECATED
-  virtual void send(LogSeverity severity, const char* full_filename,
-                    const char* base_filename, int line, const std::tm* t,
-                    const char* message, size_t message_len);
-
-  // Redefine this to implement waiting for
-  // the sink's logging logic to complete.
-  // It will be called after each send() returns,
-  // but before that LogMessage exits or crashes.
-  // By default this function does nothing.
-  // Using this function one can implement complex logic for send()
-  // that itself involves logging; and do all this w/o causing deadlocks and
-  // inconsistent rearrangement of log messages.
-  // E.g. if a LogSink has thread-specific actions, the send() method
-  // can simply add the message to a queue and wake up another thread that
-  // handles real logging while itself making some LOG() calls;
-  // WaitTillSent() can be implemented to wait for that logic to complete.
-  // See our unittest for an example.
-  virtual void WaitTillSent();
-
-  // Returns the normal text output of the log message.
-  // Can be useful to implement send().
-  static std::string ToString(LogSeverity severity, const char* file, int line,
-                              const LogMessageTime &logmsgtime,
-                              const char* message, size_t message_len);
-};
-
-// Add or remove a LogSink as a consumer of logging data.  Thread-safe.
-GLOG_EXPORT void AddLogSink(LogSink *destination);
-GLOG_EXPORT void RemoveLogSink(LogSink *destination);
-
-//
-// Specify an "extension" added to the filename specified via
-// SetLogDestination.  This applies to all severity levels.  It's
-// often used to append the port we're listening on to the logfile
-// name.  Thread-safe.
-//
-GLOG_EXPORT void SetLogFilenameExtension(
-    const char* filename_extension);
-
-//
-// Make it so that all log messages of at least a particular severity
-// are logged to stderr (in addition to logging to the usual log
-// file(s)).  Thread-safe.
-//
-GLOG_EXPORT void SetStderrLogging(LogSeverity min_severity);
-
-//
-// Make it so that all log messages go only to stderr.  Thread-safe.
-//
-GLOG_EXPORT void LogToStderr();
-
-//
-// Make it so that all log messages of at least a particular severity are
-// logged via email to a list of addresses (in addition to logging to the
-// usual log file(s)).  The list of addresses is just a string containing
-// the email addresses to send to (separated by spaces, say).  Thread-safe.
-//
-GLOG_EXPORT void SetEmailLogging(LogSeverity min_severity,
-                                          const char* addresses);
-
-// A simple function that sends email. dest is a commma-separated
-// list of addressess.  Thread-safe.
-GLOG_EXPORT bool SendEmail(const char* dest, const char* subject,
-                           const char* body);
-
-GLOG_EXPORT const std::vector<std::string>& GetLoggingDirectories();
-
-// For tests only:  Clear the internal [cached] list of logging directories to
-// force a refresh the next time GetLoggingDirectories is called.
-// Thread-hostile.
-void TestOnly_ClearLoggingDirectoriesList();
-
-// Returns a set of existing temporary directories, which will be a
-// subset of the directories returned by GetLoggingDirectories().
-// Thread-safe.
-GLOG_EXPORT void GetExistingTempDirectories(
-    std::vector<std::string>* list);
-
-// Print any fatal message again -- useful to call from signal handler
-// so that the last thing in the output is the fatal message.
-// Thread-hostile, but a race is unlikely.
-GLOG_EXPORT void ReprintFatalMessage();
-
-// Truncate a log file that may be the append-only output of multiple
-// processes and hence can't simply be renamed/reopened (typically a
-// stdout/stderr).  If the file "path" is > "limit" bytes, copy the
-// last "keep" bytes to offset 0 and truncate the rest. Since we could
-// be racing with other writers, this approach has the potential to
-// lose very small amounts of data. For security, only follow symlinks
-// if the path is /proc/self/fd/*
-GLOG_EXPORT void TruncateLogFile(const char* path, uint64 limit, uint64 keep);
-
-// Truncate stdout and stderr if they are over the value specified by
-// --max_log_size; keep the final 1MB.  This function has the same
-// race condition as TruncateLogFile.
-GLOG_EXPORT void TruncateStdoutStderr();
-
-// Return the string representation of the provided LogSeverity level.
-// Thread-safe.
-GLOG_EXPORT const char* GetLogSeverityName(LogSeverity severity);
-
-// ---------------------------------------------------------------------
-// Implementation details that are not useful to most clients
-// ---------------------------------------------------------------------
-
-// A Logger is the interface used by logging modules to emit entries
-// to a log.  A typical implementation will dump formatted data to a
-// sequence of files.  We also provide interfaces that will forward
-// the data to another thread so that the invoker never blocks.
-// Implementations should be thread-safe since the logging system
-// will write to them from multiple threads.
-
-namespace base {
-
-class GLOG_EXPORT Logger {
- public:
-  virtual ~Logger();
-
-  // Writes "message[0,message_len-1]" corresponding to an event that
-  // occurred at "timestamp".  If "force_flush" is true, the log file
-  // is flushed immediately.
-  //
-  // The input message has already been formatted as deemed
-  // appropriate by the higher level logging facility.  For example,
-  // textual log messages already contain timestamps, and the
-  // file:linenumber header.
-  virtual void Write(bool force_flush,
-                     time_t timestamp,
-                     const char* message,
-                     size_t message_len) = 0;
-
-  // Flush any buffered messages
-  virtual void Flush() = 0;
-
-  // Get the current LOG file size.
-  // The returned value is approximate since some
-  // logged data may not have been flushed to disk yet.
-  virtual uint32 LogSize() = 0;
-};
-
-// Get the logger for the specified severity level.  The logger
-// remains the property of the logging module and should not be
-// deleted by the caller.  Thread-safe.
-extern GLOG_EXPORT Logger* GetLogger(LogSeverity level);
-
-// Set the logger for the specified severity level.  The logger
-// becomes the property of the logging module and should not
-// be deleted by the caller.  Thread-safe.
-extern GLOG_EXPORT void SetLogger(LogSeverity level, Logger* logger);
-
-}
-
-// glibc has traditionally implemented two incompatible versions of
-// strerror_r(). There is a poorly defined convention for picking the
-// version that we want, but it is not clear whether it even works with
-// all versions of glibc.
-// So, instead, we provide this wrapper that automatically detects the
-// version that is in use, and then implements POSIX semantics.
-// N.B. In addition to what POSIX says, we also guarantee that "buf" will
-// be set to an empty string, if this function failed. This means, in most
-// cases, you do not need to check the error code and you can directly
-// use the value of "buf". It will never have an undefined value.
-// DEPRECATED: Use StrError(int) instead.
-GLOG_EXPORT int posix_strerror_r(int err, char *buf, size_t len);
-
-// A thread-safe replacement for strerror(). Returns a string describing the
-// given POSIX error code.
-GLOG_EXPORT std::string StrError(int err);
-
-// A class for which we define operator<<, which does nothing.
-class GLOG_EXPORT NullStream : public LogMessage::LogStream {
- public:
-  // Initialize the LogStream so the messages can be written somewhere
-  // (they'll never be actually displayed). This will be needed if a
-  // NullStream& is implicitly converted to LogStream&, in which case
-  // the overloaded NullStream::operator<< will not be invoked.
-  NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
-  NullStream(const char* /*file*/, int /*line*/,
-             const CheckOpString& /*result*/) :
-      LogMessage::LogStream(message_buffer_, 1, 0) { }
-  NullStream &stream() { return *this; }
- private:
-  // A very short buffer for messages (which we discard anyway). This
-  // will be needed if NullStream& converted to LogStream& (e.g. as a
-  // result of a conditional expression).
-  char message_buffer_[2];
-};
-
-// Do nothing. This operator is inline, allowing the message to be
-// compiled away. The message will not be compiled away if we do
-// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
-// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
-// converted to LogStream and the message will be computed and then
-// quietly discarded.
-template<class T>
-inline NullStream& operator<<(NullStream &str, const T &) { return str; }
-
-// Similar to NullStream, but aborts the program (without stack
-// trace), like LogMessageFatal.
-class GLOG_EXPORT NullStreamFatal : public NullStream {
- public:
-  NullStreamFatal() { }
-  NullStreamFatal(const char* file, int line, const CheckOpString& result) :
-      NullStream(file, line, result) { }
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4722)
-#endif // _MSC_VER
-  @ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(EXIT_FAILURE); }
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif // _MSC_VER
-};
-
-// Install a signal handler that will dump signal information and a stack
-// trace when the program crashes on certain signals.  We'll install the
-// signal handler for the following signals.
-//
-// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM.
-//
-// By default, the signal handler will write the failure dump to the
-// standard error.  You can customize the destination by installing your
-// own writer function by InstallFailureWriter() below.
-//
-// Note on threading:
-//
-// The function should be called before threads are created, if you want
-// to use the failure signal handler for all threads.  The stack trace
-// will be shown only for the thread that receives the signal.  In other
-// words, stack traces of other threads won't be shown.
-GLOG_EXPORT void InstallFailureSignalHandler();
-
-// Installs a function that is used for writing the failure dump.  "data"
-// is the pointer to the beginning of a message to be written, and "size"
-// is the size of the message.  You should not expect the data is
-// terminated with '\0'.
-GLOG_EXPORT void InstallFailureWriter(
-    void (*writer)(const char* data, size_t size));
-
-@ac_google_end_namespace@
-
-#pragma pop_macro("DECLARE_VARIABLE")
-#pragma pop_macro("DECLARE_bool")
-#pragma pop_macro("DECLARE_string")
-#pragma pop_macro("DECLARE_int32")
-#pragma pop_macro("DECLARE_uint32")
-
-#endif // GLOG_LOGGING_H
diff --git a/third_party/google-glog/src/glog/platform.h b/third_party/google-glog/src/glog/platform.h
deleted file mode 100644
index 7893c45..0000000
--- a/third_party/google-glog/src/glog/platform.h
+++ /dev/null
@@ -1,60 +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: Shinichiro Hamaji
-//
-// Detect supported platforms.
-
-#ifndef GLOG_PLATFORM_H
-#define GLOG_PLATFORM_H
-
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-#define GLOG_OS_WINDOWS
-#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
-#define GLOG_OS_CYGWIN
-#elif defined(linux) || defined(__linux) || defined(__linux__)
-#ifndef GLOG_OS_LINUX
-#define GLOG_OS_LINUX
-#endif
-#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
-#define GLOG_OS_MACOSX
-#elif defined(__FreeBSD__)
-#define GLOG_OS_FREEBSD
-#elif defined(__NetBSD__)
-#define GLOG_OS_NETBSD
-#elif defined(__OpenBSD__)
-#define GLOG_OS_OPENBSD
-#elif defined(__EMSCRIPTEN__)
-#define GLOG_OS_EMSCRIPTEN
-#else
-// TODO(hamaji): Add other platforms.
-#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github.
-#endif
-
-#endif // GLOG_PLATFORM_H
diff --git a/third_party/google-glog/src/glog/raw_logging.h.in b/third_party/google-glog/src/glog/raw_logging.h.in
deleted file mode 100644
index 66fec91..0000000
--- a/third_party/google-glog/src/glog/raw_logging.h.in
+++ /dev/null
@@ -1,179 +0,0 @@
-// 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
-//
-// Thread-safe logging routines that do not allocate any memory or
-// acquire any locks, and can therefore be used by low-level memory
-// allocation and synchronization code.
-
-#ifndef GLOG_RAW_LOGGING_H
-#define GLOG_RAW_LOGGING_H
-
-#include <ctime>
-
-@ac_google_start_namespace@
-
-#include <glog/log_severity.h>
-#include <glog/logging.h>
-#include <glog/vlog_is_on.h>
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wvariadic-macros"
-#endif
-
-// This is similar to LOG(severity) << format... and VLOG(level) << format..,
-// but
-// * it is to be used ONLY by low-level modules that can't use normal LOG()
-// * it is desiged to be a low-level logger that does not allocate any
-//   memory and does not need any locks, hence:
-// * it logs straight and ONLY to STDERR w/o buffering
-// * it uses an explicit format and arguments list
-// * it will silently chop off really long message strings
-// Usage example:
-//   RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
-//   RAW_VLOG(3, "status is %i", status);
-// These will print an almost standard log lines like this to stderr only:
-//   E20200821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
-//   I20200821 211317 file.cc:142] RAW: status is 20
-#define RAW_LOG(severity, ...) \
-  do { \
-    switch (@ac_google_namespace@::GLOG_ ## severity) {  \
-      case 0: \
-        RAW_LOG_INFO(__VA_ARGS__); \
-        break; \
-      case 1: \
-        RAW_LOG_WARNING(__VA_ARGS__); \
-        break; \
-      case 2: \
-        RAW_LOG_ERROR(__VA_ARGS__); \
-        break; \
-      case 3: \
-        RAW_LOG_FATAL(__VA_ARGS__); \
-        break; \
-      default: \
-        break; \
-    } \
-  } while (0)
-
-// The following STRIP_LOG testing is performed in the header file so that it's
-// possible to completely compile out the logging code and the log messages.
-#if !defined(STRIP_LOG) || STRIP_LOG == 0
-#define RAW_VLOG(verboselevel, ...) \
-  do { \
-    if (VLOG_IS_ON(verboselevel)) { \
-      RAW_LOG_INFO(__VA_ARGS__); \
-    } \
-  } while (0)
-#else
-#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
-#endif // STRIP_LOG == 0
-
-#if !defined(STRIP_LOG) || STRIP_LOG == 0
-#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_INFO, \
-                                   __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__)
-#endif // STRIP_LOG == 0
-
-#if !defined(STRIP_LOG) || STRIP_LOG <= 1
-#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_WARNING,   \
-                                      __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__)
-#endif // STRIP_LOG <= 1
-
-#if !defined(STRIP_LOG) || STRIP_LOG <= 2
-#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_ERROR,       \
-                                    __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__)
-#endif // STRIP_LOG <= 2
-
-#if !defined(STRIP_LOG) || STRIP_LOG <= 3
-#define RAW_LOG_FATAL(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_FATAL,       \
-                                    __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define RAW_LOG_FATAL(...) \
-  do { \
-    @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__);        \
-    exit(EXIT_FAILURE); \
-  } while (0)
-#endif // STRIP_LOG <= 3
-
-// Similar to CHECK(condition) << message,
-// but for low-level modules: we use only RAW_LOG that does not allocate memory.
-// We do not want to provide args list here to encourage this usage:
-//   if (!cond)  RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
-// so that the args are not computed when not needed.
-#define RAW_CHECK(condition, message)                                   \
-  do {                                                                  \
-    if (!(condition)) {                                                 \
-      RAW_LOG(FATAL, "Check %s failed: %s", #condition, message);       \
-    }                                                                   \
-  } while (0)
-
-// Debug versions of RAW_LOG and RAW_CHECK
-#ifndef NDEBUG
-
-#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
-#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
-
-#else  // NDEBUG
-
-#define RAW_DLOG(severity, ...)                                 \
-  while (false)                                                 \
-    RAW_LOG(severity, __VA_ARGS__)
-#define RAW_DCHECK(condition, message) \
-  while (false) \
-    RAW_CHECK(condition, message)
-
-#endif  // NDEBUG
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-// Stub log function used to work around for unused variable warnings when
-// building with STRIP_LOG > 0.
-static inline void RawLogStub__(int /* ignored */, ...) {
-}
-
-// Helper function to implement RAW_LOG and RAW_VLOG
-// Logs format... at "severity" level, reporting it
-// as called from file:line.
-// This does not allocate memory or acquire locks.
-GLOG_EXPORT void RawLog__(LogSeverity severity, const char* file, int line,
-                          const char* format, ...)
-    @ac_cv___attribute___printf_4_5@;
-
-@ac_google_end_namespace@
-
-#endif  // GLOG_RAW_LOGGING_H
diff --git a/third_party/google-glog/src/glog/stl_logging.h.in b/third_party/google-glog/src/glog/stl_logging.h.in
deleted file mode 100644
index bdfdc8b..0000000
--- a/third_party/google-glog/src/glog/stl_logging.h.in
+++ /dev/null
@@ -1,220 +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.
-//
-// Stream output operators for STL containers; to be used for logging *only*.
-// Inclusion of this file lets you do:
-//
-// list<string> x;
-// LOG(INFO) << "data: " << x;
-// vector<int> v1, v2;
-// CHECK_EQ(v1, v2);
-//
-// If you want to use this header file with hash maps or slist, you
-// need to define macros before including this file:
-//
-// - GLOG_STL_LOGGING_FOR_UNORDERED     - <unordered_map> and <unordered_set>
-// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
-// - GLOG_STL_LOGGING_FOR_EXT_HASH      - <ext/hash_(map|set)>
-// - GLOG_STL_LOGGING_FOR_EXT_SLIST     - <ext/slist>
-//
-
-#ifndef UTIL_GTL_STL_LOGGING_INL_H_
-#define UTIL_GTL_STL_LOGGING_INL_H_
-
-#if !@ac_cv_cxx_using_operator@
-# error We do not support stl_logging for this compiler
-#endif
-
-#include <deque>
-#include <list>
-#include <map>
-#include <ostream>
-#include <set>
-#include <utility>
-#include <vector>
-
-#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
-# include <unordered_map>
-# include <unordered_set>
-#endif
-
-#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
-# include <tr1/unordered_map>
-# include <tr1/unordered_set>
-#endif
-
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-# include <ext/hash_set>
-# include <ext/hash_map>
-#endif
-#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
-# include <ext/slist>
-#endif
-
-// Forward declare these two, and define them after all the container streams
-// operators so that we can recurse from pair -> container -> container -> pair
-// properly.
-template<class First, class Second>
-std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
-
-@ac_google_start_namespace@
-
-template<class Iter>
-void PrintSequence(std::ostream& out, Iter begin, Iter end);
-
-@ac_google_end_namespace@
-
-#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
-template<class T1, class T2> \
-inline std::ostream& operator<<(std::ostream& out, \
-                                const Sequence<T1, T2>& seq) { \
-  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
-  return out; \
-}
-
-OUTPUT_TWO_ARG_CONTAINER(std::vector)
-OUTPUT_TWO_ARG_CONTAINER(std::deque)
-OUTPUT_TWO_ARG_CONTAINER(std::list)
-#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
-OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
-#endif
-
-#undef OUTPUT_TWO_ARG_CONTAINER
-
-#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
-template<class T1, class T2, class T3> \
-inline std::ostream& operator<<(std::ostream& out, \
-                                const Sequence<T1, T2, T3>& seq) { \
-  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
-  return out; \
-}
-
-OUTPUT_THREE_ARG_CONTAINER(std::set)
-OUTPUT_THREE_ARG_CONTAINER(std::multiset)
-
-#undef OUTPUT_THREE_ARG_CONTAINER
-
-#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
-template<class T1, class T2, class T3, class T4> \
-inline std::ostream& operator<<(std::ostream& out, \
-                                const Sequence<T1, T2, T3, T4>& seq) { \
-  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
-  return out; \
-}
-
-OUTPUT_FOUR_ARG_CONTAINER(std::map)
-OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
-#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
-OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
-OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
-#endif
-#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
-OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
-OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
-#endif
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
-OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
-#endif
-
-#undef OUTPUT_FOUR_ARG_CONTAINER
-
-#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
-template<class T1, class T2, class T3, class T4, class T5> \
-inline std::ostream& operator<<(std::ostream& out, \
-                                const Sequence<T1, T2, T3, T4, T5>& seq) { \
-  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
-  return out; \
-}
-
-#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
-OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
-OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
-#endif
-#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
-OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
-OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
-#endif
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
-OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
-#endif
-
-#undef OUTPUT_FIVE_ARG_CONTAINER
-
-template<class First, class Second>
-inline std::ostream& operator<<(std::ostream& out,
-                                const std::pair<First, Second>& p) {
-  out << '(' << p.first << ", " << p.second << ')';
-  return out;
-}
-
-@ac_google_start_namespace@
-
-template<class Iter>
-inline void PrintSequence(std::ostream& out, Iter begin, Iter end) {
-  // Output at most 100 elements -- appropriate if used for logging.
-  for (int i = 0; begin != end && i < 100; ++i, ++begin) {
-    if (i > 0) out << ' ';
-    out << *begin;
-  }
-  if (begin != end) {
-    out << " ...";
-  }
-}
-
-@ac_google_end_namespace@
-
-// Note that this is technically undefined behavior! We are adding things into
-// the std namespace for a reason though -- we are providing new operations on
-// types which are themselves defined with this namespace. Without this, these
-// operator overloads cannot be found via ADL. If these definitions are not
-// found via ADL, they must be #included before they're used, which requires
-// this header to be included before apparently independent other headers.
-//
-// For example, base/logging.h defines various template functions to implement
-// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
-// It does so via the function template MakeCheckOpValueString:
-//   template<class T>
-//   void MakeCheckOpValueString(strstream* ss, const T& v) {
-//     (*ss) << v;
-//   }
-// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
-// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
-// find these operator definitions via ADL.
-//
-// Even this solution has problems -- it may pull unintended operators into the
-// namespace as well, allowing them to also be found via ADL, and creating code
-// that only works with a particular order of includes. Long term, we need to
-// move all of the *definitions* into namespace std, bet we need to ensure no
-// one references them first. This lets us take that step. We cannot define them
-// in both because that would create ambiguous overloads when both are found.
-namespace std { using ::operator<<; }
-
-#endif  // UTIL_GTL_STL_LOGGING_INL_H_
diff --git a/third_party/google-glog/src/glog/vlog_is_on.h.in b/third_party/google-glog/src/glog/vlog_is_on.h.in
deleted file mode 100644
index 7526fc3..0000000
--- a/third_party/google-glog/src/glog/vlog_is_on.h.in
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 1999, 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: Ray Sidney and many others
-//
-// Defines the VLOG_IS_ON macro that controls the variable-verbosity
-// conditional logging.
-//
-// It's used by VLOG and VLOG_IF in logging.h
-// and by RAW_VLOG in raw_logging.h to trigger the logging.
-//
-// It can also be used directly e.g. like this:
-//   if (VLOG_IS_ON(2)) {
-//     // do some logging preparation and logging
-//     // that can't be accomplished e.g. via just VLOG(2) << ...;
-//   }
-//
-// The truth value that VLOG_IS_ON(level) returns is determined by
-// the three verbosity level flags:
-//   --v=<n>  Gives the default maximal active V-logging level;
-//            0 is the default.
-//            Normally positive values are used for V-logging levels.
-//   --vmodule=<str>  Gives the per-module maximal V-logging levels to override
-//                    the value given by --v.
-//                    E.g. "my_module=2,foo*=3" would change the logging level
-//                    for all code in source files "my_module.*" and "foo*.*"
-//                    ("-inl" suffixes are also disregarded for this matching).
-//
-// SetVLOGLevel helper function is provided to do limited dynamic control over
-// V-logging by overriding the per-module settings given via --vmodule flag.
-//
-// CAVEAT: --vmodule functionality is not available in non gcc compilers.
-//
-
-#ifndef BASE_VLOG_IS_ON_H_
-#define BASE_VLOG_IS_ON_H_
-
-#include <glog/log_severity.h>
-
-#if defined(__GNUC__)
-// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
-// (Normally) the first time every VLOG_IS_ON(n) site is hit,
-// we determine what variable will dynamically control logging at this site:
-// it's either FLAGS_v or an appropriate internal variable
-// matching the current source file that represents results of
-// parsing of --vmodule flag and/or SetVLOGLevel calls.
-#define VLOG_IS_ON(verboselevel)                                \
-  __extension__  \
-  ({ static @ac_google_namespace@::SiteFlag vlocal__ = {NULL, NULL, 0, NULL};       \
-     @ac_google_namespace@::int32 verbose_level__ = (verboselevel);                    \
-     (vlocal__.level == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \
-                        __FILE__, verbose_level__) : *vlocal__.level >= verbose_level__); \
-  })
-#else
-// GNU extensions not available, so we do not support --vmodule.
-// Dynamic value of FLAGS_v always controls the logging level.
-#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
-#endif
-
-// Set VLOG(_IS_ON) level for module_pattern to log_level.
-// This lets us dynamically control what is normally set by the --vmodule flag.
-// Returns the level that previously applied to module_pattern.
-// NOTE: To change the log level for VLOG(_IS_ON) sites
-//	 that have already executed after/during InitGoogleLogging,
-//	 one needs to supply the exact --vmodule pattern that applied to them.
-//       (If no --vmodule pattern applied to them
-//       the value of FLAGS_v will continue to control them.)
-extern GLOG_EXPORT int SetVLOGLevel(const char* module_pattern, int log_level);
-
-// Various declarations needed for VLOG_IS_ON above: =========================
-
-struct SiteFlag {
-  @ac_google_namespace@::int32* level;
-  const char* base_name;
-  size_t base_len;
-  SiteFlag* next;
-};
-
-// Helper routine which determines the logging info for a particalur VLOG site.
-//   site_flag     is the address of the site-local pointer to the controlling
-//                 verbosity level
-//   site_default  is the default to use for *site_flag
-//   fname         is the current source file name
-//   verbose_level is the argument to VLOG_IS_ON
-// We will return the return value for VLOG_IS_ON
-// and if possible set *site_flag appropriately.
-extern GLOG_EXPORT bool InitVLOG3__(
-    @ac_google_namespace@::SiteFlag* site_flag,
-    @ac_google_namespace@::int32* site_default, const char* fname,
-    @ac_google_namespace@::int32 verbose_level);
-
-#endif  // BASE_VLOG_IS_ON_H_
diff --git a/third_party/google-glog/src/googletest.h b/third_party/google-glog/src/googletest.h
deleted file mode 100644
index 5761361..0000000
--- a/third_party/google-glog/src/googletest.h
+++ /dev/null
@@ -1,672 +0,0 @@
-// 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: Shinichiro Hamaji
-//   (based on googletest: http://code.google.com/p/googletest/)
-
-#ifdef GOOGLETEST_H__
-#error You must not include this file twice.
-#endif
-#define GOOGLETEST_H__
-
-#include "utilities.h"
-
-#include <cctype>
-#include <csetjmp>
-#include <cstdio>
-#include <cstdlib>
-#include <ctime>
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include "base/commandlineflags.h"
-
-#if __cplusplus < 201103L && !defined(_MSC_VER)
-#define GOOGLE_GLOG_THROW_BAD_ALLOC throw (std::bad_alloc)
-#else
-#define GOOGLE_GLOG_THROW_BAD_ALLOC
-#endif
-
-using std::map;
-using std::string;
-using std::vector;
-
-_START_GOOGLE_NAMESPACE_
-
-extern GLOG_EXPORT void (*g_logging_fail_func)();
-
-_END_GOOGLE_NAMESPACE_
-
-#undef GLOG_EXPORT
-#define GLOG_EXPORT
-
-static inline string GetTempDir() {
-  vector<string> temp_directories_list;
-  google::GetExistingTempDirectories(&temp_directories_list);
-
-  if (temp_directories_list.empty()) {
-    fprintf(stderr, "No temporary directory found\n");
-    exit(EXIT_FAILURE);
-  }
-
-  // Use first directory from list of existing temporary directories.
-  return temp_directories_list.front();
-}
-
-#if defined(GLOG_OS_WINDOWS) && defined(_MSC_VER) && !defined(TEST_SRC_DIR)
-// The test will run in glog/vsproject/<project name>
-// (e.g., glog/vsproject/logging_unittest).
-static const char TEST_SRC_DIR[] = "../..";
-#elif !defined(TEST_SRC_DIR)
-# warning TEST_SRC_DIR should be defined in config.h
-static const char TEST_SRC_DIR[] = ".";
-#endif
-
-static const uint32_t PTR_TEST_VALUE = 0x12345678;
-
-DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files");
-DEFINE_string(test_srcdir, TEST_SRC_DIR,
-              "Source-dir root, needed to find glog_unittest_flagfile");
-DEFINE_bool(run_benchmark, false, "If true, run benchmarks");
-#ifdef NDEBUG
-DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark");
-#else
-DEFINE_int32(benchmark_iters, 100000, "Number of iterations per benchmark");
-#endif
-
-#ifdef HAVE_LIB_GTEST
-# include <gtest/gtest.h>
-// Use our ASSERT_DEATH implementation.
-# undef ASSERT_DEATH
-# undef ASSERT_DEBUG_DEATH
-using testing::InitGoogleTest;
-#else
-
-_START_GOOGLE_NAMESPACE_
-
-void InitGoogleTest(int*, char**);
-
-void InitGoogleTest(int*, char**) {}
-
-// The following is some bare-bones testing infrastructure
-
-#define EXPECT_NEAR(val1, val2, abs_error)                                     \
-  do {                                                                         \
-    if (abs(val1 - val2) > abs_error) {                                        \
-      fprintf(stderr, "Check failed: %s within %s of %s\n", #val1, #abs_error, \
-              #val2);                                                          \
-      exit(EXIT_FAILURE);                                                      \
-    }                                                                          \
-  } while (0)
-
-#define EXPECT_TRUE(cond)                               \
-  do {                                                  \
-    if (!(cond)) {                                      \
-      fprintf(stderr, "Check failed: %s\n", #cond);     \
-      exit(EXIT_FAILURE);                               \
-    }                                                   \
-  } while (0)
-
-#define EXPECT_FALSE(cond)  EXPECT_TRUE(!(cond))
-
-#define EXPECT_OP(op, val1, val2)                                       \
-  do {                                                                  \
-    if (!((val1) op (val2))) {                                          \
-      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
-      exit(EXIT_FAILURE);                                               \
-    }                                                                   \
-  } while (0)
-
-#define EXPECT_EQ(val1, val2)  EXPECT_OP(==, val1, val2)
-#define EXPECT_NE(val1, val2)  EXPECT_OP(!=, val1, val2)
-#define EXPECT_GT(val1, val2)  EXPECT_OP(>, val1, val2)
-#define EXPECT_LT(val1, val2)  EXPECT_OP(<, val1, val2)
-
-#define EXPECT_NAN(arg)                                         \
-  do {                                                          \
-    if (!isnan(arg)) {                                          \
-      fprintf(stderr, "Check failed: isnan(%s)\n", #arg);       \
-      exit(EXIT_FAILURE);                                       \
-    }                                                           \
-  } while (0)
-
-#define EXPECT_INF(arg)                                         \
-  do {                                                          \
-    if (!isinf(arg)) {                                          \
-      fprintf(stderr, "Check failed: isinf(%s)\n", #arg);       \
-      exit(EXIT_FAILURE);                                       \
-    }                                                           \
-  } while (0)
-
-#define EXPECT_DOUBLE_EQ(val1, val2)                                    \
-  do {                                                                  \
-    if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) {         \
-      fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2);        \
-      exit(EXIT_FAILURE);                                               \
-    }                                                                   \
-  } while (0)
-
-#define EXPECT_STREQ(val1, val2)                                        \
-  do {                                                                  \
-    if (strcmp((val1), (val2)) != 0) {                                  \
-      fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2);   \
-      exit(EXIT_FAILURE);                                               \
-    }                                                                   \
-  } while (0)
-
-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() { FlagSaver fs; RunTest(); }      \
-    static void RunTest();                              \
-  };                                                    \
-  static Test_##a##_##b g_test_##a##_##b;               \
-  void Test_##a##_##b::RunTest()
-
-
-static inline int RUN_ALL_TESTS() {
-  vector<void (*)()>::const_iterator it;
-  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
-    (*it)();
-  }
-  fprintf(stderr, "Passed %d tests\n\nPASS\n",
-          static_cast<int>(g_testlist.size()));
-  return 0;
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#endif  // ! HAVE_LIB_GTEST
-
-_START_GOOGLE_NAMESPACE_
-
-static bool g_called_abort;
-static jmp_buf g_jmp_buf;
-static inline void CalledAbort() {
-  g_called_abort = true;
-  longjmp(g_jmp_buf, 1);
-}
-
-#ifdef GLOG_OS_WINDOWS
-// TODO(hamaji): Death test somehow doesn't work in Windows.
-#define ASSERT_DEATH(fn, msg)
-#else
-#define ASSERT_DEATH(fn, msg)                                           \
-  do {                                                                  \
-    g_called_abort = false;                                             \
-    /* in logging.cc */                                                 \
-    void (*original_logging_fail_func)() = g_logging_fail_func;         \
-    g_logging_fail_func = &CalledAbort;                                 \
-    if (!setjmp(g_jmp_buf)) fn;                                         \
-    /* set back to their default */                                     \
-    g_logging_fail_func = original_logging_fail_func;                   \
-    if (!g_called_abort) {                                              \
-      fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn);      \
-      exit(EXIT_FAILURE);                                               \
-    }                                                                   \
-  } while (0)
-#endif
-
-#ifdef NDEBUG
-#define ASSERT_DEBUG_DEATH(fn, msg)
-#else
-#define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg)
-#endif  // NDEBUG
-
-// Benchmark tools.
-
-#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n);
-
-map<string, void (*)(int)> g_benchlist;  // the benchmarks to run
-
-class BenchmarkRegisterer {
- public:
-  BenchmarkRegisterer(const char* name, void (*function)(int iters)) {
-    EXPECT_TRUE(g_benchlist.insert(std::make_pair(name, function)).second);
-  }
-};
-
-static inline void RunSpecifiedBenchmarks() {
-  if (!FLAGS_run_benchmark) {
-    return;
-  }
-
-  int iter_cnt = FLAGS_benchmark_iters;
-  puts("Benchmark\tTime(ns)\tIterations");
-  for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
-       iter != g_benchlist.end();
-       ++iter) {
-    clock_t start = clock();
-    iter->second(iter_cnt);
-    double elapsed_ns = (static_cast<double>(clock()) - start) /
-                        CLOCKS_PER_SEC * 1000 * 1000 * 1000;
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat="
-#endif
-    printf("%s\t%8.2lf\t%10d\n",
-           iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt);
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-  }
-  puts("");
-}
-
-// ----------------------------------------------------------------------
-// Golden file functions
-// ----------------------------------------------------------------------
-
-class CapturedStream {
- public:
-  CapturedStream(int fd, const string & filename) :
-    fd_(fd),
-    uncaptured_fd_(-1),
-    filename_(filename) {
-    Capture();
-  }
-
-  ~CapturedStream() {
-    if (uncaptured_fd_ != -1) {
-      CHECK(close(uncaptured_fd_) != -1);
-    }
-  }
-
-  // Start redirecting output to a file
-  void Capture() {
-    // Keep original stream for later
-    CHECK(uncaptured_fd_ == -1) << ", Stream " << fd_ << " already captured!";
-    uncaptured_fd_ = dup(fd_);
-    CHECK(uncaptured_fd_ != -1);
-
-    // Open file to save stream to
-    int cap_fd = open(filename_.c_str(),
-                      O_CREAT | O_TRUNC | O_WRONLY,
-                      S_IRUSR | S_IWUSR);
-    CHECK(cap_fd != -1);
-
-    // Send stdout/stderr to this file
-    fflush(NULL);
-    CHECK(dup2(cap_fd, fd_) != -1);
-    CHECK(close(cap_fd) != -1);
-  }
-
-  // Remove output redirection
-  void StopCapture() {
-    // Restore original stream
-    if (uncaptured_fd_ != -1) {
-      fflush(NULL);
-      CHECK(dup2(uncaptured_fd_, fd_) != -1);
-    }
-  }
-
-  const string & filename() const { return filename_; }
-
- private:
-  int fd_;             // file descriptor being captured
-  int uncaptured_fd_;  // where the stream was originally being sent to
-  string filename_;    // file where stream is being saved
-};
-static CapturedStream * s_captured_streams[STDERR_FILENO+1];
-// Redirect a file descriptor to a file.
-//   fd       - Should be STDOUT_FILENO or STDERR_FILENO
-//   filename - File where output should be stored
-static inline void CaptureTestOutput(int fd, const string & filename) {
-  CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
-  CHECK(s_captured_streams[fd] == NULL);
-  s_captured_streams[fd] = new CapturedStream(fd, filename);
-}
-static inline void CaptureTestStdout() {
-  CaptureTestOutput(STDOUT_FILENO, FLAGS_test_tmpdir + "/captured.out");
-}
-static inline void CaptureTestStderr() {
-  CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
-}
-// Return the size (in bytes) of a file
-static inline size_t GetFileSize(FILE * file) {
-  fseek(file, 0, SEEK_END);
-  return static_cast<size_t>(ftell(file));
-}
-// Read the entire content of a file as a string
-static inline string ReadEntireFile(FILE * file) {
-  const size_t file_size = GetFileSize(file);
-  char * const buffer = new char[file_size];
-
-  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
-  size_t bytes_read = 0;       // # of bytes read so far
-
-  fseek(file, 0, SEEK_SET);
-
-  // Keep reading the file until we cannot read further or the
-  // pre-determined file size is reached.
-  do {
-    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
-    bytes_read += bytes_last_read;
-  } while (bytes_last_read > 0 && bytes_read < file_size);
-
-  const string content = string(buffer, buffer+bytes_read);
-  delete[] buffer;
-
-  return content;
-}
-// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
-// fd is STDERR_FILENO) as a string
-static inline string GetCapturedTestOutput(int fd) {
-  CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
-  CapturedStream * const cap = s_captured_streams[fd];
-  CHECK(cap)
-    << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
-
-  // Make sure everything is flushed.
-  cap->StopCapture();
-
-  // Read the captured file.
-  FILE * const file = fopen(cap->filename().c_str(), "r");
-  const string content = ReadEntireFile(file);
-  fclose(file);
-
-  delete cap;
-  s_captured_streams[fd] = NULL;
-
-  return content;
-}
-// Get the captured stderr of a test as a string.
-static inline string GetCapturedTestStderr() {
-  return GetCapturedTestOutput(STDERR_FILENO);
-}
-
-static const std::size_t kLoggingPrefixLength = 9;
-
-// Check if the string is [IWEF](\d{8}|YEARDATE)
-static inline bool IsLoggingPrefix(const string& s) {
-  if (s.size() != kLoggingPrefixLength) {
-    return false;
-  }
-  if (!strchr("IWEF", s[0])) return false;
-  for (size_t i = 1; i <= 8; ++i) {
-    if (!isdigit(s[i]) && s[i] != "YEARDATE"[i-1]) return false;
-  }
-  return true;
-}
-
-// Convert log output into normalized form.
-//
-// Example:
-//     I20200102 030405 logging_unittest.cc:345] RAW: vlog -1
-//  => IYEARDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1
-static inline string MungeLine(const string& line) {
-  string before, logcode_date, time, thread_lineinfo;
-  std::size_t begin_of_logging_prefix = 0;
-  for (; begin_of_logging_prefix + kLoggingPrefixLength < line.size();
-       ++begin_of_logging_prefix) {
-    if (IsLoggingPrefix(
-            line.substr(begin_of_logging_prefix, kLoggingPrefixLength))) {
-      break;
-    }
-  }
-  if (begin_of_logging_prefix + kLoggingPrefixLength >= line.size()) {
-    return line;
-  } else if (begin_of_logging_prefix > 0) {
-    before = line.substr(0, begin_of_logging_prefix - 1);
-  }
-  std::istringstream iss(line.substr(begin_of_logging_prefix));
-  iss >> logcode_date;
-  iss >> time;
-  iss >> thread_lineinfo;
-  CHECK(!thread_lineinfo.empty());
-  if (thread_lineinfo[thread_lineinfo.size() - 1] != ']') {
-    // We found thread ID.
-    string tmp;
-    iss >> tmp;
-    CHECK(!tmp.empty());
-    CHECK_EQ(']', tmp[tmp.size() - 1]);
-    thread_lineinfo = "THREADID " + tmp;
-  }
-  size_t index = thread_lineinfo.find(':');
-  CHECK_NE(string::npos, index);
-  thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]";
-  string rest;
-  std::getline(iss, rest);
-  return (before + logcode_date[0] + "YEARDATE TIME__ " + thread_lineinfo +
-          MungeLine(rest));
-}
-
-static inline void StringReplace(string* str,
-                          const string& oldsub,
-                          const string& newsub) {
-  size_t pos = str->find(oldsub);
-  if (pos != string::npos) {
-    str->replace(pos, oldsub.size(), newsub);
-  }
-}
-
-static inline string Munge(const string& filename) {
-  FILE* fp = fopen(filename.c_str(), "rb");
-  CHECK(fp != NULL) << filename << ": couldn't open";
-  char buf[4096];
-  string result;
-  while (fgets(buf, 4095, fp)) {
-    string line = MungeLine(buf);
-    const size_t str_size = 256;
-    char null_str[str_size];
-    char ptr_str[str_size];
-    snprintf(null_str, str_size, "%p", static_cast<void*>(NULL));
-    snprintf(ptr_str, str_size, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE));
-
-    StringReplace(&line, "__NULLP__", null_str);
-    StringReplace(&line, "__PTRTEST__", ptr_str);
-
-    StringReplace(&line, "__SUCCESS__", StrError(0));
-    StringReplace(&line, "__ENOENT__", StrError(ENOENT));
-    StringReplace(&line, "__EINTR__", StrError(EINTR));
-    StringReplace(&line, "__ENXIO__", StrError(ENXIO));
-    StringReplace(&line, "__ENOEXEC__", StrError(ENOEXEC));
-    result += line + "\n";
-  }
-  fclose(fp);
-  return result;
-}
-
-static inline void WriteToFile(const string& body, const string& file) {
-  FILE* fp = fopen(file.c_str(), "wb");
-  fwrite(body.data(), 1, body.size(), fp);
-  fclose(fp);
-}
-
-static inline bool MungeAndDiffTest(const string& golden_filename,
-                                    CapturedStream* cap) {
-  if (cap == s_captured_streams[STDOUT_FILENO]) {
-    CHECK(cap) << ": did you forget CaptureTestStdout()?";
-  } else {
-    CHECK(cap) << ": did you forget CaptureTestStderr()?";
-  }
-
-  cap->StopCapture();
-
-  // Run munge
-  const string captured = Munge(cap->filename());
-  const string golden = Munge(golden_filename);
-  if (captured != golden) {
-    fprintf(stderr,
-            "Test with golden file failed. We'll try to show the diff:\n");
-    string munged_golden = golden_filename + ".munged";
-    WriteToFile(golden, munged_golden);
-    string munged_captured = cap->filename() + ".munged";
-    WriteToFile(captured, munged_captured);
-#ifdef GLOG_OS_WINDOWS
-    string diffcmd("fc " + munged_golden + " " + munged_captured);
-#else
-    string diffcmd("diff -u " + munged_golden + " " + munged_captured);
-#endif
-    if (system(diffcmd.c_str()) != 0) {
-      fprintf(stderr, "diff command was failed.\n");
-    }
-    unlink(munged_golden.c_str());
-    unlink(munged_captured.c_str());
-    return false;
-  }
-  LOG(INFO) << "Diff was successful";
-  return true;
-}
-
-static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
-  return MungeAndDiffTest(golden_filename, s_captured_streams[STDERR_FILENO]);
-}
-
-static inline bool MungeAndDiffTestStdout(const string& golden_filename) {
-  return MungeAndDiffTest(golden_filename, s_captured_streams[STDOUT_FILENO]);
-}
-
-// Save flags used from logging_unittest.cc.
-#ifndef HAVE_LIB_GFLAGS
-struct FlagSaver {
-  FlagSaver()
-      : v_(FLAGS_v),
-        stderrthreshold_(FLAGS_stderrthreshold),
-        logtostderr_(FLAGS_logtostderr),
-        alsologtostderr_(FLAGS_alsologtostderr) {}
-  ~FlagSaver() {
-    FLAGS_v = v_;
-    FLAGS_stderrthreshold = stderrthreshold_;
-    FLAGS_logtostderr = logtostderr_;
-    FLAGS_alsologtostderr = alsologtostderr_;
-  }
-  int v_;
-  int stderrthreshold_;
-  bool logtostderr_;
-  bool alsologtostderr_;
-};
-#endif
-
-class Thread {
- public:
-  virtual ~Thread() {}
-
-  void SetJoinable(bool) {}
-#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
-  void Start() {
-    handle_ = CreateThread(NULL,
-                           0,
-                           &Thread::InvokeThreadW,
-                           this,
-                           0,
-                           &th_);
-    CHECK(handle_) << "CreateThread";
-  }
-  void Join() {
-    WaitForSingleObject(handle_, INFINITE);
-  }
-#elif defined(HAVE_PTHREAD)
-  void Start() {
-    pthread_create(&th_, NULL, &Thread::InvokeThread, this);
-  }
-  void Join() {
-    pthread_join(th_, NULL);
-  }
-#else
-# error No thread implementation.
-#endif
-
- protected:
-  virtual void Run() = 0;
-
- private:
-  static void* InvokeThread(void* self) {
-    (static_cast<Thread*>(self))->Run();
-    return NULL;
-  }
-
-#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
-  static DWORD __stdcall InvokeThreadW(LPVOID self) {
-    InvokeThread(self);
-    return 0;
-  }
-  HANDLE handle_;
-  DWORD th_;
-#else
-  pthread_t th_;
-#endif
-};
-
-static inline void SleepForMilliseconds(unsigned t) {
-#ifndef GLOG_OS_WINDOWS
-# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
-  const struct timespec req = {0, t * 1000 * 1000};
-  nanosleep(&req, NULL);
-# else
-  usleep(t * 1000);
-# endif
-#else
-  Sleep(t);
-#endif
-}
-
-// Add hook for operator new to ensure there are no memory allocation.
-
-void (*g_new_hook)() = NULL;
-
-_END_GOOGLE_NAMESPACE_
-
-void* operator new(size_t size) GOOGLE_GLOG_THROW_BAD_ALLOC {
-  if (GOOGLE_NAMESPACE::g_new_hook) {
-    GOOGLE_NAMESPACE::g_new_hook();
-  }
-  return malloc(size);
-}
-
-void* operator new[](size_t size) GOOGLE_GLOG_THROW_BAD_ALLOC {
-  return ::operator new(size);
-}
-
-void operator delete(void* p) throw() {
-  free(p);
-}
-
-void operator delete(void* p, size_t) throw() {
-  ::operator delete(p);
-}
-
-void operator delete[](void* p) throw() {
-  ::operator delete(p);
-}
-
-void operator delete[](void* p, size_t) throw() {
-  ::operator delete(p);
-}
diff --git a/third_party/google-glog/src/logging.cc b/third_party/google-glog/src/logging.cc
deleted file mode 100644
index f7e3111..0000000
--- a/third_party/google-glog/src/logging.cc
+++ /dev/null
@@ -1,2726 +0,0 @@
-// Copyright (c) 1999, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite()
-
-#include "utilities.h"
-
-#include <algorithm>
-#include <cassert>
-#include <iomanip>
-#include <string>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>  // For _exit.
-#endif
-#include <climits>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_UTSNAME_H
-# include <sys/utsname.h>  // For uname.
-#endif
-#include <dirent.h>
-#include <ctime>
-#include <fcntl.h>
-#include <cstdio>
-#include <iostream>
-#include <cstdarg>
-#include <cstdlib>
-#ifdef HAVE_PWD_H
-# include <pwd.h>
-#endif
-#ifdef HAVE_SYSLOG_H
-# include <syslog.h>
-#endif
-#include <vector>
-#include <cerrno>                   // for errno
-#include <sstream>
-#ifdef GLOG_OS_WINDOWS
-#include "windows/dirent.h"
-#else
-#include <dirent.h> // for automatic removal of old logs
-#endif
-#include "base/commandlineflags.h"        // to get the program name
-#include <glog/logging.h>
-#include <glog/raw_logging.h>
-#include "base/googleinit.h"
-
-#ifdef HAVE_STACKTRACE
-# include "stacktrace.h"
-#endif
-
-#ifdef __ANDROID__
-#include <android/log.h>
-#endif
-
-using std::string;
-using std::vector;
-using std::setw;
-using std::setfill;
-using std::hex;
-using std::dec;
-using std::min;
-using std::ostream;
-using std::ostringstream;
-
-using std::FILE;
-using std::fwrite;
-using std::fclose;
-using std::fflush;
-using std::fprintf;
-using std::perror;
-
-#ifdef __QNX__
-using std::fdopen;
-#endif
-
-#ifdef _WIN32
-#define fdopen _fdopen
-#endif
-
-// There is no thread annotation support.
-#define EXCLUSIVE_LOCKS_REQUIRED(mu)
-
-static bool BoolFromEnv(const char *varname, bool defval) {
-  const char* const valstr = getenv(varname);
-  if (!valstr) {
-    return defval;
-  }
-  return memchr("tTyY1\0", valstr[0], 6) != NULL;
-}
-
-GLOG_DEFINE_bool(timestamp_in_logfile_name,
-                 BoolFromEnv("GOOGLE_TIMESTAMP_IN_LOGFILE_NAME", true),
-                 "put a timestamp at the end of the log file name");
-GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false),
-                 "log messages go to stderr instead of logfiles");
-GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
-                 "log messages go to stderr in addition to logfiles");
-GLOG_DEFINE_bool(colorlogtostderr, false,
-                 "color messages logged to stderr (if supported by terminal)");
-GLOG_DEFINE_bool(colorlogtostdout, false,
-                 "color messages logged to stdout (if supported by terminal)");
-GLOG_DEFINE_bool(logtostdout, BoolFromEnv("GOOGLE_LOGTOSTDOUT", false),
-                 "log messages go to stdout instead of logfiles");
-#ifdef GLOG_OS_LINUX
-GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. "
-                 "Logs can grow very quickly and they are rarely read before they "
-                 "need to be evicted from memory. Instead, drop them from memory "
-                 "as soon as they are flushed to disk.");
-#endif
-
-// By default, errors (including fatal errors) get logged to stderr as
-// well as the file.
-//
-// The default is ERROR instead of FATAL so that users can see problems
-// when they run a program without having to look in another file.
-DEFINE_int32(stderrthreshold,
-             GOOGLE_NAMESPACE::GLOG_ERROR,
-             "log messages at or above this level are copied to stderr in "
-             "addition to logfiles.  This flag obsoletes --alsologtostderr.");
-
-GLOG_DEFINE_string(alsologtoemail, "",
-                   "log messages go to these email addresses "
-                   "in addition to logfiles");
-GLOG_DEFINE_bool(log_prefix, true,
-                 "Prepend the log prefix to the start of each log line");
-GLOG_DEFINE_bool(log_year_in_prefix, true,
-                 "Include the year in the log prefix");
-GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't "
-                  "actually get logged anywhere");
-GLOG_DEFINE_int32(logbuflevel, 0,
-                  "Buffer log messages logged at this level or lower"
-                  " (-1 means don't buffer; 0 means buffer INFO only;"
-                  " ...)");
-GLOG_DEFINE_int32(logbufsecs, 30,
-                  "Buffer log messages for at most this many seconds");
-
-GLOG_DEFINE_int32(logcleansecs, 60 * 5, // every 5 minutes
-                  "Clean overdue logs every this many seconds");
-
-GLOG_DEFINE_int32(logemaillevel, 999,
-                  "Email log messages logged at this level or higher"
-                  " (0 means email all; 3 means email FATAL only;"
-                  " ...)");
-GLOG_DEFINE_string(logmailer, "",
-                   "Mailer used to send logging email");
-
-// Compute the default value for --log_dir
-static const char* DefaultLogDir() {
-  const char* env;
-  env = getenv("GOOGLE_LOG_DIR");
-  if (env != NULL && env[0] != '\0') {
-    return env;
-  }
-  env = getenv("TEST_TMPDIR");
-  if (env != NULL && env[0] != '\0') {
-    return env;
-  }
-  return "";
-}
-
-namespace aos {
-void FatalUnsetRealtimePriority() __attribute__((weak));
-}
-
-static void MaybeUnsetRealtime() {
-  if (&aos::FatalUnsetRealtimePriority != nullptr) {
-    aos::FatalUnsetRealtimePriority();
-  }
-}
-
-GLOG_DEFINE_int32(logfile_mode, 0664, "Log file mode/permissions.");
-
-GLOG_DEFINE_string(log_dir, DefaultLogDir(),
-                   "If specified, logfiles are written into this directory instead "
-                   "of the default logging directory.");
-GLOG_DEFINE_string(log_link, "", "Put additional links to the log "
-                   "files in this directory");
-
-GLOG_DEFINE_uint32(max_log_size, 1800,
-                   "approx. maximum log file size (in MB). A value of 0 will "
-                   "be silently overridden to 1.");
-
-GLOG_DEFINE_bool(stop_logging_if_full_disk, false,
-                 "Stop attempting to log to disk if the disk is full.");
-
-GLOG_DEFINE_string(log_backtrace_at, "",
-                   "Emit a backtrace when logging at file:linenum.");
-
-GLOG_DEFINE_bool(log_utc_time, false,
-    "Use UTC time for logging.");
-
-// TODO(hamaji): consider windows
-#define PATH_SEPARATOR '/'
-
-#ifndef HAVE_PREAD
-#if defined(GLOG_OS_WINDOWS)
-#include <basetsd.h>
-#define ssize_t SSIZE_T
-#endif
-static ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
-  off_t orig_offset = lseek(fd, 0, SEEK_CUR);
-  if (orig_offset == (off_t)-1)
-    return -1;
-  if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
-    return -1;
-  ssize_t len = read(fd, buf, count);
-  if (len < 0)
-    return len;
-  if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
-    return -1;
-  return len;
-}
-#endif  // !HAVE_PREAD
-
-#ifndef HAVE_PWRITE
-static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) {
-  off_t orig_offset = lseek(fd, 0, SEEK_CUR);
-  if (orig_offset == (off_t)-1)
-    return -1;
-  if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
-    return -1;
-  ssize_t len = write(fd, buf, count);
-  if (len < 0)
-    return len;
-  if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
-    return -1;
-  return len;
-}
-#endif  // !HAVE_PWRITE
-
-static void GetHostName(string* hostname) {
-#if defined(HAVE_SYS_UTSNAME_H)
-  struct utsname buf;
-  if (uname(&buf) < 0) {
-    // ensure null termination on failure
-    *buf.nodename = '\0';
-  }
-  *hostname = buf.nodename;
-#elif defined(GLOG_OS_WINDOWS)
-  char buf[MAX_COMPUTERNAME_LENGTH + 1];
-  DWORD len = MAX_COMPUTERNAME_LENGTH + 1;
-  if (GetComputerNameA(buf, &len)) {
-    *hostname = buf;
-  } else {
-    hostname->clear();
-  }
-#else
-# warning There is no way to retrieve the host name.
-  *hostname = "(unknown)";
-#endif
-}
-
-// Returns true iff terminal supports using colors in output.
-static bool TerminalSupportsColor() {
-  bool term_supports_color = false;
-#ifdef GLOG_OS_WINDOWS
-  // on Windows TERM variable is usually not set, but the console does
-  // support colors.
-  term_supports_color = true;
-#else
-  // On non-Windows platforms, we rely on the TERM variable.
-  const char* const term = getenv("TERM");
-  if (term != NULL && term[0] != '\0') {
-    term_supports_color =
-      !strcmp(term, "xterm") ||
-      !strcmp(term, "xterm-color") ||
-      !strcmp(term, "xterm-256color") ||
-      !strcmp(term, "screen-256color") ||
-      !strcmp(term, "konsole") ||
-      !strcmp(term, "konsole-16color") ||
-      !strcmp(term, "konsole-256color") ||
-      !strcmp(term, "screen") ||
-      !strcmp(term, "linux") ||
-      !strcmp(term, "cygwin");
-  }
-#endif
-  return term_supports_color;
-}
-
-_START_GOOGLE_NAMESPACE_
-
-enum GLogColor {
-  COLOR_DEFAULT,
-  COLOR_RED,
-  COLOR_GREEN,
-  COLOR_YELLOW
-};
-
-static GLogColor SeverityToColor(LogSeverity severity) {
-  assert(severity >= 0 && severity < NUM_SEVERITIES);
-  GLogColor color = COLOR_DEFAULT;
-  switch (severity) {
-  case GLOG_INFO:
-    color = COLOR_DEFAULT;
-    break;
-  case GLOG_WARNING:
-    color = COLOR_YELLOW;
-    break;
-  case GLOG_ERROR:
-  case GLOG_FATAL:
-    color = COLOR_RED;
-    break;
-  default:
-    // should never get here.
-    assert(false);
-  }
-  return color;
-}
-
-#ifdef GLOG_OS_WINDOWS
-
-// Returns the character attribute for the given color.
-static WORD GetColorAttribute(GLogColor color) {
-  switch (color) {
-    case COLOR_RED:    return FOREGROUND_RED;
-    case COLOR_GREEN:  return FOREGROUND_GREEN;
-    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
-    default:           return 0;
-  }
-}
-
-#else
-
-// Returns the ANSI color code for the given color.
-static const char* GetAnsiColorCode(GLogColor color) {
-  switch (color) {
-  case COLOR_RED:     return "1";
-  case COLOR_GREEN:   return "2";
-  case COLOR_YELLOW:  return "3";
-  case COLOR_DEFAULT:  return "";
-  };
-  return NULL; // stop warning about return type.
-}
-
-#endif  // GLOG_OS_WINDOWS
-
-// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0
-static uint32 MaxLogSize() {
-  return (FLAGS_max_log_size > 0 && FLAGS_max_log_size < 4096
-              ? FLAGS_max_log_size
-              : 1);
-}
-
-// An arbitrary limit on the length of a single log message.  This
-// is so that streaming can be done more efficiently.
-const size_t LogMessage::kMaxLogMessageLen = 30000;
-
-struct LogMessage::LogMessageData  {
-  LogMessageData();
-
-  int preserved_errno_;      // preserved errno
-  // Buffer space; contains complete message text.
-  char message_text_[LogMessage::kMaxLogMessageLen+1];
-  LogStream stream_;
-  char severity_;      // What level is this LogMessage logged at?
-  int line_;                 // line number where logging call is.
-  void (LogMessage::*send_method_)();  // Call this in destructor to send
-  union {  // At most one of these is used: union to keep the size low.
-    LogSink* sink_;             // NULL or sink to send message to
-    std::vector<std::string>* outvec_; // NULL or vector to push message onto
-    std::string* message_;             // NULL or string to write message into
-  };
-  size_t num_prefix_chars_;     // # of chars of prefix in this message
-  size_t num_chars_to_log_;     // # of chars of msg to send to log
-  size_t num_chars_to_syslog_;  // # of chars of msg to send to syslog
-  const char* basename_;        // basename of file that called LOG
-  const char* fullname_;        // fullname of file that called LOG
-  bool has_been_flushed_;       // false => data has not been flushed
-  bool first_fatal_;            // true => this was first fatal msg
-
- private:
-  LogMessageData(const LogMessageData&);
-  void operator=(const LogMessageData&);
-};
-
-// A mutex that allows only one thread to log at a time, to keep things from
-// getting jumbled.  Some other very uncommon logging operations (like
-// changing the destination file for log messages of a given severity) also
-// lock this mutex.  Please be sure that anybody who might possibly need to
-// lock it does so.
-static Mutex log_mutex;
-
-// Number of messages sent at each severity.  Under log_mutex.
-int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0};
-
-// Globally disable log writing (if disk is full)
-static bool stop_writing = false;
-
-const char*const LogSeverityNames[NUM_SEVERITIES] = {
-  "INFO", "WARNING", "ERROR", "FATAL"
-};
-
-// Has the user called SetExitOnDFatal(true)?
-static bool exit_on_dfatal = true;
-
-const char* GetLogSeverityName(LogSeverity severity) {
-  return LogSeverityNames[severity];
-}
-
-static bool SendEmailInternal(const char*dest, const char *subject,
-                              const char*body, bool use_logging);
-
-base::Logger::~Logger() {
-}
-
-#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
-namespace  {
-  // Optional user-configured callback to print custom prefixes.
-  CustomPrefixCallback custom_prefix_callback = NULL;
-  // User-provided data to pass to the callback:
-  void* custom_prefix_callback_data = NULL;
-}
-#endif
-
-namespace {
-
-// Encapsulates all file-system related state
-class LogFileObject : public base::Logger {
- public:
-  LogFileObject(LogSeverity severity, const char* base_filename);
-  ~LogFileObject();
-
-  virtual void Write(bool force_flush, // Should we force a flush here?
-                     time_t timestamp,  // Timestamp for this entry
-                     const char* message,
-                     size_t message_len);
-
-  // Configuration options
-  void SetBasename(const char* basename);
-  void SetExtension(const char* ext);
-  void SetSymlinkBasename(const char* symlink_basename);
-
-  // Normal flushing routine
-  virtual void Flush();
-
-  // It is the actual file length for the system loggers,
-  // i.e., INFO, ERROR, etc.
-  virtual uint32 LogSize() {
-    MutexLock l(&lock_);
-    return file_length_;
-  }
-
-  // Internal flush routine.  Exposed so that FlushLogFilesUnsafe()
-  // can avoid grabbing a lock.  Usually Flush() calls it after
-  // acquiring lock_.
-  void FlushUnlocked();
-
- private:
-  static const uint32 kRolloverAttemptFrequency = 0x20;
-
-  Mutex lock_;
-  bool base_filename_selected_;
-  string base_filename_;
-  string symlink_basename_;
-  string filename_extension_;     // option users can specify (eg to add port#)
-  FILE* file_;
-  LogSeverity severity_;
-  uint32 bytes_since_flush_;
-  uint32 dropped_mem_length_;
-  uint32 file_length_;
-  unsigned int rollover_attempt_;
-  int64 next_flush_time_;         // cycle count at which to flush log
-  WallTime start_time_;
-
-  // Actually create a logfile using the value of base_filename_ and the
-  // optional argument time_pid_string
-  // REQUIRES: lock_ is held
-  bool CreateLogfile(const string& time_pid_string);
-};
-
-// Encapsulate all log cleaner related states
-class LogCleaner {
- public:
-  LogCleaner();
-
-  // Setting overdue_days to 0 days will delete all logs.
-  void Enable(unsigned int overdue_days);
-  void Disable();
-
-  // update next_cleanup_time_
-  void UpdateCleanUpTime();
-
-  void Run(bool base_filename_selected,
-           const string& base_filename,
-           const string& filename_extension);
-
-  bool enabled() const { return enabled_; }
-
- private:
-  vector<string> GetOverdueLogNames(string log_directory, unsigned int days,
-                                    const string& base_filename,
-                                    const string& filename_extension) const;
-
-  bool IsLogFromCurrentProject(const string& filepath,
-                               const string& base_filename,
-                               const string& filename_extension) const;
-
-  bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const;
-
-  bool enabled_;
-  unsigned int overdue_days_;
-  int64 next_cleanup_time_;         // cycle count at which to clean overdue log
-};
-
-LogCleaner log_cleaner;
-
-}  // namespace
-
-class LogDestination {
- public:
-  friend class LogMessage;
-  friend void ReprintFatalMessage();
-  friend base::Logger* base::GetLogger(LogSeverity);
-  friend void base::SetLogger(LogSeverity, base::Logger*);
-
-  // These methods are just forwarded to by their global versions.
-  static void SetLogDestination(LogSeverity severity,
-				const char* base_filename);
-  static void SetLogSymlink(LogSeverity severity,
-                            const char* symlink_basename);
-  static void AddLogSink(LogSink *destination);
-  static void RemoveLogSink(LogSink *destination);
-  static void SetLogFilenameExtension(const char* filename_extension);
-  static void SetStderrLogging(LogSeverity min_severity);
-  static void SetEmailLogging(LogSeverity min_severity, const char* addresses);
-  static void LogToStderr();
-  // Flush all log files that are at least at the given severity level
-  static void FlushLogFiles(int min_severity);
-  static void FlushLogFilesUnsafe(int min_severity);
-
-  // we set the maximum size of our packet to be 1400, the logic being
-  // to prevent fragmentation.
-  // Really this number is arbitrary.
-  static const int kNetworkBytes = 1400;
-
-  static const string& hostname();
-  static const bool& terminal_supports_color() {
-    return terminal_supports_color_;
-  }
-
-  static void DeleteLogDestinations();
-
- private:
-  LogDestination(LogSeverity severity, const char* base_filename);
-  ~LogDestination();
-
-  // Take a log message of a particular severity and log it to stderr
-  // iff it's of a high enough severity to deserve it.
-  static void MaybeLogToStderr(LogSeverity severity, const char* message,
-			       size_t message_len, size_t prefix_len);
-
-  // Take a log message of a particular severity and log it to email
-  // iff it's of a high enough severity to deserve it.
-  static void MaybeLogToEmail(LogSeverity severity, const char* message,
-			      size_t len);
-  // Take a log message of a particular severity and log it to a file
-  // iff the base filename is not "" (which means "don't log to me")
-  static void MaybeLogToLogfile(LogSeverity severity,
-                                time_t timestamp,
-				const char* message, size_t len);
-  // Take a log message of a particular severity and log it to the file
-  // for that severity and also for all files with severity less than
-  // this severity.
-  static void LogToAllLogfiles(LogSeverity severity,
-                               time_t timestamp,
-                               const char* message, size_t len);
-
-  // Send logging info to all registered sinks.
-  static void LogToSinks(LogSeverity severity, const char* full_filename,
-                         const char* base_filename, int line,
-                         const LogMessageTime& logmsgtime, const char* message,
-                         size_t message_len);
-
-  // Wait for all registered sinks via WaitTillSent
-  // including the optional one in "data".
-  static void WaitForSinks(LogMessage::LogMessageData* data);
-
-  static LogDestination* log_destination(LogSeverity severity);
-
-  LogFileObject fileobject_;
-  base::Logger* logger_;      // Either &fileobject_, or wrapper around it
-
-  static LogDestination* log_destinations_[NUM_SEVERITIES];
-  static LogSeverity email_logging_severity_;
-  static string addresses_;
-  static string hostname_;
-  static bool terminal_supports_color_;
-
-  // arbitrary global logging destinations.
-  static vector<LogSink*>* sinks_;
-
-  // Protects the vector sinks_,
-  // but not the LogSink objects its elements reference.
-  static Mutex sink_mutex_;
-
-  // Disallow
-  LogDestination(const LogDestination&);
-  LogDestination& operator=(const LogDestination&);
-};
-
-// Errors do not get logged to email by default.
-LogSeverity LogDestination::email_logging_severity_ = 99999;
-
-string LogDestination::addresses_;
-string LogDestination::hostname_;
-
-vector<LogSink*>* LogDestination::sinks_ = NULL;
-Mutex LogDestination::sink_mutex_;
-bool LogDestination::terminal_supports_color_ = TerminalSupportsColor();
-
-/* static */
-const string& LogDestination::hostname() {
-  if (hostname_.empty()) {
-    GetHostName(&hostname_);
-    if (hostname_.empty()) {
-      hostname_ = "(unknown)";
-    }
-  }
-  return hostname_;
-}
-
-LogDestination::LogDestination(LogSeverity severity,
-                               const char* base_filename)
-  : fileobject_(severity, base_filename),
-    logger_(&fileobject_) {
-}
-
-LogDestination::~LogDestination() {
-  if (logger_ && logger_ != &fileobject_) {
-    // Delete user-specified logger set via SetLogger().
-    delete logger_;
-  }
-}
-
-inline void LogDestination::FlushLogFilesUnsafe(int min_severity) {
-  // assume we have the log_mutex or we simply don't care
-  // about it
-  for (int i = min_severity; i < NUM_SEVERITIES; i++) {
-    LogDestination* log = log_destinations_[i];
-    if (log != NULL) {
-      // Flush the base fileobject_ logger directly instead of going
-      // through any wrappers to reduce chance of deadlock.
-      log->fileobject_.FlushUnlocked();
-    }
-  }
-}
-
-inline void LogDestination::FlushLogFiles(int min_severity) {
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&log_mutex);
-  for (int i = min_severity; i < NUM_SEVERITIES; i++) {
-    LogDestination* log = log_destination(i);
-    if (log != NULL) {
-      log->logger_->Flush();
-    }
-  }
-}
-
-inline void LogDestination::SetLogDestination(LogSeverity severity,
-					      const char* base_filename) {
-  assert(severity >= 0 && severity < NUM_SEVERITIES);
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&log_mutex);
-  log_destination(severity)->fileobject_.SetBasename(base_filename);
-}
-
-inline void LogDestination::SetLogSymlink(LogSeverity severity,
-                                          const char* symlink_basename) {
-  CHECK_GE(severity, 0);
-  CHECK_LT(severity, NUM_SEVERITIES);
-  MutexLock l(&log_mutex);
-  log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename);
-}
-
-inline void LogDestination::AddLogSink(LogSink *destination) {
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&sink_mutex_);
-  if (!sinks_)  sinks_ = new vector<LogSink*>;
-  sinks_->push_back(destination);
-}
-
-inline void LogDestination::RemoveLogSink(LogSink *destination) {
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&sink_mutex_);
-  // This doesn't keep the sinks in order, but who cares?
-  if (sinks_) {
-    sinks_->erase(std::remove(sinks_->begin(), sinks_->end(), destination), sinks_->end());
-  }
-}
-
-inline void LogDestination::SetLogFilenameExtension(const char* ext) {
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&log_mutex);
-  for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) {
-    log_destination(severity)->fileobject_.SetExtension(ext);
-  }
-}
-
-inline void LogDestination::SetStderrLogging(LogSeverity min_severity) {
-  assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&log_mutex);
-  FLAGS_stderrthreshold = min_severity;
-}
-
-inline void LogDestination::LogToStderr() {
-  // *Don't* put this stuff in a mutex lock, since SetStderrLogging &
-  // SetLogDestination already do the locking!
-  SetStderrLogging(0);            // thus everything is "also" logged to stderr
-  for ( int i = 0; i < NUM_SEVERITIES; ++i ) {
-    SetLogDestination(i, "");     // "" turns off logging to a logfile
-  }
-}
-
-inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
-					    const char* addresses) {
-  assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // all this stuff.
-  MutexLock l(&log_mutex);
-  LogDestination::email_logging_severity_ = min_severity;
-  LogDestination::addresses_ = addresses;
-}
-
-static void ColoredWriteToStderrOrStdout(FILE* output, LogSeverity severity,
-                                         const char* message, size_t len) {
-  bool is_stdout = (output == stdout);
-  const GLogColor color = (LogDestination::terminal_supports_color() &&
-                           ((!is_stdout && FLAGS_colorlogtostderr) ||
-                            (is_stdout && FLAGS_colorlogtostdout)))
-                              ? SeverityToColor(severity)
-                              : COLOR_DEFAULT;
-
-  // Avoid using cerr from this module since we may get called during
-  // exit code, and cerr may be partially or fully destroyed by then.
-  if (COLOR_DEFAULT == color) {
-    fwrite(message, len, 1, output);
-    return;
-  }
-#ifdef GLOG_OS_WINDOWS
-  const HANDLE output_handle =
-      GetStdHandle(is_stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
-
-  // Gets the current text color.
-  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
-  GetConsoleScreenBufferInfo(output_handle, &buffer_info);
-  const WORD old_color_attrs = buffer_info.wAttributes;
-
-  // We need to flush the stream buffers into the console before each
-  // SetConsoleTextAttribute call lest it affect the text that is already
-  // printed but has not yet reached the console.
-  fflush(output);
-  SetConsoleTextAttribute(output_handle,
-                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
-  fwrite(message, len, 1, output);
-  fflush(output);
-  // Restores the text color.
-  SetConsoleTextAttribute(output_handle, old_color_attrs);
-#else
-  fprintf(output, "\033[0;3%sm", GetAnsiColorCode(color));
-  fwrite(message, len, 1, output);
-  fprintf(output, "\033[m");  // Resets the terminal to default.
-#endif  // GLOG_OS_WINDOWS
-}
-
-static void ColoredWriteToStdout(LogSeverity severity, const char* message,
-                                 size_t len) {
-  FILE* output = stdout;
-  // We also need to send logs to the stderr when the severity is
-  // higher or equal to the stderr threshold.
-  if (severity >= FLAGS_stderrthreshold) {
-    output = stderr;
-  }
-  ColoredWriteToStderrOrStdout(output, severity, message, len);
-}
-
-static void ColoredWriteToStderr(LogSeverity severity, const char* message,
-                                 size_t len) {
-  ColoredWriteToStderrOrStdout(stderr, severity, message, len);
-}
-
-static void WriteToStderr(const char* message, size_t len) {
-  // Avoid using cerr from this module since we may get called during
-  // exit code, and cerr may be partially or fully destroyed by then.
-  fwrite(message, len, 1, stderr);
-}
-
-inline void LogDestination::MaybeLogToStderr(LogSeverity severity,
-					     const char* message, size_t message_len, size_t prefix_len) {
-  if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) {
-    ColoredWriteToStderr(severity, message, message_len);
-#ifdef GLOG_OS_WINDOWS
-    (void) prefix_len;
-    // On Windows, also output to the debugger
-    ::OutputDebugStringA(message);
-#elif defined(__ANDROID__)
-    // On Android, also output to logcat
-    const int android_log_levels[NUM_SEVERITIES] = {
-      ANDROID_LOG_INFO,
-      ANDROID_LOG_WARN,
-      ANDROID_LOG_ERROR,
-      ANDROID_LOG_FATAL,
-    };
-    __android_log_write(android_log_levels[severity],
-                        glog_internal_namespace_::ProgramInvocationShortName(),
-                        message + prefix_len);
-#else
-    (void) prefix_len;
-#endif
-  }
-}
-
-
-inline void LogDestination::MaybeLogToEmail(LogSeverity severity,
-					    const char* message, size_t len) {
-  if (severity >= email_logging_severity_ ||
-      severity >= FLAGS_logemaillevel) {
-    string to(FLAGS_alsologtoemail);
-    if (!addresses_.empty()) {
-      if (!to.empty()) {
-        to += ",";
-      }
-      to += addresses_;
-    }
-    const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " +
-                         glog_internal_namespace_::ProgramInvocationShortName());
-    string body(hostname());
-    body += "\n\n";
-    body.append(message, len);
-
-    // should NOT use SendEmail().  The caller of this function holds the
-    // log_mutex and SendEmail() calls LOG/VLOG which will block trying to
-    // acquire the log_mutex object.  Use SendEmailInternal() and set
-    // use_logging to false.
-    SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false);
-  }
-}
-
-
-inline void LogDestination::MaybeLogToLogfile(LogSeverity severity,
-                                              time_t timestamp,
-					      const char* message,
-					      size_t len) {
-  const bool should_flush = severity > FLAGS_logbuflevel;
-  LogDestination* destination = log_destination(severity);
-  destination->logger_->Write(should_flush, timestamp, message, len);
-}
-
-inline void LogDestination::LogToAllLogfiles(LogSeverity severity,
-                                             time_t timestamp,
-                                             const char* message,
-                                             size_t len) {
-  if (FLAGS_logtostdout) {  // global flag: never log to file
-    ColoredWriteToStdout(severity, message, len);
-  } else if (FLAGS_logtostderr) {  // global flag: never log to file
-    ColoredWriteToStderr(severity, message, len);
-  } else {
-    for (int i = severity; i >= 0; --i) {
-      LogDestination::MaybeLogToLogfile(i, timestamp, message, len);
-    }
-  }
-}
-
-inline void LogDestination::LogToSinks(LogSeverity severity,
-                                       const char* full_filename,
-                                       const char* base_filename, int line,
-                                       const LogMessageTime& logmsgtime,
-                                       const char* message,
-                                       size_t message_len) {
-  ReaderMutexLock l(&sink_mutex_);
-  if (sinks_) {
-    for (size_t i = sinks_->size(); i-- > 0; ) {
-      (*sinks_)[i]->send(severity, full_filename, base_filename,
-                         line, logmsgtime, message, message_len);
-    }
-  }
-}
-
-inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) {
-  ReaderMutexLock l(&sink_mutex_);
-  if (sinks_) {
-    for (size_t i = sinks_->size(); i-- > 0; ) {
-      (*sinks_)[i]->WaitTillSent();
-    }
-  }
-  const bool send_to_sink =
-      (data->send_method_ == &LogMessage::SendToSink) ||
-      (data->send_method_ == &LogMessage::SendToSinkAndLog);
-  if (send_to_sink && data->sink_ != NULL) {
-    data->sink_->WaitTillSent();
-  }
-}
-
-LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES];
-
-inline LogDestination* LogDestination::log_destination(LogSeverity severity) {
-  assert(severity >=0 && severity < NUM_SEVERITIES);
-  if (!log_destinations_[severity]) {
-    log_destinations_[severity] = new LogDestination(severity, NULL);
-  }
-  return log_destinations_[severity];
-}
-
-void LogDestination::DeleteLogDestinations() {
-  for (int severity = 0; severity < NUM_SEVERITIES; ++severity) {
-    delete log_destinations_[severity];
-    log_destinations_[severity] = NULL;
-  }
-  MutexLock l(&sink_mutex_);
-  delete sinks_;
-  sinks_ = NULL;
-}
-
-namespace {
-
-std::string g_application_fingerprint;
-
-} // namespace
-
-void SetApplicationFingerprint(const std::string& fingerprint) {
-  g_application_fingerprint = fingerprint;
-}
-
-namespace {
-
-// Directory delimiter; Windows supports both forward slashes and backslashes
-#ifdef GLOG_OS_WINDOWS
-const char possible_dir_delim[] = {'\\', '/'};
-#else
-const char possible_dir_delim[] = {'/'};
-#endif
-
-string PrettyDuration(int secs) {
-  std::stringstream result;
-  int mins = secs / 60;
-  int hours = mins / 60;
-  mins = mins % 60;
-  secs = secs % 60;
-  result.fill('0');
-  result << hours << ':' << setw(2) << mins << ':' << setw(2) << secs;
-  return result.str();
-}
-
-
-LogFileObject::LogFileObject(LogSeverity severity,
-                             const char* base_filename)
-  : base_filename_selected_(base_filename != NULL),
-    base_filename_((base_filename != NULL) ? base_filename : ""),
-    symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
-    filename_extension_(),
-    file_(NULL),
-    severity_(severity),
-    bytes_since_flush_(0),
-    dropped_mem_length_(0),
-    file_length_(0),
-    rollover_attempt_(kRolloverAttemptFrequency-1),
-    next_flush_time_(0),
-    start_time_(WallTime_Now()) {
-  assert(severity >= 0);
-  assert(severity < NUM_SEVERITIES);
-}
-
-LogFileObject::~LogFileObject() {
-  MutexLock l(&lock_);
-  if (file_ != NULL) {
-    fclose(file_);
-    file_ = NULL;
-  }
-}
-
-void LogFileObject::SetBasename(const char* basename) {
-  MutexLock l(&lock_);
-  base_filename_selected_ = true;
-  if (base_filename_ != basename) {
-    // Get rid of old log file since we are changing names
-    if (file_ != NULL) {
-      fclose(file_);
-      file_ = NULL;
-      rollover_attempt_ = kRolloverAttemptFrequency-1;
-    }
-    base_filename_ = basename;
-  }
-}
-
-void LogFileObject::SetExtension(const char* ext) {
-  MutexLock l(&lock_);
-  if (filename_extension_ != ext) {
-    // Get rid of old log file since we are changing names
-    if (file_ != NULL) {
-      fclose(file_);
-      file_ = NULL;
-      rollover_attempt_ = kRolloverAttemptFrequency-1;
-    }
-    filename_extension_ = ext;
-  }
-}
-
-void LogFileObject::SetSymlinkBasename(const char* symlink_basename) {
-  MutexLock l(&lock_);
-  symlink_basename_ = symlink_basename;
-}
-
-void LogFileObject::Flush() {
-  MutexLock l(&lock_);
-  FlushUnlocked();
-}
-
-void LogFileObject::FlushUnlocked(){
-  if (file_ != NULL) {
-    fflush(file_);
-    bytes_since_flush_ = 0;
-  }
-  // Figure out when we are due for another flush.
-  const int64 next = (FLAGS_logbufsecs
-                      * static_cast<int64>(1000000));  // in usec
-  next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
-}
-
-bool LogFileObject::CreateLogfile(const string& time_pid_string) {
-  string string_filename = base_filename_;
-  if (FLAGS_timestamp_in_logfile_name) {
-    string_filename += time_pid_string;
-  }
-  string_filename += filename_extension_;
-  const char* filename = string_filename.c_str();
-  //only write to files, create if non-existant.
-  int flags = O_WRONLY | O_CREAT;
-  if (FLAGS_timestamp_in_logfile_name) {
-    //demand that the file is unique for our timestamp (fail if it exists).
-    flags = flags | O_EXCL;
-  }
-  int fd = open(filename, flags, static_cast<mode_t>(FLAGS_logfile_mode));
-  if (fd == -1) return false;
-#ifdef HAVE_FCNTL
-  // Mark the file close-on-exec. We don't really care if this fails
-  fcntl(fd, F_SETFD, FD_CLOEXEC);
-
-  // Mark the file as exclusive write access to avoid two clients logging to the
-  // same file. This applies particularly when !FLAGS_timestamp_in_logfile_name
-  // (otherwise open would fail because the O_EXCL flag on similar filename).
-  // locks are released on unlock or close() automatically, only after log is
-  // released.
-  // This will work after a fork as it is not inherited (not stored in the fd).
-  // Lock will not be lost because the file is opened with exclusive lock (write)
-  // and we will never read from it inside the process.
-  // TODO windows implementation of this (as flock is not available on mingw).
-  static struct flock w_lock;
-
-  w_lock.l_type = F_WRLCK;
-  w_lock.l_start = 0;
-  w_lock.l_whence = SEEK_SET;
-  w_lock.l_len = 0;
-
-  int wlock_ret = fcntl(fd, F_SETLK, &w_lock);
-  if (wlock_ret == -1) {
-      close(fd); //as we are failing already, do not check errors here
-      return false;
-  }
-#endif
-
-  //fdopen in append mode so if the file exists it will fseek to the end
-  file_ = fdopen(fd, "a");  // Make a FILE*.
-  if (file_ == NULL) {  // Man, we're screwed!
-    close(fd);
-    if (FLAGS_timestamp_in_logfile_name) {
-      unlink(filename);  // Erase the half-baked evidence: an unusable log file, only if we just created it.
-    }
-    return false;
-  }
-#ifdef GLOG_OS_WINDOWS
-  // https://github.com/golang/go/issues/27638 - make sure we seek to the end to append
-  // empirically replicated with wine over mingw build
-  if (!FLAGS_timestamp_in_logfile_name) {
-    if (fseek(file_, 0, SEEK_END) != 0) {
-      return false;
-    }
-  }
-#endif
-  // We try to create a symlink called <program_name>.<severity>,
-  // which is easier to use.  (Every time we create a new logfile,
-  // we destroy the old symlink and create a new one, so it always
-  // points to the latest logfile.)  If it fails, we're sad but it's
-  // no error.
-  if (!symlink_basename_.empty()) {
-    // take directory from filename
-    const char* slash = strrchr(filename, PATH_SEPARATOR);
-    const string linkname =
-      symlink_basename_ + '.' + LogSeverityNames[severity_];
-    string linkpath;
-    if ( slash ) linkpath = string(filename, static_cast<size_t>(slash-filename+1));  // get dirname
-    linkpath += linkname;
-    unlink(linkpath.c_str());                    // delete old one if it exists
-
-#if defined(GLOG_OS_WINDOWS)
-    // TODO(hamaji): Create lnk file on Windows?
-#elif defined(HAVE_UNISTD_H)
-    // We must have unistd.h.
-    // Make the symlink be relative (in the same dir) so that if the
-    // entire log directory gets relocated the link is still valid.
-    const char *linkdest = slash ? (slash + 1) : filename;
-    if (symlink(linkdest, linkpath.c_str()) != 0) {
-      // silently ignore failures
-    }
-
-    // Make an additional link to the log file in a place specified by
-    // FLAGS_log_link, if indicated
-    if (!FLAGS_log_link.empty()) {
-      linkpath = FLAGS_log_link + "/" + linkname;
-      unlink(linkpath.c_str());                  // delete old one if it exists
-      if (symlink(filename, linkpath.c_str()) != 0) {
-        // silently ignore failures
-      }
-    }
-#endif
-  }
-
-  return true;  // Everything worked
-}
-
-void LogFileObject::Write(bool force_flush,
-                          time_t timestamp,
-                          const char* message,
-                          size_t message_len) {
-  MutexLock l(&lock_);
-
-  // We don't log if the base_name_ is "" (which means "don't write")
-  if (base_filename_selected_ && base_filename_.empty()) {
-    return;
-  }
-
-  if (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) {
-    if (file_ != NULL) fclose(file_);
-    file_ = NULL;
-    file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0;
-    rollover_attempt_ = kRolloverAttemptFrequency - 1;
-  }
-
-  // If there's no destination file, make one before outputting
-  if (file_ == NULL) {
-    // Try to rollover the log file every 32 log messages.  The only time
-    // this could matter would be when we have trouble creating the log
-    // file.  If that happens, we'll lose lots of log messages, of course!
-    if (++rollover_attempt_ != kRolloverAttemptFrequency) return;
-    rollover_attempt_ = 0;
-
-    struct ::tm tm_time;
-    if (FLAGS_log_utc_time) {
-      gmtime_r(&timestamp, &tm_time);
-    } else {
-      localtime_r(&timestamp, &tm_time);
-    }
-
-    // The logfile's filename will have the date/time & pid in it
-    ostringstream time_pid_stream;
-    time_pid_stream.fill('0');
-    time_pid_stream << 1900+tm_time.tm_year
-                    << setw(2) << 1+tm_time.tm_mon
-                    << setw(2) << tm_time.tm_mday
-                    << '-'
-                    << setw(2) << tm_time.tm_hour
-                    << setw(2) << tm_time.tm_min
-                    << setw(2) << tm_time.tm_sec
-                    << '.'
-                    << GetMainThreadPid();
-    const string& time_pid_string = time_pid_stream.str();
-
-    if (base_filename_selected_) {
-      if (!CreateLogfile(time_pid_string)) {
-        perror("Could not create log file");
-        fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n",
-                time_pid_string.c_str());
-        return;
-      }
-    } else {
-      // If no base filename for logs of this severity has been set, use a
-      // default base filename of
-      // "<program name>.<hostname>.<user name>.log.<severity level>.".  So
-      // logfiles will have names like
-      // webserver.examplehost.root.log.INFO.19990817-150000.4354, where
-      // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00),
-      // and 4354 is the pid of the logging process.  The date & time reflect
-      // when the file was created for output.
-      //
-      // Where does the file get put?  Successively try the directories
-      // "/tmp", and "."
-      string stripped_filename(
-          glog_internal_namespace_::ProgramInvocationShortName());
-      string hostname;
-      GetHostName(&hostname);
-
-      string uidname = MyUserName();
-      // We should not call CHECK() here because this function can be
-      // called after holding on to log_mutex. We don't want to
-      // attempt to hold on to the same mutex, and get into a
-      // deadlock. Simply use a name like invalid-user.
-      if (uidname.empty()) uidname = "invalid-user";
-
-      stripped_filename = stripped_filename+'.'+hostname+'.'
-                          +uidname+".log."
-                          +LogSeverityNames[severity_]+'.';
-      // We're going to (potentially) try to put logs in several different dirs
-      const vector<string> & log_dirs = GetLoggingDirectories();
-
-      // Go through the list of dirs, and try to create the log file in each
-      // until we succeed or run out of options
-      bool success = false;
-      for (vector<string>::const_iterator dir = log_dirs.begin();
-           dir != log_dirs.end();
-           ++dir) {
-        base_filename_ = *dir + "/" + stripped_filename;
-        if ( CreateLogfile(time_pid_string) ) {
-          success = true;
-          break;
-        }
-      }
-      // If we never succeeded, we have to give up
-      if ( success == false ) {
-        perror("Could not create logging file");
-        fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!",
-                time_pid_string.c_str());
-        return;
-      }
-    }
-
-    // Write a header message into the log file
-    ostringstream file_header_stream;
-    file_header_stream.fill('0');
-    file_header_stream << "Log file created at: "
-                       << 1900+tm_time.tm_year << '/'
-                       << setw(2) << 1+tm_time.tm_mon << '/'
-                       << setw(2) << tm_time.tm_mday
-                       << ' '
-                       << setw(2) << tm_time.tm_hour << ':'
-                       << setw(2) << tm_time.tm_min << ':'
-                       << setw(2) << tm_time.tm_sec << (FLAGS_log_utc_time ? " UTC\n" : "\n")
-                       << "Running on machine: "
-                       << LogDestination::hostname() << '\n';
-
-    if(!g_application_fingerprint.empty()) {
-      file_header_stream << "Application fingerprint: " << g_application_fingerprint << '\n';
-    }
-    const char* const date_time_format = FLAGS_log_year_in_prefix
-                                             ? "yyyymmdd hh:mm:ss.uuuuuu"
-                                             : "mmdd hh:mm:ss.uuuuuu";
-    file_header_stream << "Running duration (h:mm:ss): "
-                       << PrettyDuration(static_cast<int>(WallTime_Now() - start_time_)) << '\n'
-                       << "Log line format: [IWEF]" << date_time_format << " "
-                       << "threadid file:line] msg" << '\n';
-    const string& file_header_string = file_header_stream.str();
-
-    const size_t header_len = file_header_string.size();
-    fwrite(file_header_string.data(), 1, header_len, file_);
-    file_length_ += header_len;
-    bytes_since_flush_ += header_len;
-  }
-
-  // Write to LOG file
-  if ( !stop_writing ) {
-    // fwrite() doesn't return an error when the disk is full, for
-    // messages that are less than 4096 bytes. When the disk is full,
-    // it returns the message length for messages that are less than
-    // 4096 bytes. fwrite() returns 4096 for message lengths that are
-    // greater than 4096, thereby indicating an error.
-    errno = 0;
-    fwrite(message, 1, message_len, file_);
-    if ( FLAGS_stop_logging_if_full_disk &&
-         errno == ENOSPC ) {  // disk full, stop writing to disk
-      stop_writing = true;  // until the disk is
-      return;
-    } else {
-      file_length_ += message_len;
-      bytes_since_flush_ += message_len;
-    }
-  } else {
-    if (CycleClock_Now() >= next_flush_time_) {
-      stop_writing = false;  // check to see if disk has free space.
-    }
-    return;  // no need to flush
-  }
-
-  // See important msgs *now*.  Also, flush logs at least every 10^6 chars,
-  // or every "FLAGS_logbufsecs" seconds.
-  if ( force_flush ||
-       (bytes_since_flush_ >= 1000000) ||
-       (CycleClock_Now() >= next_flush_time_) ) {
-    FlushUnlocked();
-#ifdef GLOG_OS_LINUX
-    // Only consider files >= 3MiB
-    if (FLAGS_drop_log_memory && file_length_ >= (3U << 20U)) {
-      // Don't evict the most recent 1-2MiB so as not to impact a tailer
-      // of the log file and to avoid page rounding issue on linux < 4.7
-      uint32 total_drop_length =
-          (file_length_ & ~((1U << 20U) - 1U)) - (1U << 20U);
-      uint32 this_drop_length = total_drop_length - dropped_mem_length_;
-      if (this_drop_length >= (2U << 20U)) {
-        // Only advise when >= 2MiB to drop
-# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
-        // 'posix_fadvise' introduced in API 21:
-        // * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732
-# else
-        posix_fadvise(fileno(file_), static_cast<off_t>(dropped_mem_length_),
-                      static_cast<off_t>(this_drop_length),
-                      POSIX_FADV_DONTNEED);
-# endif
-        dropped_mem_length_ = total_drop_length;
-      }
-    }
-#endif
-
-    // Remove old logs
-    if (log_cleaner.enabled()) {
-      log_cleaner.Run(base_filename_selected_,
-                      base_filename_,
-                      filename_extension_);
-    }
-  }
-}
-
-LogCleaner::LogCleaner() : enabled_(false), overdue_days_(7), next_cleanup_time_(0) {}
-
-void LogCleaner::Enable(unsigned int overdue_days) {
-  enabled_ = true;
-  overdue_days_ = overdue_days;
-}
-
-void LogCleaner::Disable() {
-  enabled_ = false;
-}
-
-void LogCleaner::UpdateCleanUpTime() {
-  const int64 next = (FLAGS_logcleansecs
-                      * 1000000);  // in usec
-  next_cleanup_time_ = CycleClock_Now() + UsecToCycles(next);
-}
-
-void LogCleaner::Run(bool base_filename_selected,
-                     const string& base_filename,
-                     const string& filename_extension) {
-  assert(enabled_);
-  assert(!base_filename_selected || !base_filename.empty());
-
-  // avoid scanning logs too frequently
-  if (CycleClock_Now() < next_cleanup_time_) {
-    return;
-  }
-  UpdateCleanUpTime();
-
-  vector<string> dirs;
-
-  if (!base_filename_selected) {
-    dirs = GetLoggingDirectories();
-  } else {
-    size_t pos = base_filename.find_last_of(possible_dir_delim, string::npos,
-                                            sizeof(possible_dir_delim));
-    if (pos != string::npos) {
-      string dir = base_filename.substr(0, pos + 1);
-      dirs.push_back(dir);
-    } else {
-      dirs.push_back(".");
-    }
-  }
-
-  for (size_t i = 0; i < dirs.size(); i++) {
-    vector<string> logs = GetOverdueLogNames(dirs[i],
-                                             overdue_days_,
-                                             base_filename,
-                                             filename_extension);
-    for (size_t j = 0; j < logs.size(); j++) {
-      static_cast<void>(unlink(logs[j].c_str()));
-    }
-  }
-}
-
-vector<string> LogCleaner::GetOverdueLogNames(
-    string log_directory, unsigned int days, const string& base_filename,
-    const string& filename_extension) const {
-  // The names of overdue logs.
-  vector<string> overdue_log_names;
-
-  // Try to get all files within log_directory.
-  DIR *dir;
-  struct dirent *ent;
-
-  if ((dir = opendir(log_directory.c_str()))) {
-    while ((ent = readdir(dir))) {
-      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
-        continue;
-      }
-
-      string filepath = ent->d_name;
-      const char* const dir_delim_end =
-          possible_dir_delim + sizeof(possible_dir_delim);
-
-      if (!log_directory.empty() &&
-          std::find(possible_dir_delim, dir_delim_end,
-                    log_directory[log_directory.size() - 1]) != dir_delim_end) {
-        filepath = log_directory + filepath;
-      }
-
-      if (IsLogFromCurrentProject(filepath, base_filename, filename_extension) &&
-          IsLogLastModifiedOver(filepath, days)) {
-        overdue_log_names.push_back(filepath);
-      }
-    }
-    closedir(dir);
-  }
-
-  return overdue_log_names;
-}
-
-bool LogCleaner::IsLogFromCurrentProject(const string& filepath,
-                                         const string& base_filename,
-                                         const string& filename_extension) const {
-  // We should remove duplicated delimiters from `base_filename`, e.g.,
-  // before: "/tmp//<base_filename>.<create_time>.<pid>"
-  // after:  "/tmp/<base_filename>.<create_time>.<pid>"
-  string cleaned_base_filename;
-
-  const char* const dir_delim_end =
-      possible_dir_delim + sizeof(possible_dir_delim);
-
-  size_t real_filepath_size = filepath.size();
-  for (size_t i = 0; i < base_filename.size(); ++i) {
-    const char& c = base_filename[i];
-
-    if (cleaned_base_filename.empty()) {
-      cleaned_base_filename += c;
-    } else if (std::find(possible_dir_delim, dir_delim_end, c) ==
-                   dir_delim_end ||
-               (!cleaned_base_filename.empty() &&
-                c != cleaned_base_filename[cleaned_base_filename.size() - 1])) {
-      cleaned_base_filename += c;
-    }
-  }
-
-  // Return early if the filename doesn't start with `cleaned_base_filename`.
-  if (filepath.find(cleaned_base_filename) != 0) {
-    return false;
-  }
-
-  // Check if in the string `filename_extension` is right next to
-  // `cleaned_base_filename` in `filepath` if the user
-  // has set a custom filename extension.
-  if (!filename_extension.empty()) {
-    if (cleaned_base_filename.size() >= real_filepath_size) {
-      return false;
-    }
-    // for origin version, `filename_extension` is middle of the `filepath`.
-    string ext = filepath.substr(cleaned_base_filename.size(), filename_extension.size());
-    if (ext == filename_extension) {
-      cleaned_base_filename += filename_extension;
-    }
-    else {
-      // for new version, `filename_extension` is right of the `filepath`.
-      if (filename_extension.size() >= real_filepath_size) {
-        return false;
-      }
-      real_filepath_size = filepath.size() - filename_extension.size();
-      if (filepath.substr(real_filepath_size) != filename_extension) {
-        return false;
-      }
-    }
-  }
-
-  // The characters after `cleaned_base_filename` should match the format:
-  // YYYYMMDD-HHMMSS.pid
-  for (size_t i = cleaned_base_filename.size(); i < real_filepath_size; i++) {
-    const char& c = filepath[i];
-
-    if (i <= cleaned_base_filename.size() + 7) { // 0 ~ 7 : YYYYMMDD
-      if (c < '0' || c > '9') { return false; }
-
-    } else if (i == cleaned_base_filename.size() + 8) { // 8: -
-      if (c != '-') { return false; }
-
-    } else if (i <= cleaned_base_filename.size() + 14) { // 9 ~ 14: HHMMSS
-      if (c < '0' || c > '9') { return false; }
-
-    } else if (i == cleaned_base_filename.size() + 15) { // 15: .
-      if (c != '.') { return false; }
-
-    } else if (i >= cleaned_base_filename.size() + 16) { // 16+: pid
-      if (c < '0' || c > '9') { return false; }
-    }
-  }
-
-  return true;
-}
-
-bool LogCleaner::IsLogLastModifiedOver(const string& filepath,
-                                       unsigned int days) const {
-  // Try to get the last modified time of this file.
-  struct stat file_stat;
-
-  if (stat(filepath.c_str(), &file_stat) == 0) {
-    const time_t seconds_in_a_day = 60 * 60 * 24;
-    time_t last_modified_time = file_stat.st_mtime;
-    time_t current_time = time(NULL);
-    return difftime(current_time, last_modified_time) > days * seconds_in_a_day;
-  }
-
-  // If failed to get file stat, don't return true!
-  return false;
-}
-
-}  // namespace
-
-// Static log data space to avoid alloc failures in a LOG(FATAL)
-//
-// Since multiple threads may call LOG(FATAL), and we want to preserve
-// the data from the first call, we allocate two sets of space.  One
-// for exclusive use by the first thread, and one for shared use by
-// all other threads.
-static Mutex fatal_msg_lock;
-static CrashReason crash_reason;
-static bool fatal_msg_exclusive = true;
-static LogMessage::LogMessageData fatal_msg_data_exclusive;
-static LogMessage::LogMessageData fatal_msg_data_shared;
-
-#ifdef GLOG_THREAD_LOCAL_STORAGE
-// Static thread-local log data space to use, because typically at most one
-// LogMessageData object exists (in this case glog makes zero heap memory
-// allocations).
-static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true;
-
-#if defined(HAVE_ALIGNED_STORAGE) && __cplusplus >= 201103L
-static GLOG_THREAD_LOCAL_STORAGE
-    std::aligned_storage<sizeof(LogMessage::LogMessageData),
-                         alignof(LogMessage::LogMessageData)>::type thread_msg_data;
-#else
-static GLOG_THREAD_LOCAL_STORAGE
-    char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)];
-#endif  // HAVE_ALIGNED_STORAGE
-#endif  // defined(GLOG_THREAD_LOCAL_STORAGE)
-
-LogMessage::LogMessageData::LogMessageData()
-  : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
-}
-
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
-                       int64 ctr, void (LogMessage::*send_method)())
-    : allocated_(NULL) {
-  Init(file, line, severity, send_method);
-  data_->stream_.set_ctr(ctr);
-}
-
-LogMessage::LogMessage(const char* file, int line,
-                       const CheckOpString& result)
-    : allocated_(NULL) {
-  Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
-  stream() << "Check failed: " << (*result.str_) << " ";
-}
-
-LogMessage::LogMessage(const char* file, int line)
-    : allocated_(NULL) {
-  Init(file, line, GLOG_INFO, &LogMessage::SendToLog);
-}
-
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
-    : allocated_(NULL) {
-  Init(file, line, severity, &LogMessage::SendToLog);
-}
-
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
-                       LogSink* sink, bool also_send_to_log)
-    : allocated_(NULL) {
-  Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
-                                                &LogMessage::SendToSink);
-  data_->sink_ = sink;  // override Init()'s setting to NULL
-}
-
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
-                       vector<string> *outvec)
-    : allocated_(NULL) {
-  Init(file, line, severity, &LogMessage::SaveOrSendToLog);
-  data_->outvec_ = outvec; // override Init()'s setting to NULL
-}
-
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
-                       string *message)
-    : allocated_(NULL) {
-  Init(file, line, severity, &LogMessage::WriteToStringAndLog);
-  data_->message_ = message;  // override Init()'s setting to NULL
-}
-
-void LogMessage::Init(const char* file,
-                      int line,
-                      LogSeverity severity,
-                      void (LogMessage::*send_method)()) {
-  allocated_ = NULL;
-  if (severity != GLOG_FATAL || !exit_on_dfatal) {
-#ifdef GLOG_THREAD_LOCAL_STORAGE
-    // No need for locking, because this is thread local.
-    if (thread_data_available) {
-      thread_data_available = false;
-#ifdef HAVE_ALIGNED_STORAGE
-      data_ = new (&thread_msg_data) LogMessageData;
-#else
-      const uintptr_t kAlign = sizeof(void*) - 1;
-
-      char* align_ptr =
-          reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign);
-      data_ = new (align_ptr) LogMessageData;
-      assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0);
-#endif
-    } else {
-      allocated_ = new LogMessageData();
-      data_ = allocated_;
-    }
-#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
-    allocated_ = new LogMessageData();
-    data_ = allocated_;
-#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
-    data_->first_fatal_ = false;
-  } else {
-    MutexLock l(&fatal_msg_lock);
-    if (fatal_msg_exclusive) {
-      fatal_msg_exclusive = false;
-      data_ = &fatal_msg_data_exclusive;
-      data_->first_fatal_ = true;
-    } else {
-      data_ = &fatal_msg_data_shared;
-      data_->first_fatal_ = false;
-    }
-    MaybeUnsetRealtime();
-  }
-
-  data_->preserved_errno_ = errno;
-  data_->severity_ = severity;
-  data_->line_ = line;
-  data_->send_method_ = send_method;
-  data_->sink_ = NULL;
-  data_->outvec_ = NULL;
-  WallTime now = WallTime_Now();
-  time_t timestamp_now = static_cast<time_t>(now);
-  logmsgtime_ = LogMessageTime(timestamp_now, now);
-
-  data_->num_chars_to_log_ = 0;
-  data_->num_chars_to_syslog_ = 0;
-  data_->basename_ = const_basename(file);
-  data_->fullname_ = file;
-  data_->has_been_flushed_ = false;
-
-  // If specified, prepend a prefix to each line.  For example:
-  //    I20201018 160715 f5d4fbb0 logging.cc:1153]
-  //    (log level, GMT year, month, date, time, thread_id, file basename, line)
-  // We exclude the thread_id for the default thread.
-  if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
-      std::ios saved_fmt(NULL);
-      saved_fmt.copyfmt(stream());
-      stream().fill('0');
-    #ifdef GLOG_CUSTOM_PREFIX_SUPPORT
-      if (custom_prefix_callback == NULL) {
-    #endif
-          stream() << LogSeverityNames[severity][0];
-          if (FLAGS_log_year_in_prefix) {
-            stream() << setw(4) << 1900 + logmsgtime_.year();
-          }
-          stream() << setw(2) << 1 + logmsgtime_.month()
-                   << setw(2) << logmsgtime_.day()
-                   << ' '
-                   << setw(2) << logmsgtime_.hour() << ':'
-                   << setw(2) << logmsgtime_.min() << ':'
-                   << setw(2) << logmsgtime_.sec() << "."
-                   << setw(6) << logmsgtime_.usec()
-                   << ' '
-                   << setfill(' ') << setw(5)
-                   << static_cast<unsigned int>(GetTID()) << setfill('0')
-                   << ' '
-                   << data_->basename_ << ':' << data_->line_ << "] ";
-    #ifdef GLOG_CUSTOM_PREFIX_SUPPORT
-      } else {
-        custom_prefix_callback(
-                stream(),
-                LogMessageInfo(LogSeverityNames[severity],
-                               data_->basename_, data_->line_, GetTID(),
-                               logmsgtime_),
-                custom_prefix_callback_data
-                );
-        stream() << " ";
-      }
-    #endif
-      stream().copyfmt(saved_fmt);
-  }
-  data_->num_prefix_chars_ = data_->stream_.pcount();
-
-  if (!FLAGS_log_backtrace_at.empty()) {
-    char fileline[128];
-    snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line);
-#ifdef HAVE_STACKTRACE
-    if (FLAGS_log_backtrace_at == fileline) {
-      string stacktrace;
-      DumpStackTraceToString(&stacktrace);
-      stream() << " (stacktrace:\n" << stacktrace << ") ";
-    }
-#endif
-  }
-}
-
-const LogMessageTime& LogMessage::getLogMessageTime() const {
-  return logmsgtime_;
-}
-
-LogMessage::~LogMessage() {
-  Flush();
-#ifdef GLOG_THREAD_LOCAL_STORAGE
-  if (data_ == static_cast<void*>(&thread_msg_data)) {
-    data_->~LogMessageData();
-    thread_data_available = true;
-  }
-  else {
-    delete allocated_;
-  }
-#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
-  delete allocated_;
-#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
-}
-
-int LogMessage::preserved_errno() const {
-  return data_->preserved_errno_;
-}
-
-ostream& LogMessage::stream() {
-  return data_->stream_;
-}
-
-// Flush buffered message, called by the destructor, or any other function
-// that needs to synchronize the log.
-void LogMessage::Flush() {
-  if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) {
-    return;
-  }
-
-  data_->num_chars_to_log_ = data_->stream_.pcount();
-  data_->num_chars_to_syslog_ =
-    data_->num_chars_to_log_ - data_->num_prefix_chars_;
-
-  // Do we need to add a \n to the end of this message?
-  bool append_newline =
-      (data_->message_text_[data_->num_chars_to_log_-1] != '\n');
-  char original_final_char = '\0';
-
-  // If we do need to add a \n, we'll do it by violating the memory of the
-  // ostrstream buffer.  This is quick, and we'll make sure to undo our
-  // modification before anything else is done with the ostrstream.  It
-  // would be preferable not to do things this way, but it seems to be
-  // the best way to deal with this.
-  if (append_newline) {
-    original_final_char = data_->message_text_[data_->num_chars_to_log_];
-    data_->message_text_[data_->num_chars_to_log_++] = '\n';
-  }
-  data_->message_text_[data_->num_chars_to_log_] = '\0';
-
-  // Prevent any subtle race conditions by wrapping a mutex lock around
-  // the actual logging action per se.
-  {
-    MutexLock l(&log_mutex);
-    (this->*(data_->send_method_))();
-    ++num_messages_[static_cast<int>(data_->severity_)];
-  }
-  LogDestination::WaitForSinks(data_);
-
-  if (append_newline) {
-    // Fix the ostrstream back how it was before we screwed with it.
-    // It's 99.44% certain that we don't need to worry about doing this.
-    data_->message_text_[data_->num_chars_to_log_-1] = original_final_char;
-  }
-
-  // If errno was already set before we enter the logging call, we'll
-  // set it back to that value when we return from the logging call.
-  // It happens often that we log an error message after a syscall
-  // failure, which can potentially set the errno to some other
-  // values.  We would like to preserve the original errno.
-  if (data_->preserved_errno_ != 0) {
-    errno = data_->preserved_errno_;
-  }
-
-  // Note that this message is now safely logged.  If we're asked to flush
-  // again, as a result of destruction, say, we'll do nothing on future calls.
-  data_->has_been_flushed_ = true;
-}
-
-// Copy of first FATAL log message so that we can print it out again
-// after all the stack traces.  To preserve legacy behavior, we don't
-// use fatal_msg_data_exclusive.
-static time_t fatal_time;
-static char fatal_message[256];
-
-void ReprintFatalMessage() {
-  if (fatal_message[0]) {
-    const size_t n = strlen(fatal_message);
-    if (!FLAGS_logtostderr) {
-      // Also write to stderr (don't color to avoid terminal checks)
-      WriteToStderr(fatal_message, n);
-    }
-    LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n);
-  }
-}
-
-// L >= log_mutex (callers must hold the log_mutex).
-void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
-  static bool already_warned_before_initgoogle = false;
-
-  log_mutex.AssertHeld();
-  if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) {
-    if (data_->first_fatal_) {
-      MaybeUnsetRealtime();
-    }
-  }
-
-  RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
-             data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
-
-  // Messages of a given severity get logged to lower severity logs, too
-
-  if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) {
-    const char w[] = "WARNING: Logging before InitGoogleLogging() is "
-                     "written to STDERR\n";
-    WriteToStderr(w, strlen(w));
-    already_warned_before_initgoogle = true;
-  }
-
-  // global flag: never log to file if set.  Also -- don't log to a
-  // file if we haven't parsed the command line flags to get the
-  // program name.
-  if (FLAGS_logtostderr || FLAGS_logtostdout || !IsGoogleLoggingInitialized()) {
-    if (FLAGS_logtostdout) {
-      ColoredWriteToStdout(data_->severity_, data_->message_text_,
-                           data_->num_chars_to_log_);
-    } else {
-      ColoredWriteToStderr(data_->severity_, data_->message_text_,
-                           data_->num_chars_to_log_);
-    }
-
-    // this could be protected by a flag if necessary.
-    LogDestination::LogToSinks(data_->severity_,
-                               data_->fullname_, data_->basename_,
-                               data_->line_, logmsgtime_,
-                               data_->message_text_ + data_->num_prefix_chars_,
-                               (data_->num_chars_to_log_ -
-                                data_->num_prefix_chars_ - 1) );
-  } else {
-    // log this message to all log files of severity <= severity_
-    LogDestination::LogToAllLogfiles(data_->severity_, logmsgtime_.timestamp(),
-                                     data_->message_text_,
-                                     data_->num_chars_to_log_);
-
-    LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_,
-                                     data_->num_chars_to_log_,
-                                     data_->num_prefix_chars_);
-    LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_,
-                                    data_->num_chars_to_log_);
-    LogDestination::LogToSinks(data_->severity_,
-                               data_->fullname_, data_->basename_,
-                               data_->line_, logmsgtime_,
-                               data_->message_text_ + data_->num_prefix_chars_,
-                               (data_->num_chars_to_log_
-                                - data_->num_prefix_chars_ - 1) );
-    // NOTE: -1 removes trailing \n
-  }
-
-  // If we log a FATAL message, flush all the log destinations, then toss
-  // a signal for others to catch. We leave the logs in a state that
-  // someone else can use them (as long as they flush afterwards)
-  if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) {
-    if (data_->first_fatal_) {
-      // Store crash information so that it is accessible from within signal
-      // handlers that may be invoked later.
-      RecordCrashReason(&crash_reason);
-      SetCrashReason(&crash_reason);
-
-      // Store shortened fatal message for other logs and GWQ status
-      const size_t copy = min(data_->num_chars_to_log_,
-                                sizeof(fatal_message)-1);
-      memcpy(fatal_message, data_->message_text_, copy);
-      fatal_message[copy] = '\0';
-      fatal_time = logmsgtime_.timestamp();
-    }
-
-    if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
-      for (int i = 0; i < NUM_SEVERITIES; ++i) {
-        if (LogDestination::log_destinations_[i]) {
-          LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0);
-        }
-      }
-    }
-
-    // release the lock that our caller (directly or indirectly)
-    // LogMessage::~LogMessage() grabbed so that signal handlers
-    // can use the logging facility. Alternately, we could add
-    // an entire unsafe logging interface to bypass locking
-    // for signal handlers but this seems simpler.
-    log_mutex.Unlock();
-    LogDestination::WaitForSinks(data_);
-
-    const char* message = "*** Check failure stack trace: ***\n";
-    if (write(STDERR_FILENO, message, strlen(message)) < 0) {
-      // Ignore errors.
-    }
-#if defined(__ANDROID__)
-    // ANDROID_LOG_FATAL as this message is of FATAL severity.
-    __android_log_write(ANDROID_LOG_FATAL,
-                        glog_internal_namespace_::ProgramInvocationShortName(),
-                        message);
-#endif
-    Fail();
-  }
-}
-
-void LogMessage::RecordCrashReason(
-    glog_internal_namespace_::CrashReason* reason) {
-  reason->filename = fatal_msg_data_exclusive.fullname_;
-  reason->line_number = fatal_msg_data_exclusive.line_;
-  reason->message = fatal_msg_data_exclusive.message_text_ +
-                    fatal_msg_data_exclusive.num_prefix_chars_;
-#ifdef HAVE_STACKTRACE
-  // Retrieve the stack trace, omitting the logging frames that got us here.
-  reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4);
-#else
-  reason->depth = 0;
-#endif
-}
-
-GLOG_EXPORT logging_fail_func_t g_logging_fail_func =
-    reinterpret_cast<logging_fail_func_t>(&abort);
-
-void InstallFailureFunction(logging_fail_func_t fail_func) {
-  g_logging_fail_func = fail_func;
-}
-
-void LogMessage::Fail() {
-  g_logging_fail_func();
-}
-
-// L >= log_mutex (callers must hold the log_mutex).
-void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
-  if (data_->sink_ != NULL) {
-    RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
-               data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
-    data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
-                       data_->line_, logmsgtime_,
-                       data_->message_text_ + data_->num_prefix_chars_,
-                       (data_->num_chars_to_log_ -
-                        data_->num_prefix_chars_ - 1) );
-  }
-}
-
-// L >= log_mutex (callers must hold the log_mutex).
-void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
-  SendToSink();
-  SendToLog();
-}
-
-// L >= log_mutex (callers must hold the log_mutex).
-void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
-  if (data_->outvec_ != NULL) {
-    RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
-               data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
-    // Omit prefix of message and trailing newline when recording in outvec_.
-    const char *start = data_->message_text_ + data_->num_prefix_chars_;
-    size_t len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
-    data_->outvec_->push_back(string(start, len));
-  } else {
-    SendToLog();
-  }
-}
-
-void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
-  if (data_->message_ != NULL) {
-    RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
-               data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
-    // Omit prefix of message and trailing newline when writing to message_.
-    const char *start = data_->message_text_ + data_->num_prefix_chars_;
-    size_t len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
-    data_->message_->assign(start, len);
-  }
-  SendToLog();
-}
-
-// L >= log_mutex (callers must hold the log_mutex).
-void LogMessage::SendToSyslogAndLog() {
-#ifdef HAVE_SYSLOG_H
-  // Before any calls to syslog(), make a single call to openlog()
-  static bool openlog_already_called = false;
-  if (!openlog_already_called) {
-    openlog(glog_internal_namespace_::ProgramInvocationShortName(),
-            LOG_CONS | LOG_NDELAY | LOG_PID,
-            LOG_USER);
-    openlog_already_called = true;
-  }
-
-  // This array maps Google severity levels to syslog levels
-  const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
-  syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s",
-         int(data_->num_chars_to_syslog_),
-         data_->message_text_ + data_->num_prefix_chars_);
-  SendToLog();
-#else
-  LOG(ERROR) << "No syslog support: message=" << data_->message_text_;
-#endif
-}
-
-base::Logger* base::GetLogger(LogSeverity severity) {
-  MutexLock l(&log_mutex);
-  return LogDestination::log_destination(severity)->logger_;
-}
-
-void base::SetLogger(LogSeverity severity, base::Logger* logger) {
-  MutexLock l(&log_mutex);
-  LogDestination::log_destination(severity)->logger_ = logger;
-}
-
-// L < log_mutex.  Acquires and releases mutex_.
-int64 LogMessage::num_messages(int severity) {
-  MutexLock l(&log_mutex);
-  return num_messages_[severity];
-}
-
-// Output the COUNTER value. This is only valid if ostream is a
-// LogStream.
-ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
-#ifdef DISABLE_RTTI
-  LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
-#else
-  LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os);
-#endif
-  CHECK(log && log == log->self())
-      << "You must not use COUNTER with non-glog ostream";
-  os << log->ctr();
-  return os;
-}
-
-ErrnoLogMessage::ErrnoLogMessage(const char* file, int line,
-                                 LogSeverity severity, int64 ctr,
-                                 void (LogMessage::*send_method)())
-    : LogMessage(file, line, severity, ctr, send_method) {}
-
-ErrnoLogMessage::~ErrnoLogMessage() {
-  // Don't access errno directly because it may have been altered
-  // while streaming the message.
-  stream() << ": " << StrError(preserved_errno()) << " ["
-           << preserved_errno() << "]";
-}
-
-void FlushLogFiles(LogSeverity min_severity) {
-  LogDestination::FlushLogFiles(min_severity);
-}
-
-void FlushLogFilesUnsafe(LogSeverity min_severity) {
-  LogDestination::FlushLogFilesUnsafe(min_severity);
-}
-
-void SetLogDestination(LogSeverity severity, const char* base_filename) {
-  LogDestination::SetLogDestination(severity, base_filename);
-}
-
-void SetLogSymlink(LogSeverity severity, const char* symlink_basename) {
-  LogDestination::SetLogSymlink(severity, symlink_basename);
-}
-
-LogSink::~LogSink() {
-}
-
-void LogSink::send(LogSeverity severity, const char* full_filename,
-                   const char* base_filename, int line,
-                   const LogMessageTime& time, const char* message,
-                   size_t message_len) {
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#elif defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4996)
-#endif  // __GNUC__
-  send(severity, full_filename, base_filename, line, &time.tm(), message,
-       message_len);
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-#pragma warning(pop)
-#endif  // __GNUC__
-}
-
-void LogSink::send(LogSeverity severity, const char* full_filename,
-                   const char* base_filename, int line, const std::tm* t,
-                   const char* message, size_t message_len) {
-  (void)severity;
-  (void)full_filename;
-  (void)base_filename;
-  (void)line;
-  (void)t;
-  (void)message;
-  (void)message_len;
-}
-
-void LogSink::WaitTillSent() {
-  // noop default
-}
-
-string LogSink::ToString(LogSeverity severity, const char* file, int line,
-                         const LogMessageTime& logmsgtime, const char* message,
-                         size_t message_len) {
-  ostringstream stream(string(message, message_len));
-  stream.fill('0');
-
-  stream << LogSeverityNames[severity][0]
-         << setw(4) << 1900 + logmsgtime.year()
-         << setw(2) << 1 + logmsgtime.month()
-         << setw(2) << logmsgtime.day()
-         << ' '
-         << setw(2) << logmsgtime.hour() << ':'
-         << setw(2) << logmsgtime.min() << ':'
-         << setw(2) << logmsgtime.sec() << '.'
-         << setw(6) << logmsgtime.usec()
-         << ' '
-         << setfill(' ') << setw(5) << GetTID() << setfill('0')
-         << ' '
-         << file << ':' << line << "] ";
-
-  stream << string(message, message_len);
-  return stream.str();
-}
-
-void AddLogSink(LogSink *destination) {
-  LogDestination::AddLogSink(destination);
-}
-
-void RemoveLogSink(LogSink *destination) {
-  LogDestination::RemoveLogSink(destination);
-}
-
-void SetLogFilenameExtension(const char* ext) {
-  LogDestination::SetLogFilenameExtension(ext);
-}
-
-void SetStderrLogging(LogSeverity min_severity) {
-  LogDestination::SetStderrLogging(min_severity);
-}
-
-void SetEmailLogging(LogSeverity min_severity, const char* addresses) {
-  LogDestination::SetEmailLogging(min_severity, addresses);
-}
-
-void LogToStderr() {
-  LogDestination::LogToStderr();
-}
-
-namespace base {
-namespace internal {
-
-bool GetExitOnDFatal();
-bool GetExitOnDFatal() {
-  MutexLock l(&log_mutex);
-  return exit_on_dfatal;
-}
-
-// Determines whether we exit the program for a LOG(DFATAL) message in
-// debug mode.  It does this by skipping the call to Fail/FailQuietly.
-// This is intended for testing only.
-//
-// This can have some effects on LOG(FATAL) as well.  Failure messages
-// are always allocated (rather than sharing a buffer), the crash
-// reason is not recorded, the "gwq" status message is not updated,
-// and the stack trace is not recorded.  The LOG(FATAL) *will* still
-// exit the program.  Since this function is used only in testing,
-// these differences are acceptable.
-void SetExitOnDFatal(bool value);
-void SetExitOnDFatal(bool value) {
-  MutexLock l(&log_mutex);
-  exit_on_dfatal = value;
-}
-
-}  // namespace internal
-}  // namespace base
-
-#ifndef GLOG_OS_EMSCRIPTEN
-// Shell-escaping as we need to shell out ot /bin/mail.
-static const char kDontNeedShellEscapeChars[] =
-            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-            "abcdefghijklmnopqrstuvwxyz"
-            "0123456789+-_.=/:,@";
-
-static string ShellEscape(const string& src) {
-  string result;
-  if (!src.empty() &&  // empty string needs quotes
-      src.find_first_not_of(kDontNeedShellEscapeChars) == string::npos) {
-    // only contains chars that don't need quotes; it's fine
-    result.assign(src);
-  } else if (src.find_first_of('\'') == string::npos) {
-    // no single quotes; just wrap it in single quotes
-    result.assign("'");
-    result.append(src);
-    result.append("'");
-  } else {
-    // needs double quote escaping
-    result.assign("\"");
-    for (size_t i = 0; i < src.size(); ++i) {
-      switch (src[i]) {
-        case '\\':
-        case '$':
-        case '"':
-        case '`':
-          result.append("\\");
-      }
-      result.append(src, i, 1);
-    }
-    result.append("\"");
-  }
-  return result;
-}
-#endif
-
-// use_logging controls whether the logging functions LOG/VLOG are used
-// to log errors.  It should be set to false when the caller holds the
-// log_mutex.
-static bool SendEmailInternal(const char*dest, const char *subject,
-                              const char*body, bool use_logging) {
-#ifndef GLOG_OS_EMSCRIPTEN
-  if (dest && *dest) {
-    if ( use_logging ) {
-      VLOG(1) << "Trying to send TITLE:" << subject
-              << " BODY:" << body << " to " << dest;
-    } else {
-      fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n",
-              subject, body, dest);
-    }
-
-    string logmailer = FLAGS_logmailer;
-    if (logmailer.empty()) {
-        logmailer = "/bin/mail";
-    }
-    string cmd =
-        logmailer + " -s" +
-        ShellEscape(subject) + " " + ShellEscape(dest);
-    if (use_logging) {
-        VLOG(4) << "Mailing command: " << cmd;
-    }
-
-    FILE* pipe = popen(cmd.c_str(), "w");
-    if (pipe != NULL) {
-      // Add the body if we have one
-      if (body) {
-        fwrite(body, sizeof(char), strlen(body), pipe);
-      }
-      bool ok = pclose(pipe) != -1;
-      if ( !ok ) {
-        if ( use_logging ) {
-          LOG(ERROR) << "Problems sending mail to " << dest << ": "
-                     << StrError(errno);
-        } else {
-          fprintf(stderr, "Problems sending mail to %s: %s\n",
-                  dest, StrError(errno).c_str());
-        }
-      }
-      return ok;
-    } else {
-      if ( use_logging ) {
-        LOG(ERROR) << "Unable to send mail to " << dest;
-      } else {
-        fprintf(stderr, "Unable to send mail to %s\n", dest);
-      }
-    }
-  }
-#else
-  (void)dest;
-  (void)subject;
-  (void)body;
-  (void)use_logging;
-  LOG(WARNING) << "Email support not available; not sending message";
-#endif
-  return false;
-}
-
-bool SendEmail(const char*dest, const char *subject, const char*body){
-  return SendEmailInternal(dest, subject, body, true);
-}
-
-static void GetTempDirectories(vector<string>* list) {
-  list->clear();
-#ifdef GLOG_OS_WINDOWS
-  // On windows we'll try to find a directory in this order:
-  //   C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is)
-  //   C:/TMP/
-  //   C:/TEMP/
-  //   C:/WINDOWS/ or C:/WINNT/
-  //   .
-  char tmp[MAX_PATH];
-  if (GetTempPathA(MAX_PATH, tmp))
-    list->push_back(tmp);
-  list->push_back("C:\\tmp\\");
-  list->push_back("C:\\temp\\");
-#else
-  // Directories, in order of preference. If we find a dir that
-  // exists, we stop adding other less-preferred dirs
-  const char * candidates[] = {
-    // Non-null only during unittest/regtest
-    getenv("TEST_TMPDIR"),
-
-    // Explicitly-supplied temp dirs
-    getenv("TMPDIR"), getenv("TMP"),
-
-    // If all else fails
-    "/tmp",
-  };
-
-  for (size_t i = 0; i < ARRAYSIZE(candidates); i++) {
-    const char *d = candidates[i];
-    if (!d) continue;  // Empty env var
-
-    // Make sure we don't surprise anyone who's expecting a '/'
-    string dstr = d;
-    if (dstr[dstr.size() - 1] != '/') {
-      dstr += "/";
-    }
-    list->push_back(dstr);
-
-    struct stat statbuf;
-    if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) {
-      // We found a dir that exists - we're done.
-      return;
-    }
-  }
-
-#endif
-}
-
-static vector<string>* logging_directories_list;
-
-const vector<string>& GetLoggingDirectories() {
-  // Not strictly thread-safe but we're called early in InitGoogle().
-  if (logging_directories_list == NULL) {
-    logging_directories_list = new vector<string>;
-
-    if ( !FLAGS_log_dir.empty() ) {
-      // A dir was specified, we should use it
-      logging_directories_list->push_back(FLAGS_log_dir);
-    } else {
-      GetTempDirectories(logging_directories_list);
-#ifdef GLOG_OS_WINDOWS
-      char tmp[MAX_PATH];
-      if (GetWindowsDirectoryA(tmp, MAX_PATH))
-        logging_directories_list->push_back(tmp);
-      logging_directories_list->push_back(".\\");
-#else
-      logging_directories_list->push_back("./");
-#endif
-    }
-  }
-  return *logging_directories_list;
-}
-
-void TestOnly_ClearLoggingDirectoriesList() {
-  fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
-          "called from test code.\n");
-  delete logging_directories_list;
-  logging_directories_list = NULL;
-}
-
-void GetExistingTempDirectories(vector<string>* list) {
-  GetTempDirectories(list);
-  vector<string>::iterator i_dir = list->begin();
-  while( i_dir != list->end() ) {
-    // zero arg to access means test for existence; no constant
-    // defined on windows
-    if ( access(i_dir->c_str(), 0) ) {
-      i_dir = list->erase(i_dir);
-    } else {
-      ++i_dir;
-    }
-  }
-}
-
-void TruncateLogFile(const char *path, uint64 limit, uint64 keep) {
-#ifdef HAVE_UNISTD_H
-  struct stat statbuf;
-  const int kCopyBlockSize = 8 << 10;
-  char copybuf[kCopyBlockSize];
-  off_t read_offset, write_offset;
-  // Don't follow symlinks unless they're our own fd symlinks in /proc
-  int flags = O_RDWR;
-  // TODO(hamaji): Support other environments.
-#ifdef GLOG_OS_LINUX
-  const char *procfd_prefix = "/proc/self/fd/";
-  if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW;
-#endif
-
-  int fd = open(path, flags);
-  if (fd == -1) {
-    if (errno == EFBIG) {
-      // The log file in question has got too big for us to open. The
-      // real fix for this would be to compile logging.cc (or probably
-      // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's
-      // rather scary.
-      // Instead just truncate the file to something we can manage
-      if (truncate(path, 0) == -1) {
-        PLOG(ERROR) << "Unable to truncate " << path;
-      } else {
-        LOG(ERROR) << "Truncated " << path << " due to EFBIG error";
-      }
-    } else {
-      PLOG(ERROR) << "Unable to open " << path;
-    }
-    return;
-  }
-
-  if (fstat(fd, &statbuf) == -1) {
-    PLOG(ERROR) << "Unable to fstat()";
-    goto out_close_fd;
-  }
-
-  // See if the path refers to a regular file bigger than the
-  // specified limit
-  if (!S_ISREG(statbuf.st_mode)) goto out_close_fd;
-  if (statbuf.st_size <= static_cast<off_t>(limit))  goto out_close_fd;
-  if (statbuf.st_size <= static_cast<off_t>(keep)) goto out_close_fd;
-
-  // This log file is too large - we need to truncate it
-  LOG(INFO) << "Truncating " << path << " to " << keep << " bytes";
-
-  // Copy the last "keep" bytes of the file to the beginning of the file
-  read_offset = statbuf.st_size - static_cast<off_t>(keep);
-  write_offset = 0;
-  ssize_t bytesin, bytesout;
-  while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) {
-    bytesout = pwrite(fd, copybuf, static_cast<size_t>(bytesin), write_offset);
-    if (bytesout == -1) {
-      PLOG(ERROR) << "Unable to write to " << path;
-      break;
-    } else if (bytesout != bytesin) {
-      LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout;
-    }
-    read_offset += bytesin;
-    write_offset += bytesout;
-  }
-  if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path;
-
-  // Truncate the remainder of the file. If someone else writes to the
-  // end of the file after our last read() above, we lose their latest
-  // data. Too bad ...
-  if (ftruncate(fd, write_offset) == -1) {
-    PLOG(ERROR) << "Unable to truncate " << path;
-  }
-
- out_close_fd:
-  close(fd);
-#else
-  LOG(ERROR) << "No log truncation support.";
-  (void)path;
-  (void)limit;
-  (void)keep;
-#endif
- }
-
-void TruncateStdoutStderr() {
-#ifdef HAVE_UNISTD_H
-  uint64 limit = MaxLogSize() << 20U;
-  uint64 keep = 1U << 20U;
-  TruncateLogFile("/proc/self/fd/1", limit, keep);
-  TruncateLogFile("/proc/self/fd/2", limit, keep);
-#else
-  LOG(ERROR) << "No log truncation support.";
-#endif
-}
-
-
-// Helper functions for string comparisons.
-#define DEFINE_CHECK_STROP_IMPL(name, func, expected)                   \
-  string* Check##func##expected##Impl(const char* s1, const char* s2,   \
-                                      const char* names) {              \
-    bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2));               \
-    if (equal == expected) return NULL;                                 \
-    else {                                                              \
-      ostringstream ss;                                                 \
-      if (!s1) s1 = "";                                                 \
-      if (!s2) s2 = "";                                                 \
-      ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
-      return new string(ss.str());                                      \
-    }                                                                   \
-  }
-DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
-DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
-DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
-DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
-#undef DEFINE_CHECK_STROP_IMPL
-
-int posix_strerror_r(int err, char *buf, size_t len) {
-  // Sanity check input parameters
-  if (buf == NULL || len <= 0) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  // Reset buf and errno, and try calling whatever version of strerror_r()
-  // is implemented by glibc
-  buf[0] = '\000';
-  int old_errno = errno;
-  errno = 0;
-  char *rc = reinterpret_cast<char *>(strerror_r(err, buf, len));
-
-  // Both versions set errno on failure
-  if (errno) {
-    // Should already be there, but better safe than sorry
-    buf[0]     = '\000';
-    return -1;
-  }
-  errno = old_errno;
-
-  // POSIX is vague about whether the string will be terminated, although
-  // is indirectly implies that typically ERANGE will be returned, instead
-  // of truncating the string. This is different from the GNU implementation.
-  // We play it safe by always terminating the string explicitly.
-  buf[len-1] = '\000';
-
-  // If the function succeeded, we can use its exit code to determine the
-  // semantics implemented by glibc
-  if (!rc) {
-    return 0;
-  } else {
-    // GNU semantics detected
-    if (rc == buf) {
-      return 0;
-    } else {
-      buf[0] = '\000';
-#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
-      if (reinterpret_cast<intptr_t>(rc) < sys_nerr) {
-        // This means an error on MacOSX or FreeBSD.
-        return -1;
-      }
-#endif
-      strncat(buf, rc, len-1);
-      return 0;
-    }
-  }
-}
-
-string StrError(int err) {
-  char buf[100];
-  int rc = posix_strerror_r(err, buf, sizeof(buf));
-  if ((rc < 0) || (buf[0] == '\000')) {
-    snprintf(buf, sizeof(buf), "Error number %d", err);
-  }
-  return buf;
-}
-
-LogMessageFatal::LogMessageFatal(const char *file, int line)
-    : LogMessage(file, line, GLOG_FATAL) {
-  MaybeUnsetRealtime();
-}
-
-LogMessageFatal::LogMessageFatal(const char* file, int line,
-                                 const CheckOpString& result) :
-    LogMessage(file, line, result) {}
-
-LogMessageFatal::~LogMessageFatal() {
-    Flush();
-    LogMessage::Fail();
-}
-
-namespace base {
-
-static ostringstream* MakeSafeOstream() {
-  MaybeUnsetRealtime();
-  return new ostringstream;
-}
-
-CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext)
-    : stream_(MakeSafeOstream()) {
-  *stream_ << exprtext << " (";
-}
-
-CheckOpMessageBuilder::~CheckOpMessageBuilder() {
-  delete stream_;
-}
-
-ostream* CheckOpMessageBuilder::ForVar2() {
-  *stream_ << " vs. ";
-  return stream_;
-}
-
-string* CheckOpMessageBuilder::NewString() {
-  *stream_ << ")";
-  return new string(stream_->str());
-}
-
-}  // namespace base
-
-template <>
-void MakeCheckOpValueString(std::ostream* os, const char& v) {
-  if (v >= 32 && v <= 126) {
-    (*os) << "'" << v << "'";
-  } else {
-    (*os) << "char value " << static_cast<short>(v);
-  }
-}
-
-template <>
-void MakeCheckOpValueString(std::ostream* os, const signed char& v) {
-  if (v >= 32 && v <= 126) {
-    (*os) << "'" << v << "'";
-  } else {
-    (*os) << "signed char value " << static_cast<short>(v);
-  }
-}
-
-template <>
-void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) {
-  if (v >= 32 && v <= 126) {
-    (*os) << "'" << v << "'";
-  } else {
-    (*os) << "unsigned char value " << static_cast<unsigned short>(v);
-  }
-}
-
-#if defined(HAVE_CXX11_NULLPTR_T) && __cplusplus >= 201103L
-template <>
-void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
-  (*os) << "nullptr";
-}
-#endif // defined(HAVE_CXX11_NULLPTR_T)
-
-void InitGoogleLogging(const char* argv0) {
-  glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
-}
-
-#ifdef GLOG_CUSTOM_PREFIX_SUPPORT
-void InitGoogleLogging(const char* argv0,
-                       CustomPrefixCallback prefix_callback,
-                       void* prefix_callback_data) {
-  custom_prefix_callback = prefix_callback;
-  custom_prefix_callback_data = prefix_callback_data;
-  InitGoogleLogging(argv0);
-}
-#endif
-
-void ShutdownGoogleLogging() {
-  glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
-  LogDestination::DeleteLogDestinations();
-  delete logging_directories_list;
-  logging_directories_list = NULL;
-}
-
-void EnableLogCleaner(unsigned int overdue_days) {
-  log_cleaner.Enable(overdue_days);
-}
-
-void DisableLogCleaner() {
-  log_cleaner.Disable();
-}
-
-LogMessageTime::LogMessageTime()
-    : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
-
-LogMessageTime::LogMessageTime(std::tm t) {
-  std::time_t timestamp = std::mktime(&t);
-  init(t, timestamp, 0);
-}
-
-LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
-  std::tm t;
-  if (FLAGS_log_utc_time)
-    gmtime_r(&timestamp, &t);
-  else
-    localtime_r(&timestamp, &t);
-  init(t, timestamp, now);
-}
-
-void LogMessageTime::init(const std::tm& t, std::time_t timestamp,
-                          WallTime now) {
-  time_struct_ = t;
-  timestamp_ = timestamp;
-  usecs_ = static_cast<int32>((now - timestamp) * 1000000);
-
-  CalcGmtOffset();
-}
-
-void LogMessageTime::CalcGmtOffset() {
-  std::tm gmt_struct;
-  int isDst = 0;
-  if ( FLAGS_log_utc_time ) {
-    localtime_r(&timestamp_, &gmt_struct);
-    isDst = gmt_struct.tm_isdst;
-    gmt_struct = time_struct_;
-  } else {
-    isDst = time_struct_.tm_isdst;
-    gmtime_r(&timestamp_, &gmt_struct);
-  }
-
-  time_t gmt_sec = mktime(&gmt_struct);
-  const long hour_secs = 3600;
-  // If the Daylight Saving Time(isDst) is active subtract an hour from the current timestamp.
-  gmtoffset_ = static_cast<long int>(timestamp_ - gmt_sec + (isDst ? hour_secs : 0) ) ;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/logging_custom_prefix_unittest.cc b/third_party/google-glog/src/logging_custom_prefix_unittest.cc
deleted file mode 100644
index 615dce7..0000000
--- a/third_party/google-glog/src/logging_custom_prefix_unittest.cc
+++ /dev/null
@@ -1,1384 +0,0 @@
-// Copyright (c) 2002, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Ray Sidney
-
-#include "utilities.h"
-
-#include <fcntl.h>
-#ifdef HAVE_GLOB_H
-# include <glob.h>
-#endif
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#include <cstdio>
-#include <cstdlib>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-#include <memory>
-#include <queue>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "base/commandlineflags.h"
-#include <glog/logging.h>
-#include <glog/raw_logging.h>
-#include "googletest.h"
-
-DECLARE_string(log_backtrace_at);  // logging.cc
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-#ifdef HAVE_LIB_GMOCK
-#include <gmock/gmock.h>
-#include "mock-log.h"
-// Introduce several symbols from gmock.
-using testing::_;
-using testing::AnyNumber;
-using testing::HasSubstr;
-using testing::AllOf;
-using testing::StrNe;
-using testing::StrictMock;
-using testing::InitGoogleMock;
-using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
-#endif
-
-using namespace std;
-using namespace GOOGLE_NAMESPACE;
-
-// Some non-advertised functions that we want to test or use.
-_START_GOOGLE_NAMESPACE_
-namespace base {
-namespace internal {
-bool GetExitOnDFatal();
-void SetExitOnDFatal(bool value);
-}  // namespace internal
-}  // namespace base
-_END_GOOGLE_NAMESPACE_
-
-static void TestLogging(bool check_counts);
-static void TestRawLogging();
-static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
-static void TestLoggingLevels();
-static void TestLogString();
-static void TestLogSink();
-static void TestLogToString();
-static void TestLogSinkWaitTillSent();
-static void TestCHECK();
-static void TestDCHECK();
-static void TestSTREQ();
-static void TestBasename();
-static void TestBasenameAppendWhenNoTimestamp();
-static void TestTwoProcessesWrite();
-static void TestSymlink();
-static void TestExtension();
-static void TestWrapper();
-static void TestErrno();
-static void TestTruncate();
-static void TestCustomLoggerDeletionOnShutdown();
-
-static int x = -1;
-static void BM_Check1(int n) {
-  while (n-- > 0) {
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-  }
-}
-BENCHMARK(BM_Check1)
-
-static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
-static void BM_Check3(int n) {
-  while (n-- > 0) {
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-  }
-}
-BENCHMARK(BM_Check3)
-
-static void BM_Check2(int n) {
-  if (n == 17) {
-    x = 5;
-  }
-  while (n-- > 0) {
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-  }
-}
-BENCHMARK(BM_Check2)
-
-static void CheckFailure(int, int, const char* /* file */, int /* line */,
-                         const char* /* msg */) {
-}
-
-static void BM_logspeed(int n) {
-  while (n-- > 0) {
-    LOG(INFO) << "test message";
-  }
-}
-BENCHMARK(BM_logspeed)
-
-static void BM_vlog(int n) {
-  while (n-- > 0) {
-    VLOG(1) << "test message";
-  }
-}
-BENCHMARK(BM_vlog)
-
-// Dynamically generate a prefix using the default format and write it to the stream.
-void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) {
-  // Assert that `data` contains the expected contents before producing the
-  // prefix (otherwise causing the tests to fail):
-  if (data == NULL || *static_cast<string*>(data) != "good data") {
-    return;
-  }
-
-  s << l.severity[0]
-    << setw(4) << 1900 + l.time.year()
-    << setw(2) << 1 + l.time.month()
-    << setw(2) << l.time.day()
-    << ' '
-    << setw(2) << l.time.hour() << ':'
-    << setw(2) << l.time.min()  << ':'
-    << setw(2) << l.time.sec() << "."
-    << setw(6) << l.time.usec()
-    << ' '
-    << setfill(' ') << setw(5)
-    << l.thread_id << setfill('0')
-    << ' '
-    << l.filename << ':' << l.line_number << "]";
-}
-
-int main(int argc, char **argv) {
-  FLAGS_colorlogtostderr = false;
-  FLAGS_timestamp_in_logfile_name = true;
-
-  // Make sure stderr is not buffered as stderr seems to be buffered
-  // on recent windows.
-  setbuf(stderr, NULL);
-
-  // Test some basics before InitGoogleLogging:
-  CaptureTestStderr();
-  LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
-                FLAGS_logtostderr, FLAGS_alsologtostderr);
-  LogWithLevels(0, 0, 0, 0);  // simulate "before global c-tors"
-  const string early_stderr = GetCapturedTestStderr();
-
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-
-  // Setting a custom prefix generator (it will use the default format so that
-  // the golden outputs can be reused):
-  string prefix_attacher_data = "good data";
-  InitGoogleLogging(argv[0], &PrefixAttacher, static_cast<void*>(&prefix_attacher_data));
-
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-
-  RunSpecifiedBenchmarks();
-
-  FLAGS_logtostderr = true;
-
-  InitGoogleTest(&argc, argv);
-#ifdef HAVE_LIB_GMOCK
-  InitGoogleMock(&argc, argv);
-#endif
-
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-
-  // so that death tests run before we use threads
-  CHECK_EQ(RUN_ALL_TESTS(), 0);
-
-  CaptureTestStderr();
-
-  // re-emit early_stderr
-  LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
-
-  TestLogging(true);
-  TestRawLogging();
-  TestLoggingLevels();
-  TestLogString();
-  TestLogSink();
-  TestLogToString();
-  TestLogSinkWaitTillSent();
-  TestCHECK();
-  TestDCHECK();
-  TestSTREQ();
-
-  // TODO: The golden test portion of this test is very flakey.
-  EXPECT_TRUE(
-      MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_custom_prefix_unittest.err"));
-
-  FLAGS_logtostderr = false;
-
-  TestBasename();
-  TestBasenameAppendWhenNoTimestamp();
-  TestTwoProcessesWrite();
-  TestSymlink();
-  TestExtension();
-  TestWrapper();
-  TestErrno();
-  TestTruncate();
-  TestCustomLoggerDeletionOnShutdown();
-
-  fprintf(stdout, "PASS\n");
-  return 0;
-}
-
-void TestLogging(bool check_counts) {
-  int64 base_num_infos   = LogMessage::num_messages(GLOG_INFO);
-  int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
-  int64 base_num_errors  = LogMessage::num_messages(GLOG_ERROR);
-
-  LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
-  for ( int i = 0; i < 10; ++i ) {
-    int old_errno = errno;
-    errno = i;
-    PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
-    errno = old_errno;
-
-    LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
-    LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
-
-    LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
-    LOG_IF_EVERY_N(WARNING, false, 3)
-        << "Log if every 3, iteration " << COUNTER;
-    LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
-    LOG_IF_EVERY_N(ERROR, (i < 3), 2)
-        << "Log if less than 3 every 2, iteration " << COUNTER;
-  }
-  LOG_IF(WARNING, true) << "log_if this";
-  LOG_IF(WARNING, false) << "don't log_if this";
-
-  char s[] = "array";
-  LOG(INFO) << s;
-  const char const_s[] = "const array";
-  LOG(INFO) << const_s;
-  int j = 1000;
-  LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
-             << setw(1) << hex << j;
-  LOG(INFO) << "foo " << std::setw(10) << 1.0;
-
-  {
-    google::LogMessage outer(__FILE__, __LINE__, GLOG_ERROR);
-    outer.stream() << "outer";
-
-    LOG(ERROR) << "inner";
-  }
-
-  LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
-
-  if (check_counts) {
-    CHECK_EQ(base_num_infos   + 15, LogMessage::num_messages(GLOG_INFO));
-    CHECK_EQ(base_num_warning + 3,  LogMessage::num_messages(GLOG_WARNING));
-    CHECK_EQ(base_num_errors  + 17, LogMessage::num_messages(GLOG_ERROR));
-  }
-}
-
-static void NoAllocNewHook() {
-  LOG(FATAL) << "unexpected new";
-}
-
-struct NewHook {
-  NewHook() {
-    g_new_hook = &NoAllocNewHook;
-  }
-  ~NewHook() {
-    g_new_hook = NULL;
-  }
-};
-
-TEST(DeathNoAllocNewHook, logging) {
-  // tests that NewHook used below works
-  NewHook new_hook;
-  ASSERT_DEATH({
-    new int;
-  }, "unexpected new");
-}
-
-void TestRawLogging() {
-  string* foo = new string("foo ");
-  string huge_str(50000, 'a');
-
-  FlagSaver saver;
-
-  // Check that RAW loggging does not use mallocs.
-  NewHook new_hook;
-
-  RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
-  char s[] = "array";
-  RAW_LOG(WARNING, "%s", s);
-  const char const_s[] = "const array";
-  RAW_LOG(INFO, "%s", const_s);
-  void* p = reinterpret_cast<void*>(PTR_TEST_VALUE);
-  RAW_LOG(INFO, "ptr %p", p);
-  p = NULL;
-  RAW_LOG(INFO, "ptr %p", p);
-  int j = 1000;
-  RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
-  RAW_VLOG(0, "foo %d", j);
-
-#if defined(NDEBUG)
-  RAW_LOG(INFO, "foo %d", j);  // so that have same stderr to compare
-#else
-  RAW_DLOG(INFO, "foo %d", j);  // test RAW_DLOG in debug mode
-#endif
-
-  // test how long messages are chopped:
-  RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
-  RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
-
-  FLAGS_v = 0;
-  RAW_LOG(INFO, "log");
-  RAW_VLOG(0, "vlog 0 on");
-  RAW_VLOG(1, "vlog 1 off");
-  RAW_VLOG(2, "vlog 2 off");
-  RAW_VLOG(3, "vlog 3 off");
-  FLAGS_v = 2;
-  RAW_LOG(INFO, "log");
-  RAW_VLOG(1, "vlog 1 on");
-  RAW_VLOG(2, "vlog 2 on");
-  RAW_VLOG(3, "vlog 3 off");
-
-#if defined(NDEBUG)
-  RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
-#endif
-
-  RAW_CHECK(1 == 1, "should be ok");
-  RAW_DCHECK(true, "should be ok");
-
-  delete foo;
-}
-
-void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
-  RAW_LOG(INFO,
-          "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
-          v, severity, err, alsoerr);
-
-  FlagSaver saver;
-
-  FLAGS_v = v;
-  FLAGS_stderrthreshold = severity;
-  FLAGS_logtostderr = err;
-  FLAGS_alsologtostderr = alsoerr;
-
-  RAW_VLOG(-1, "vlog -1");
-  RAW_VLOG(0, "vlog 0");
-  RAW_VLOG(1, "vlog 1");
-  RAW_LOG(INFO, "log info");
-  RAW_LOG(WARNING, "log warning");
-  RAW_LOG(ERROR, "log error");
-
-  VLOG(-1) << "vlog -1";
-  VLOG(0) << "vlog 0";
-  VLOG(1) << "vlog 1";
-  LOG(INFO) << "log info";
-  LOG(WARNING) << "log warning";
-  LOG(ERROR) << "log error";
-
-  VLOG_IF(-1, true) << "vlog_if -1";
-  VLOG_IF(-1, false) << "don't vlog_if -1";
-  VLOG_IF(0, true) << "vlog_if 0";
-  VLOG_IF(0, false) << "don't vlog_if 0";
-  VLOG_IF(1, true) << "vlog_if 1";
-  VLOG_IF(1, false) << "don't vlog_if 1";
-  LOG_IF(INFO, true) << "log_if info";
-  LOG_IF(INFO, false) << "don't log_if info";
-  LOG_IF(WARNING, true) << "log_if warning";
-  LOG_IF(WARNING, false) << "don't log_if warning";
-  LOG_IF(ERROR, true) << "log_if error";
-  LOG_IF(ERROR, false) << "don't log_if error";
-
-  int c;
-  c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
-  c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
-  c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
-  c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
-  c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
-  c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
-
-  c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
-  EXPECT_EQ(c, -1);
-  c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
-  EXPECT_EQ(c, -1);
-  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
-  EXPECT_EQ(c, 0);
-  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
-  EXPECT_EQ(c, 0);
-  c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
-  EXPECT_EQ(c, 1);
-  c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
-  EXPECT_EQ(c, 1);
-  c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
-  EXPECT_EQ(c, 0);
-  c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
-  EXPECT_EQ(c, 0);
-}
-
-void TestLoggingLevels() {
-  LogWithLevels(0, GLOG_INFO, false, false);
-  LogWithLevels(1, GLOG_INFO, false, false);
-  LogWithLevels(-1, GLOG_INFO, false, false);
-  LogWithLevels(0, GLOG_WARNING, false, false);
-  LogWithLevels(0, GLOG_ERROR, false, false);
-  LogWithLevels(0, GLOG_FATAL, false, false);
-  LogWithLevels(0, GLOG_FATAL, true, false);
-  LogWithLevels(0, GLOG_FATAL, false, true);
-  LogWithLevels(1, GLOG_WARNING, false, false);
-  LogWithLevels(1, GLOG_FATAL, false, true);
-}
-
-TEST(DeathRawCHECK, logging) {
-  ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
-               "RAW: Check false failed: failure 1");
-  ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
-               "RAW: Check 1 == 2 failed: failure 2");
-}
-
-void TestLogString() {
-  vector<string> errors;
-  vector<string> *no_errors = NULL;
-
-  LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
-  LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
-  LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
-
-  LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
-  LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
-  LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
-
-  for (size_t i = 0; i < errors.size(); ++i) {
-    LOG(INFO) << "Captured by LOG_STRING:  " << errors[i];
-  }
-}
-
-void TestLogToString() {
-  string error;
-  string* no_error = NULL;
-
-  LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
-  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
-  LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
-  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
-  LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
-  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
-
-  LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
-  LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
-  LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
-}
-
-class TestLogSinkImpl : public LogSink {
- public:
-  vector<string> errors;
-  virtual void send(LogSeverity severity, const char* /* full_filename */,
-                    const char* base_filename, int line,
-                    const LogMessageTime &logmsgtime,
-                    const char* message, size_t message_len) {
-    errors.push_back(
-      ToString(severity, base_filename, line, logmsgtime, message, message_len));
-  }
-};
-
-void TestLogSink() {
-  TestLogSinkImpl sink;
-  LogSink *no_sink = NULL;
-
-  LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
-  LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
-  LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
-
-  LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
-  LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
-  LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
-
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
-
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
-
-  LOG(INFO) << "Captured by LOG_TO_SINK:";
-  for (size_t i = 0; i < sink.errors.size(); ++i) {
-    LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
-      << sink.errors[i];
-  }
-}
-
-// For testing using CHECK*() on anonymous enums.
-enum {
-  CASE_A,
-  CASE_B
-};
-
-void TestCHECK() {
-  // Tests using CHECK*() on int values.
-  CHECK(1 == 1);
-  CHECK_EQ(1, 1);
-  CHECK_NE(1, 2);
-  CHECK_GE(1, 1);
-  CHECK_GE(2, 1);
-  CHECK_LE(1, 1);
-  CHECK_LE(1, 2);
-  CHECK_GT(2, 1);
-  CHECK_LT(1, 2);
-
-  // Tests using CHECK*() on anonymous enums.
-  // Apple's GCC doesn't like this.
-#if !defined(GLOG_OS_MACOSX)
-  CHECK_EQ(CASE_A, CASE_A);
-  CHECK_NE(CASE_A, CASE_B);
-  CHECK_GE(CASE_A, CASE_A);
-  CHECK_GE(CASE_B, CASE_A);
-  CHECK_LE(CASE_A, CASE_A);
-  CHECK_LE(CASE_A, CASE_B);
-  CHECK_GT(CASE_B, CASE_A);
-  CHECK_LT(CASE_A, CASE_B);
-#endif
-}
-
-void TestDCHECK() {
-#if defined(NDEBUG)
-  DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
-#endif
-  DCHECK( 1 == 1 );
-  DCHECK_EQ(1, 1);
-  DCHECK_NE(1, 2);
-  DCHECK_GE(1, 1);
-  DCHECK_GE(2, 1);
-  DCHECK_LE(1, 1);
-  DCHECK_LE(1, 2);
-  DCHECK_GT(2, 1);
-  DCHECK_LT(1, 2);
-
-  int64* orig_ptr = new int64;
-  int64* ptr = DCHECK_NOTNULL(orig_ptr);
-  CHECK_EQ(ptr, orig_ptr);
-  delete orig_ptr;
-}
-
-void TestSTREQ() {
-  CHECK_STREQ("this", "this");
-  CHECK_STREQ(NULL, NULL);
-  CHECK_STRCASEEQ("this", "tHiS");
-  CHECK_STRCASEEQ(NULL, NULL);
-  CHECK_STRNE("this", "tHiS");
-  CHECK_STRNE("this", NULL);
-  CHECK_STRCASENE("this", "that");
-  CHECK_STRCASENE(NULL, "that");
-  CHECK_STREQ((string("a")+"b").c_str(), "ab");
-  CHECK_STREQ(string("test").c_str(),
-              (string("te") + string("st")).c_str());
-}
-
-TEST(DeathSTREQ, logging) {
-  ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
-  ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
-  ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
-  ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
-  ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
-  ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
-  ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
-}
-
-TEST(CheckNOTNULL, Simple) {
-  int64 t;
-  void *ptr = static_cast<void *>(&t);
-  void *ref = CHECK_NOTNULL(ptr);
-  EXPECT_EQ(ptr, ref);
-  CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
-  CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
-  CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
-  CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
-}
-
-TEST(DeathCheckNN, Simple) {
-  ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
-}
-
-// Get list of file names that match pattern
-static void GetFiles(const string& pattern, vector<string>* files) {
-  files->clear();
-#if defined(HAVE_GLOB_H)
-  glob_t g;
-  const int r = glob(pattern.c_str(), 0, NULL, &g);
-  CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
-  for (size_t i = 0; i < g.gl_pathc; i++) {
-    files->push_back(string(g.gl_pathv[i]));
-  }
-  globfree(&g);
-#elif defined(GLOG_OS_WINDOWS)
-  WIN32_FIND_DATAA data;
-  HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
-  size_t index = pattern.rfind('\\');
-  if (index == string::npos) {
-    LOG(FATAL) << "No directory separator.";
-  }
-  const string dirname = pattern.substr(0, index + 1);
-  if (handle == INVALID_HANDLE_VALUE) {
-    // Finding no files is OK.
-    return;
-  }
-  do {
-    files->push_back(dirname + data.cFileName);
-  } while (FindNextFileA(handle, &data));
-  BOOL result = FindClose(handle);
-  LOG_SYSRESULT(result != 0);
-#else
-# error There is no way to do glob.
-#endif
-}
-
-// Delete files patching pattern
-static void DeleteFiles(const string& pattern) {
-  vector<string> files;
-  GetFiles(pattern, &files);
-  for (size_t i = 0; i < files.size(); i++) {
-    CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
-  }
-}
-
-//check string is in file (or is *NOT*, depending on optional checkInFileOrNot)
-static void CheckFile(const string& name, const string& expected_string, const bool checkInFileOrNot = true) {
-  vector<string> files;
-  GetFiles(name + "*", &files);
-  CHECK_EQ(files.size(), 1UL);
-
-  FILE* file = fopen(files[0].c_str(), "r");
-  CHECK(file != NULL) << ": could not open " << files[0];
-  char buf[1000];
-  while (fgets(buf, sizeof(buf), file) != NULL) {
-    char* first = strstr(buf, expected_string.c_str());
-    //if first == NULL, not found.
-    //Terser than if (checkInFileOrNot && first != NULL || !check...
-    if (checkInFileOrNot != (first == NULL)) {
-      fclose(file);
-      return;
-    }
-  }
-  fclose(file);
-  LOG(FATAL) << "Did " << (checkInFileOrNot? "not " : "") << "find " << expected_string << " in " << files[0];
-}
-
-static void TestBasename() {
-  fprintf(stderr, "==== Test setting log file basename\n");
-  const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
-  DeleteFiles(dest + "*");
-
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new base";
-  FlushLogFiles(GLOG_INFO);
-
-  CheckFile(dest, "message to new base");
-
-  // Release file handle for the destination file to unlock the file in Windows.
-  LogToStderr();
-  DeleteFiles(dest + "*");
-}
-
-static void TestBasenameAppendWhenNoTimestamp() {
-  fprintf(stderr, "==== Test setting log file basename without timestamp and appending properly\n");
-  const string dest = FLAGS_test_tmpdir + "/logging_test_basename_append_when_no_timestamp";
-  DeleteFiles(dest + "*");
-
-  ofstream out(dest.c_str());
-  out << "test preexisting content" << endl;
-  out.close();
-
-  CheckFile(dest, "test preexisting content");
-
-  FLAGS_timestamp_in_logfile_name=false;
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new base, appending to preexisting file";
-  FlushLogFiles(GLOG_INFO);
-  FLAGS_timestamp_in_logfile_name=true;
-
-  //if the logging overwrites the file instead of appending it will fail.
-  CheckFile(dest, "test preexisting content");
-  CheckFile(dest, "message to new base, appending to preexisting file");
-
-  // Release file handle for the destination file to unlock the file in Windows.
-  LogToStderr();
-  DeleteFiles(dest + "*");
-}
-
-static void TestTwoProcessesWrite() {
-// test only implemented for platforms with fork & wait; the actual implementation relies on flock
-#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL)
-  fprintf(stderr, "==== Test setting log file basename and two processes writing - second should fail\n");
-  const string dest = FLAGS_test_tmpdir + "/logging_test_basename_two_processes_writing";
-  DeleteFiles(dest + "*");
-
-  //make both processes write into the same file (easier test)
-  FLAGS_timestamp_in_logfile_name=false;
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new base, parent";
-  FlushLogFiles(GLOG_INFO);
-
-  pid_t pid = fork();
-  CHECK_ERR(pid);
-  if (pid == 0) {
-    LOG(INFO) << "message to new base, child - should only appear on STDERR not on the file";
-    ShutdownGoogleLogging(); //for children proc
-    exit(EXIT_SUCCESS);
-  } else if (pid > 0) {
-    wait(NULL);
-  }
-  FLAGS_timestamp_in_logfile_name=true;
-
-  CheckFile(dest, "message to new base, parent");
-  CheckFile(dest, "message to new base, child - should only appear on STDERR not on the file", false);
-
-  // Release
-  LogToStderr();
-  DeleteFiles(dest + "*");
-#endif
-}
-
-static void TestSymlink() {
-#ifndef GLOG_OS_WINDOWS
-  fprintf(stderr, "==== Test setting log file symlink\n");
-  string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
-  string sym = FLAGS_test_tmpdir + "/symlinkbase";
-  DeleteFiles(dest + "*");
-  DeleteFiles(sym + "*");
-
-  SetLogSymlink(GLOG_INFO, "symlinkbase");
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new symlink";
-  FlushLogFiles(GLOG_INFO);
-  CheckFile(sym, "message to new symlink");
-
-  DeleteFiles(dest + "*");
-  DeleteFiles(sym + "*");
-#endif
-}
-
-static void TestExtension() {
-  fprintf(stderr, "==== Test setting log file extension\n");
-  string dest = FLAGS_test_tmpdir + "/logging_test_extension";
-  DeleteFiles(dest + "*");
-
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  SetLogFilenameExtension("specialextension");
-  LOG(INFO) << "message to new extension";
-  FlushLogFiles(GLOG_INFO);
-  CheckFile(dest, "message to new extension");
-
-  // Check that file name ends with extension
-  vector<string> filenames;
-  GetFiles(dest + "*", &filenames);
-  CHECK_EQ(filenames.size(), 1UL);
-  CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
-
-  // Release file handle for the destination file to unlock the file in Windows.
-  LogToStderr();
-  DeleteFiles(dest + "*");
-}
-
-struct MyLogger : public base::Logger {
-  string data;
-
-  virtual void Write(bool /* should_flush */,
-                     time_t /* timestamp */,
-                     const char* message,
-                     size_t length) {
-    data.append(message, length);
-  }
-
-  virtual void Flush() { }
-
-  virtual uint32 LogSize() { return data.length(); }
-};
-
-static void TestWrapper() {
-  fprintf(stderr, "==== Test log wrapper\n");
-
-  MyLogger my_logger;
-  base::Logger* old_logger = base::GetLogger(GLOG_INFO);
-  base::SetLogger(GLOG_INFO, &my_logger);
-  LOG(INFO) << "Send to wrapped logger";
-  FlushLogFiles(GLOG_INFO);
-  base::SetLogger(GLOG_INFO, old_logger);
-
-  CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
-}
-
-static void TestErrno() {
-  fprintf(stderr, "==== Test errno preservation\n");
-
-  errno = ENOENT;
-  TestLogging(false);
-  CHECK_EQ(errno, ENOENT);
-}
-
-static void TestOneTruncate(const char *path, uint64 limit, uint64 keep,
-                            size_t dsize, size_t ksize, size_t expect) {
-  int fd;
-  CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
-
-  const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
-  const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr);
-
-  // Fill the file with the requested data; first discard data, then kept data
-  size_t written = 0;
-  while (written < dsize) {
-    size_t bytes = min(dsize - written, discard_size);
-    CHECK_ERR(write(fd, discardstr, bytes));
-    written += bytes;
-  }
-  written = 0;
-  while (written < ksize) {
-    size_t bytes = min(ksize - written, keep_size);
-    CHECK_ERR(write(fd, keepstr, bytes));
-    written += bytes;
-  }
-
-  TruncateLogFile(path, limit, keep);
-
-  // File should now be shorter
-  struct stat statbuf;
-  CHECK_ERR(fstat(fd, &statbuf));
-  CHECK_EQ(static_cast<size_t>(statbuf.st_size), expect);
-  CHECK_ERR(lseek(fd, 0, SEEK_SET));
-
-  // File should contain the suffix of the original file
-  const size_t buf_size = static_cast<size_t>(statbuf.st_size) + 1;
-  char* buf = new char[buf_size];
-  memset(buf, 0, buf_size);
-  CHECK_ERR(read(fd, buf, buf_size));
-
-  const char* p = buf;
-  size_t checked = 0;
-  while (checked < expect) {
-    size_t bytes = min(expect - checked, keep_size);
-    CHECK(!memcmp(p, keepstr, bytes));
-    checked += bytes;
-  }
-  close(fd);
-  delete[] buf;
-}
-
-static void TestTruncate() {
-#ifdef HAVE_UNISTD_H
-  fprintf(stderr, "==== Test log truncation\n");
-  string path = FLAGS_test_tmpdir + "/truncatefilecustom";
-
-  // Test on a small file
-  TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
-
-  // And a big file (multiple blocks to copy)
-  TestOneTruncate(path.c_str(), 2U << 20U, 4U << 10U, 3U << 20U, 4U << 10U,
-                  4U << 10U);
-
-  // Check edge-case limits
-  TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
-  TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
-  TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
-  TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
-
-  // MacOSX 10.4 doesn't fail in this case.
-  // Windows doesn't have symlink.
-  // Let's just ignore this test for these cases.
-#if !defined(GLOG_OS_MACOSX) && !defined(GLOG_OS_WINDOWS)
-  // Through a symlink should fail to truncate
-  string linkname = path + ".link";
-  unlink(linkname.c_str());
-  CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
-  TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
-#endif
-
-  // The /proc/self path makes sense only for linux.
-#if defined(GLOG_OS_LINUX)
-  // Through an open fd symlink should work
-  int fd;
-  CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
-  char fdpath[64];
-  snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
-  TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
-#endif
-
-#endif
-}
-
-struct RecordDeletionLogger : public base::Logger {
-  RecordDeletionLogger(bool* set_on_destruction,
-                       base::Logger* wrapped_logger) :
-      set_on_destruction_(set_on_destruction),
-      wrapped_logger_(wrapped_logger)
-  {
-    *set_on_destruction_ = false;
-  }
-  virtual ~RecordDeletionLogger() {
-    *set_on_destruction_ = true;
-  }
-  virtual void Write(bool force_flush,
-                     time_t timestamp,
-                     const char* message,
-                     size_t length) {
-    wrapped_logger_->Write(force_flush, timestamp, message, length);
-  }
-  virtual void Flush() { wrapped_logger_->Flush(); }
-  virtual uint32 LogSize() { return wrapped_logger_->LogSize(); }
- private:
-  bool* set_on_destruction_;
-  base::Logger* wrapped_logger_;
-};
-
-static void TestCustomLoggerDeletionOnShutdown() {
-  bool custom_logger_deleted = false;
-  base::SetLogger(GLOG_INFO,
-                  new RecordDeletionLogger(&custom_logger_deleted,
-                                           base::GetLogger(GLOG_INFO)));
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-  ShutdownGoogleLogging();
-  EXPECT_TRUE(custom_logger_deleted);
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-}
-
-_START_GOOGLE_NAMESPACE_
-namespace glog_internal_namespace_ {
-extern  // in logging.cc
-bool SafeFNMatch_(const char* pattern, size_t patt_len,
-                  const char* str, size_t str_len);
-} // namespace glog_internal_namespace_
-using glog_internal_namespace_::SafeFNMatch_;
-_END_GOOGLE_NAMESPACE_
-
-static bool WrapSafeFNMatch(string pattern, string str) {
-  pattern += "abc";
-  str += "defgh";
-  return SafeFNMatch_(pattern.data(), pattern.size() - 3,
-                      str.data(), str.size() - 5);
-}
-
-TEST(SafeFNMatch, logging) {
-  CHECK(WrapSafeFNMatch("foo", "foo"));
-  CHECK(!WrapSafeFNMatch("foo", "bar"));
-  CHECK(!WrapSafeFNMatch("foo", "fo"));
-  CHECK(!WrapSafeFNMatch("foo", "foo2"));
-  CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
-  CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
-  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
-  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
-  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
-  CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
-  CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
-  CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
-  CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
-  CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
-  CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
-  CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
-  CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
-}
-
-// TestWaitingLogSink will save messages here
-// No lock: Accessed only by TestLogSinkWriter thread
-// and after its demise by its creator.
-static vector<string> global_messages;
-
-// helper for TestWaitingLogSink below.
-// Thread that does the logic of TestWaitingLogSink
-// It's free to use LOG() itself.
-class TestLogSinkWriter : public Thread {
- public:
-
-  TestLogSinkWriter() : should_exit_(false) {
-    SetJoinable(true);
-    Start();
-  }
-
-  // Just buffer it (can't use LOG() here).
-  void Buffer(const string& message) {
-    mutex_.Lock();
-    RAW_LOG(INFO, "Buffering");
-    messages_.push(message);
-    mutex_.Unlock();
-    RAW_LOG(INFO, "Buffered");
-  }
-
-  // Wait for the buffer to clear (can't use LOG() here).
-  void Wait() {
-    RAW_LOG(INFO, "Waiting");
-    mutex_.Lock();
-    while (!NoWork()) {
-      mutex_.Unlock();
-      SleepForMilliseconds(1);
-      mutex_.Lock();
-    }
-    RAW_LOG(INFO, "Waited");
-    mutex_.Unlock();
-  }
-
-  // Trigger thread exit.
-  void Stop() {
-    MutexLock l(&mutex_);
-    should_exit_ = true;
-  }
-
- private:
-
-  // helpers ---------------
-
-  // For creating a "Condition".
-  bool NoWork() { return messages_.empty(); }
-  bool HaveWork() { return !messages_.empty() || should_exit_; }
-
-  // Thread body; CAN use LOG() here!
-  virtual void Run() {
-    while (1) {
-      mutex_.Lock();
-      while (!HaveWork()) {
-        mutex_.Unlock();
-        SleepForMilliseconds(1);
-        mutex_.Lock();
-      }
-      if (should_exit_ && messages_.empty()) {
-        mutex_.Unlock();
-        break;
-      }
-      // Give the main thread time to log its message,
-      // so that we get a reliable log capture to compare to golden file.
-      // Same for the other sleep below.
-      SleepForMilliseconds(20);
-      RAW_LOG(INFO, "Sink got a messages");  // only RAW_LOG under mutex_ here
-      string message = messages_.front();
-      messages_.pop();
-      // Normally this would be some more real/involved logging logic
-      // where LOG() usage can't be eliminated,
-      // e.g. pushing the message over with an RPC:
-      size_t messages_left = messages_.size();
-      mutex_.Unlock();
-      SleepForMilliseconds(20);
-      // May not use LOG while holding mutex_, because Buffer()
-      // acquires mutex_, and Buffer is called from LOG(),
-      // which has its own internal mutex:
-      // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
-      LOG(INFO) << "Sink is sending out a message: " << message;
-      LOG(INFO) << "Have " << messages_left << " left";
-      global_messages.push_back(message);
-    }
-  }
-
-  // data ---------------
-
-  Mutex mutex_;
-  bool should_exit_;
-  queue<string> messages_;  // messages to be logged
-};
-
-// A log sink that exercises WaitTillSent:
-// it pushes data to a buffer and wakes up another thread to do the logging
-// (that other thread can than use LOG() itself),
-class TestWaitingLogSink : public LogSink {
- public:
-
-  TestWaitingLogSink() {
-    tid_ = pthread_self();  // for thread-specific behavior
-    AddLogSink(this);
-  }
-  ~TestWaitingLogSink() {
-    RemoveLogSink(this);
-    writer_.Stop();
-    writer_.Join();
-  }
-
-  // (re)define LogSink interface
-
-  virtual void send(LogSeverity severity, const char* /* full_filename */,
-                    const char* base_filename, int line,
-                    const LogMessageTime &logmsgtime,
-                    const char* message, size_t message_len) {
-    // Push it to Writer thread if we are the original logging thread.
-    // Note: Something like ThreadLocalLogSink is a better choice
-    //       to do thread-specific LogSink logic for real.
-    if (pthread_equal(tid_, pthread_self())) {
-      writer_.Buffer(ToString(severity, base_filename, line,
-                              logmsgtime, message, message_len));
-    }
-  }
-
-  virtual void WaitTillSent() {
-    // Wait for Writer thread if we are the original logging thread.
-    if (pthread_equal(tid_, pthread_self()))  writer_.Wait();
-  }
-
- private:
-
-  pthread_t tid_;
-  TestLogSinkWriter writer_;
-};
-
-// Check that LogSink::WaitTillSent can be used in the advertised way.
-// We also do golden-stderr comparison.
-static void TestLogSinkWaitTillSent() {
-  { TestWaitingLogSink sink;
-    // Sleeps give the sink threads time to do all their work,
-    // so that we get a reliable log capture to compare to the golden file.
-    LOG(INFO) << "Message 1";
-    SleepForMilliseconds(60);
-    LOG(ERROR) << "Message 2";
-    SleepForMilliseconds(60);
-    LOG(WARNING) << "Message 3";
-    SleepForMilliseconds(60);
-  }
-  for (size_t i = 0; i < global_messages.size(); ++i) {
-    LOG(INFO) << "Sink capture: " << global_messages[i];
-  }
-  CHECK_EQ(global_messages.size(), 3UL);
-}
-
-TEST(Strerror, logging) {
-  int errcode = EINTR;
-  char *msg = strdup(strerror(errcode));
-  const size_t buf_size = strlen(msg) + 1;
-  char *buf = new char[buf_size];
-  CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
-  buf[0] = 'A';
-  CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
-  CHECK_EQ(buf[0], 'A');
-  CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
-#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
-  // MacOSX or FreeBSD considers this case is an error since there is
-  // no enough space.
-  CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
-#else
-  CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
-#endif
-  CHECK_STREQ(buf, "");
-  CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
-  CHECK_STREQ(buf, msg);
-  delete[] buf;
-  CHECK_EQ(msg, StrError(errcode));
-  free(msg);
-}
-
-// Simple routines to look at the sizes of generated code for LOG(FATAL) and
-// CHECK(..) via objdump
-/*
-static void MyFatal() {
-  LOG(FATAL) << "Failed";
-}
-static void MyCheck(bool a, bool b) {
-  CHECK_EQ(a, b);
-}
-*/
-#ifdef HAVE_LIB_GMOCK
-
-TEST(DVLog, Basic) {
-  ScopedMockLog log;
-
-#if defined(NDEBUG)
-  // We are expecting that nothing is logged.
-  EXPECT_CALL(log, Log(_, _, _)).Times(0);
-#else
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "debug log"));
-#endif
-
-  FLAGS_v = 1;
-  DVLOG(1) << "debug log";
-}
-
-TEST(DVLog, V0) {
-  ScopedMockLog log;
-
-  // We are expecting that nothing is logged.
-  EXPECT_CALL(log, Log(_, _, _)).Times(0);
-
-  FLAGS_v = 0;
-  DVLOG(1) << "debug log";
-}
-
-TEST(LogAtLevel, Basic) {
-  ScopedMockLog log;
-
-  // The function version outputs "logging.h" as a file name.
-  EXPECT_CALL(log, Log(GLOG_WARNING, StrNe(__FILE__), "function version"));
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "macro version"));
-
-  int severity = GLOG_WARNING;
-  LogAtLevel(severity, "function version");
-
-  severity = GLOG_INFO;
-  // We can use the macro version as a C++ stream.
-  LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
-}
-
-TEST(TestExitOnDFatal, ToBeOrNotToBe) {
-  // Check the default setting...
-  EXPECT_TRUE(base::internal::GetExitOnDFatal());
-
-  // Turn off...
-  base::internal::SetExitOnDFatal(false);
-  EXPECT_FALSE(base::internal::GetExitOnDFatal());
-
-  // We don't die.
-  {
-    ScopedMockLog log;
-    //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
-    // LOG(DFATAL) has severity FATAL if debugging, but is
-    // downgraded to ERROR if not debugging.
-    const LogSeverity severity =
-#if defined(NDEBUG)
-        GLOG_ERROR;
-#else
-        GLOG_FATAL;
-#endif
-    EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
-    LOG(DFATAL) << "This should not be fatal";
-  }
-
-  // Turn back on...
-  base::internal::SetExitOnDFatal(true);
-  EXPECT_TRUE(base::internal::GetExitOnDFatal());
-
-#ifdef GTEST_HAS_DEATH_TEST
-  // Death comes on little cats' feet.
-  EXPECT_DEBUG_DEATH({
-      LOG(DFATAL) << "This should be fatal in debug mode";
-    }, "This should be fatal in debug mode");
-#endif
-}
-
-#ifdef HAVE_STACKTRACE
-
-static void BacktraceAtHelper() {
-  LOG(INFO) << "Not me";
-
-// The vertical spacing of the next 3 lines is significant.
-  LOG(INFO) << "Backtrace me";
-}
-static int kBacktraceAtLine = __LINE__ - 2;  // The line of the LOG(INFO) above
-
-TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
-  StrictMock<ScopedMockLog> log;
-
-  FLAGS_log_backtrace_at = "";
-
-  EXPECT_CALL(log, Log(_, _, "Backtrace me"));
-  EXPECT_CALL(log, Log(_, _, "Not me"));
-
-  BacktraceAtHelper();
-}
-
-TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
-  StrictMock<ScopedMockLog> log;
-
-  char where[100];
-  snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
-  FLAGS_log_backtrace_at = where;
-
-  // The LOG at the specified line should include a stacktrace which includes
-  // the name of the containing function, followed by the log message.
-  // We use HasSubstr()s instead of ContainsRegex() for environments
-  // which don't have regexp.
-  EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
-                                   HasSubstr("BacktraceAtHelper"),
-                                   HasSubstr("main"),
-                                   HasSubstr("Backtrace me"))));
-  // Other LOGs should not include a backtrace.
-  EXPECT_CALL(log, Log(_, _, "Not me"));
-
-  BacktraceAtHelper();
-}
-
-#endif // HAVE_STACKTRACE
-
-#endif // HAVE_LIB_GMOCK
-
-struct UserDefinedClass {
-  bool operator==(const UserDefinedClass&) const { return true; }
-};
-
-inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
-  out << "OK";
-  return out;
-}
-
-TEST(UserDefinedClass, logging) {
-  UserDefinedClass u;
-  vector<string> buf;
-  LOG_STRING(INFO, &buf) << u;
-  CHECK_EQ(1UL, buf.size());
-  CHECK(buf[0].find("OK") != string::npos);
-
-  // We must be able to compile this.
-  CHECK_EQ(u, u);
-}
-
-TEST(LogMsgTime, gmtoff) {
-  /*
-   * Unit test for GMT offset API
-   * TODO: To properly test this API, we need a platform independent way to set time-zone.
-   * */
-  google::LogMessage log_obj(__FILE__, __LINE__);
-
-  long int nGmtOff = log_obj.getLogMessageTime().gmtoff();
-  // GMT offset ranges from UTC-12:00 to UTC+14:00
-  const long utc_min_offset = -43200;
-  const long utc_max_offset = 50400;
-  EXPECT_TRUE( (nGmtOff >= utc_min_offset) && (nGmtOff <= utc_max_offset) );
-}
diff --git a/third_party/google-glog/src/logging_custom_prefix_unittest.err b/third_party/google-glog/src/logging_custom_prefix_unittest.err
deleted file mode 100644
index ccd5ba9..0000000
--- a/third_party/google-glog/src/logging_custom_prefix_unittest.err
+++ /dev/null
@@ -1,308 +0,0 @@
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-WARNING: Logging before InitGoogleLogging() is written to STDERR
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] foo bar 10 3.4
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0]
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 1
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 4, iteration 1
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 5, iteration 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 1
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if less than 3 every 2, iteration 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 2
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2]
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 3
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if less than 3 every 2, iteration 3
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 4
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 4
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4]
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 4, iteration 5
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 5
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 5, iteration 6
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 6
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6]
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 7
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 7
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 8
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8]
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 4, iteration 9
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 9
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 10
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 10
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if this
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] array
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] const array
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] foo 1000       1000 3e8
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] foo          1
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] inner
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] outer
-no prefix
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo bar 10 3.400000
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: array
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: const array
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: ptr __PTRTEST__
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: ptr __NULLP__
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo 1000
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo 1000
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 on
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 1 on
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 2 on
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_STRING: reported info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_STRING: reported warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_STRING: reported error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected info
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected warning
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: reported info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: reported warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: reported error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_SINK:
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: collected info
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: collected warning
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: collected error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: reported info
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: reported warning
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: reported error
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffering
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffered
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waiting
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Sink got a messages
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waited
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Have 0 left
-EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffering
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffered
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waiting
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Sink got a messages
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waited
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Have 0 left
-WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 3
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffering
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffered
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waiting
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Sink got a messages
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waited
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 3
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Have 0 left
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 3
diff --git a/third_party/google-glog/src/logging_striplog_test.sh b/third_party/google-glog/src/logging_striplog_test.sh
deleted file mode 100755
index 73492bd..0000000
--- a/third_party/google-glog/src/logging_striplog_test.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: Sergey Ioffe
-
-get_strings () {
-    if test -e ".libs/$1"; then
-        binary=".libs/$1"
-    elif test -e "$1.exe"; then
-        binary="$1.exe"
-    else
-        echo "We coundn't find $1 binary."
-        exit 1
-    fi
-    
-    strings -n 10 $binary | sort | awk '/TESTMESSAGE/ {printf "%s ", $2}'
-}
-
-# Die if "$1" != "$2", print $3 as death reason
-check_eq () {
-    if [ "$1" != "$2" ]; then
-        echo "Check failed: '$1' == '$2' ${3:+ ($3)}"
-        exit 1
-    fi
-}
-
-die () {
-    echo $1
-    exit 1
-}
-
-# Check that the string literals are appropriately stripped. This will
-# not be the case in debug mode.
-
-mode=`GLOG_check_mode=1 ./logging_striptest0 2> /dev/null`
-if [ "$mode" = "opt" ];
-then
-    echo "In OPT mode"
-    check_eq "`get_strings logging_striptest0`" "COND ERROR FATAL INFO USAGE WARNING "
-    check_eq "`get_strings logging_striptest2`" "COND ERROR FATAL USAGE "
-    check_eq "`get_strings logging_striptest10`" "" 
-else
-    echo "In DBG mode; not checking strings"
-fi
-
-# Check that LOG(FATAL) aborts even for large STRIP_LOG
-
-./logging_striptest2 2>/dev/null && die "Did not abort for STRIP_LOG=2"
-./logging_striptest10 2>/dev/null && die "Did not abort for STRIP_LOG=10"
-
-echo "PASS"
diff --git a/third_party/google-glog/src/logging_striptest10.cc b/third_party/google-glog/src/logging_striptest10.cc
deleted file mode 100644
index f6e1078..0000000
--- a/third_party/google-glog/src/logging_striptest10.cc
+++ /dev/null
@@ -1,35 +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: Sergey Ioffe
-
-#define GOOGLE_STRIP_LOG 10
-
-// Include the actual test.
-#include "logging_striptest_main.cc"
diff --git a/third_party/google-glog/src/logging_striptest2.cc b/third_party/google-glog/src/logging_striptest2.cc
deleted file mode 100644
index a64685c..0000000
--- a/third_party/google-glog/src/logging_striptest2.cc
+++ /dev/null
@@ -1,35 +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: Sergey Ioffe
-
-#define GOOGLE_STRIP_LOG 2
-
-// Include the actual test.
-#include "logging_striptest_main.cc"
diff --git a/third_party/google-glog/src/logging_striptest_main.cc b/third_party/google-glog/src/logging_striptest_main.cc
deleted file mode 100644
index 27e1254..0000000
--- a/third_party/google-glog/src/logging_striptest_main.cc
+++ /dev/null
@@ -1,73 +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: Sergey Ioffe
-
-// The common part of the striplog tests.
-
-#include <cstdio>
-#include <string>
-#include <iosfwd>
-#include <glog/logging.h>
-#include "base/commandlineflags.h"
-#include "config.h"
-
-DECLARE_bool(logtostderr);
-GLOG_DEFINE_bool(check_mode, false, "Prints 'opt' or 'dbg'");
-
-using std::string;
-using namespace GOOGLE_NAMESPACE;
-
-int CheckNoReturn(bool b) {
-  string s;
-  if (b) {
-    LOG(FATAL) << "Fatal";
-  } else {
-    return 0;
-  }
-}
-
-struct A { };
-std::ostream &operator<<(std::ostream &str, const A&) {return str;}
-
-int main(int, char* argv[]) {
-  FLAGS_logtostderr = true;
-  InitGoogleLogging(argv[0]);
-  if (FLAGS_check_mode) {
-    printf("%s\n", DEBUG_MODE ? "dbg" : "opt");
-    return 0;
-  }
-  LOG(INFO) << "TESTMESSAGE INFO";
-  LOG(WARNING) << 2 << "something" << "TESTMESSAGE WARNING"
-               << 1 << 'c' << A() << std::endl;
-  LOG(ERROR) << "TESTMESSAGE ERROR";
-  bool flag = true;
-  (flag ? LOG(INFO) : LOG(ERROR)) << "TESTMESSAGE COND";
-  LOG(FATAL) << "TESTMESSAGE FATAL";
-}
diff --git a/third_party/google-glog/src/logging_unittest.cc b/third_party/google-glog/src/logging_unittest.cc
deleted file mode 100644
index 728b5fe..0000000
--- a/third_party/google-glog/src/logging_unittest.cc
+++ /dev/null
@@ -1,1477 +0,0 @@
-// Copyright (c) 2002, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Ray Sidney
-
-#include "config.h"
-#include "utilities.h"
-
-#include <fcntl.h>
-#ifdef HAVE_GLOB_H
-# include <glob.h>
-#endif
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#include <cstdio>
-#include <cstdlib>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <memory>
-#include <queue>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "base/commandlineflags.h"
-#include <glog/logging.h>
-#include <glog/raw_logging.h>
-#include "googletest.h"
-
-DECLARE_string(log_backtrace_at);  // logging.cc
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-#ifdef HAVE_LIB_GMOCK
-#include <gmock/gmock.h>
-#include "mock-log.h"
-// Introduce several symbols from gmock.
-using testing::_;
-using testing::AnyNumber;
-using testing::HasSubstr;
-using testing::AllOf;
-using testing::StrNe;
-using testing::StrictMock;
-using testing::InitGoogleMock;
-using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
-#endif
-
-using namespace std;
-using namespace GOOGLE_NAMESPACE;
-
-// Some non-advertised functions that we want to test or use.
-_START_GOOGLE_NAMESPACE_
-namespace base {
-namespace internal {
-bool GetExitOnDFatal();
-void SetExitOnDFatal(bool value);
-}  // namespace internal
-}  // namespace base
-_END_GOOGLE_NAMESPACE_
-
-static void TestLogging(bool check_counts);
-static void TestRawLogging();
-static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
-static void TestLoggingLevels();
-static void TestVLogModule();
-static void TestLogString();
-static void TestLogSink();
-static void TestLogToString();
-static void TestLogSinkWaitTillSent();
-static void TestCHECK();
-static void TestDCHECK();
-static void TestSTREQ();
-static void TestBasename();
-static void TestBasenameAppendWhenNoTimestamp();
-static void TestTwoProcessesWrite();
-static void TestSymlink();
-static void TestExtension();
-static void TestWrapper();
-static void TestErrno();
-static void TestTruncate();
-static void TestCustomLoggerDeletionOnShutdown();
-static void TestLogPeriodically();
-
-static int x = -1;
-static void BM_Check1(int n) {
-  while (n-- > 0) {
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-    CHECK_GE(n, x);
-  }
-}
-BENCHMARK(BM_Check1)
-
-static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
-static void BM_Check3(int n) {
-  while (n-- > 0) {
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
-  }
-}
-BENCHMARK(BM_Check3)
-
-static void BM_Check2(int n) {
-  if (n == 17) {
-    x = 5;
-  }
-  while (n-- > 0) {
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-    CHECK(n >= x);
-  }
-}
-BENCHMARK(BM_Check2)
-
-static void CheckFailure(int, int, const char* /* file */, int /* line */,
-                         const char* /* msg */) {
-}
-
-static void BM_logspeed(int n) {
-  while (n-- > 0) {
-    LOG(INFO) << "test message";
-  }
-}
-BENCHMARK(BM_logspeed)
-
-static void BM_vlog(int n) {
-  while (n-- > 0) {
-    VLOG(1) << "test message";
-  }
-}
-BENCHMARK(BM_vlog)
-
-int main(int argc, char **argv) {
-  FLAGS_colorlogtostderr = false;
-  FLAGS_timestamp_in_logfile_name = true;
-
-  // Make sure stderr is not buffered as stderr seems to be buffered
-  // on recent windows.
-  setbuf(stderr, NULL);
-
-  // Test some basics before InitGoogleLogging:
-  CaptureTestStderr();
-  LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
-                FLAGS_logtostderr, FLAGS_alsologtostderr);
-  LogWithLevels(0, 0, 0, 0);  // simulate "before global c-tors"
-  const string early_stderr = GetCapturedTestStderr();
-
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-
-  InitGoogleLogging(argv[0]);
-
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-
-  RunSpecifiedBenchmarks();
-
-  FLAGS_logtostderr = true;
-
-  InitGoogleTest(&argc, argv);
-#ifdef HAVE_LIB_GMOCK
-  InitGoogleMock(&argc, argv);
-#endif
-
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-
-  // so that death tests run before we use threads
-  CHECK_EQ(RUN_ALL_TESTS(), 0);
-
-  CaptureTestStderr();
-
-  // re-emit early_stderr
-  LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
-
-  TestLogging(true);
-  TestRawLogging();
-  TestLoggingLevels();
-  TestVLogModule();
-  TestLogString();
-  TestLogSink();
-  TestLogToString();
-  TestLogSinkWaitTillSent();
-  TestCHECK();
-  TestDCHECK();
-  TestSTREQ();
-
-  // TODO: The golden test portion of this test is very flakey.
-  EXPECT_TRUE(
-      MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
-
-  FLAGS_logtostderr = false;
-
-  FLAGS_logtostdout = true;
-  FLAGS_stderrthreshold = NUM_SEVERITIES;
-  CaptureTestStdout();
-  TestRawLogging();
-  TestLoggingLevels();
-  TestLogString();
-  TestLogSink();
-  TestLogToString();
-  TestLogSinkWaitTillSent();
-  TestCHECK();
-  TestDCHECK();
-  TestSTREQ();
-  EXPECT_TRUE(
-      MungeAndDiffTestStdout(FLAGS_test_srcdir + "/src/logging_unittest.out"));
-  FLAGS_logtostdout = false;
-
-  TestBasename();
-  TestBasenameAppendWhenNoTimestamp();
-  TestTwoProcessesWrite();
-  TestSymlink();
-  TestExtension();
-  TestWrapper();
-  TestErrno();
-  TestTruncate();
-  TestCustomLoggerDeletionOnShutdown();
-  TestLogPeriodically();
-
-  fprintf(stdout, "PASS\n");
-  return 0;
-}
-
-void TestLogging(bool check_counts) {
-  int64 base_num_infos   = LogMessage::num_messages(GLOG_INFO);
-  int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
-  int64 base_num_errors  = LogMessage::num_messages(GLOG_ERROR);
-
-  LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
-  for ( int i = 0; i < 10; ++i ) {
-    int old_errno = errno;
-    errno = i;
-    PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
-    errno = old_errno;
-
-    LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
-    LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
-
-    LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
-    LOG_IF_EVERY_N(WARNING, false, 3)
-        << "Log if every 3, iteration " << COUNTER;
-    LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
-    LOG_IF_EVERY_N(ERROR, (i < 3), 2)
-        << "Log if less than 3 every 2, iteration " << COUNTER;
-  }
-  LOG_IF(WARNING, true) << "log_if this";
-  LOG_IF(WARNING, false) << "don't log_if this";
-
-  char s[] = "array";
-  LOG(INFO) << s;
-  const char const_s[] = "const array";
-  LOG(INFO) << const_s;
-  int j = 1000;
-  LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
-             << setw(1) << hex << j;
-  LOG(INFO) << "foo " << std::setw(10) << 1.0;
-
-  {
-    google::LogMessage outer(__FILE__, __LINE__, GLOG_ERROR);
-    outer.stream() << "outer";
-
-    LOG(ERROR) << "inner";
-  }
-
-  LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
-
-  if (check_counts) {
-    CHECK_EQ(base_num_infos   + 15, LogMessage::num_messages(GLOG_INFO));
-    CHECK_EQ(base_num_warning + 3,  LogMessage::num_messages(GLOG_WARNING));
-    CHECK_EQ(base_num_errors  + 17, LogMessage::num_messages(GLOG_ERROR));
-  }
-}
-
-static void NoAllocNewHook() {
-  LOG(FATAL) << "unexpected new";
-}
-
-struct NewHook {
-  NewHook() {
-    g_new_hook = &NoAllocNewHook;
-  }
-  ~NewHook() {
-    g_new_hook = NULL;
-  }
-};
-
-TEST(DeathNoAllocNewHook, logging) {
-  // tests that NewHook used below works
-  NewHook new_hook;
-  ASSERT_DEATH({
-    new int;
-  }, "unexpected new");
-}
-
-void TestRawLogging() {
-  string* foo = new string("foo ");
-  string huge_str(50000, 'a');
-
-  FlagSaver saver;
-
-  // Check that RAW loggging does not use mallocs.
-  NewHook new_hook;
-
-  RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
-  char s[] = "array";
-  RAW_LOG(WARNING, "%s", s);
-  const char const_s[] = "const array";
-  RAW_LOG(INFO, "%s", const_s);
-  void* p = reinterpret_cast<void*>(PTR_TEST_VALUE);
-  RAW_LOG(INFO, "ptr %p", p);
-  p = NULL;
-  RAW_LOG(INFO, "ptr %p", p);
-  int j = 1000;
-  RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
-  RAW_VLOG(0, "foo %d", j);
-
-#if defined(NDEBUG)
-  RAW_LOG(INFO, "foo %d", j);  // so that have same stderr to compare
-#else
-  RAW_DLOG(INFO, "foo %d", j);  // test RAW_DLOG in debug mode
-#endif
-
-  // test how long messages are chopped:
-  RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
-  RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
-
-  FLAGS_v = 0;
-  RAW_LOG(INFO, "log");
-  RAW_VLOG(0, "vlog 0 on");
-  RAW_VLOG(1, "vlog 1 off");
-  RAW_VLOG(2, "vlog 2 off");
-  RAW_VLOG(3, "vlog 3 off");
-  FLAGS_v = 2;
-  RAW_LOG(INFO, "log");
-  RAW_VLOG(1, "vlog 1 on");
-  RAW_VLOG(2, "vlog 2 on");
-  RAW_VLOG(3, "vlog 3 off");
-
-#if defined(NDEBUG)
-  RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
-#endif
-
-  RAW_CHECK(1 == 1, "should be ok");
-  RAW_DCHECK(true, "should be ok");
-
-  delete foo;
-}
-
-void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
-  RAW_LOG(INFO,
-          "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
-          v, severity, err, alsoerr);
-
-  FlagSaver saver;
-
-  FLAGS_v = v;
-  FLAGS_stderrthreshold = severity;
-  FLAGS_logtostderr = err;
-  FLAGS_alsologtostderr = alsoerr;
-
-  RAW_VLOG(-1, "vlog -1");
-  RAW_VLOG(0, "vlog 0");
-  RAW_VLOG(1, "vlog 1");
-  RAW_LOG(INFO, "log info");
-  RAW_LOG(WARNING, "log warning");
-  RAW_LOG(ERROR, "log error");
-
-  VLOG(-1) << "vlog -1";
-  VLOG(0) << "vlog 0";
-  VLOG(1) << "vlog 1";
-  LOG(INFO) << "log info";
-  LOG(WARNING) << "log warning";
-  LOG(ERROR) << "log error";
-
-  VLOG_IF(-1, true) << "vlog_if -1";
-  VLOG_IF(-1, false) << "don't vlog_if -1";
-  VLOG_IF(0, true) << "vlog_if 0";
-  VLOG_IF(0, false) << "don't vlog_if 0";
-  VLOG_IF(1, true) << "vlog_if 1";
-  VLOG_IF(1, false) << "don't vlog_if 1";
-  LOG_IF(INFO, true) << "log_if info";
-  LOG_IF(INFO, false) << "don't log_if info";
-  LOG_IF(WARNING, true) << "log_if warning";
-  LOG_IF(WARNING, false) << "don't log_if warning";
-  LOG_IF(ERROR, true) << "log_if error";
-  LOG_IF(ERROR, false) << "don't log_if error";
-
-  int c;
-  c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
-  c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
-  c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
-  c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
-  c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
-  c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
-
-  c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
-  EXPECT_EQ(c, -1);
-  c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
-  EXPECT_EQ(c, -1);
-  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
-  EXPECT_EQ(c, 0);
-  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
-  EXPECT_EQ(c, 0);
-  c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
-  EXPECT_EQ(c, 1);
-  c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
-  EXPECT_EQ(c, 1);
-  c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
-  EXPECT_EQ(c, 0);
-  c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
-  EXPECT_EQ(c, 0);
-}
-
-void TestLoggingLevels() {
-  LogWithLevels(0, GLOG_INFO, false, false);
-  LogWithLevels(1, GLOG_INFO, false, false);
-  LogWithLevels(-1, GLOG_INFO, false, false);
-  LogWithLevels(0, GLOG_WARNING, false, false);
-  LogWithLevels(0, GLOG_ERROR, false, false);
-  LogWithLevels(0, GLOG_FATAL, false, false);
-  LogWithLevels(0, GLOG_FATAL, true, false);
-  LogWithLevels(0, GLOG_FATAL, false, true);
-  LogWithLevels(1, GLOG_WARNING, false, false);
-  LogWithLevels(1, GLOG_FATAL, false, true);
-}
-
-int TestVlogHelper() {
-  if (VLOG_IS_ON(1)) {
-    return 1;
-  }
-  return 0;
-}
-
-void TestVLogModule() {
-  int c = TestVlogHelper();
-  EXPECT_EQ(0, c);
-
-#if defined(__GNUC__)
-  EXPECT_EQ(0, SetVLOGLevel("logging_unittest", 1));
-  c = TestVlogHelper();
-  EXPECT_EQ(1, c);
-#endif
-}
-
-TEST(DeathRawCHECK, logging) {
-  ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
-               "RAW: Check false failed: failure 1");
-  ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
-               "RAW: Check 1 == 2 failed: failure 2");
-}
-
-void TestLogString() {
-  vector<string> errors;
-  vector<string> *no_errors = NULL;
-
-  LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
-  LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
-  LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
-
-  LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
-  LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
-  LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
-
-  for (size_t i = 0; i < errors.size(); ++i) {
-    LOG(INFO) << "Captured by LOG_STRING:  " << errors[i];
-  }
-}
-
-void TestLogToString() {
-  string error;
-  string* no_error = NULL;
-
-  LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
-  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
-  LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
-  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
-  LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
-  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
-
-  LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
-  LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
-  LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
-}
-
-class TestLogSinkImpl : public LogSink {
- public:
-  vector<string> errors;
-  virtual void send(LogSeverity severity, const char* /* full_filename */,
-                    const char* base_filename, int line,
-                    const LogMessageTime &logmsgtime,
-                    const char* message, size_t message_len) {
-    errors.push_back(
-      ToString(severity, base_filename, line, logmsgtime, message, message_len));
-  }
-};
-
-void TestLogSink() {
-  TestLogSinkImpl sink;
-  LogSink *no_sink = NULL;
-
-  LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
-  LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
-  LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
-
-  LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
-  LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
-  LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
-
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
-
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
-  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
-      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
-
-  LOG(INFO) << "Captured by LOG_TO_SINK:";
-  for (size_t i = 0; i < sink.errors.size(); ++i) {
-    LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
-      << sink.errors[i];
-  }
-}
-
-// For testing using CHECK*() on anonymous enums.
-enum {
-  CASE_A,
-  CASE_B
-};
-
-void TestCHECK() {
-  // Tests using CHECK*() on int values.
-  CHECK(1 == 1);
-  CHECK_EQ(1, 1);
-  CHECK_NE(1, 2);
-  CHECK_GE(1, 1);
-  CHECK_GE(2, 1);
-  CHECK_LE(1, 1);
-  CHECK_LE(1, 2);
-  CHECK_GT(2, 1);
-  CHECK_LT(1, 2);
-
-  // Tests using CHECK*() on anonymous enums.
-  // Apple's GCC doesn't like this.
-#if !defined(GLOG_OS_MACOSX)
-  CHECK_EQ(CASE_A, CASE_A);
-  CHECK_NE(CASE_A, CASE_B);
-  CHECK_GE(CASE_A, CASE_A);
-  CHECK_GE(CASE_B, CASE_A);
-  CHECK_LE(CASE_A, CASE_A);
-  CHECK_LE(CASE_A, CASE_B);
-  CHECK_GT(CASE_B, CASE_A);
-  CHECK_LT(CASE_A, CASE_B);
-#endif
-}
-
-void TestDCHECK() {
-#if defined(NDEBUG)
-  DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
-#endif
-  DCHECK( 1 == 1 );
-  DCHECK_EQ(1, 1);
-  DCHECK_NE(1, 2);
-  DCHECK_GE(1, 1);
-  DCHECK_GE(2, 1);
-  DCHECK_LE(1, 1);
-  DCHECK_LE(1, 2);
-  DCHECK_GT(2, 1);
-  DCHECK_LT(1, 2);
-
-  int64* orig_ptr = new int64;
-  int64* ptr = DCHECK_NOTNULL(orig_ptr);
-  CHECK_EQ(ptr, orig_ptr);
-  delete orig_ptr;
-}
-
-void TestSTREQ() {
-  CHECK_STREQ("this", "this");
-  CHECK_STREQ(NULL, NULL);
-  CHECK_STRCASEEQ("this", "tHiS");
-  CHECK_STRCASEEQ(NULL, NULL);
-  CHECK_STRNE("this", "tHiS");
-  CHECK_STRNE("this", NULL);
-  CHECK_STRCASENE("this", "that");
-  CHECK_STRCASENE(NULL, "that");
-  CHECK_STREQ((string("a")+"b").c_str(), "ab");
-  CHECK_STREQ(string("test").c_str(),
-              (string("te") + string("st")).c_str());
-}
-
-TEST(DeathSTREQ, logging) {
-  ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
-  ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
-  ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
-  ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
-  ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
-  ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
-  ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
-}
-
-TEST(CheckNOTNULL, Simple) {
-  int64 t;
-  void *ptr = static_cast<void *>(&t);
-  void *ref = CHECK_NOTNULL(ptr);
-  EXPECT_EQ(ptr, ref);
-  CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
-  CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
-  CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
-  CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
-}
-
-TEST(DeathCheckNN, Simple) {
-  ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
-}
-
-// Get list of file names that match pattern
-static void GetFiles(const string& pattern, vector<string>* files) {
-  files->clear();
-#if defined(HAVE_GLOB_H)
-  glob_t g;
-  const int r = glob(pattern.c_str(), 0, NULL, &g);
-  CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
-  for (size_t i = 0; i < g.gl_pathc; i++) {
-    files->push_back(string(g.gl_pathv[i]));
-  }
-  globfree(&g);
-#elif defined(GLOG_OS_WINDOWS)
-  WIN32_FIND_DATAA data;
-  HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
-  size_t index = pattern.rfind('\\');
-  if (index == string::npos) {
-    LOG(FATAL) << "No directory separator.";
-  }
-  const string dirname = pattern.substr(0, index + 1);
-  if (handle == INVALID_HANDLE_VALUE) {
-    // Finding no files is OK.
-    return;
-  }
-  do {
-    files->push_back(dirname + data.cFileName);
-  } while (FindNextFileA(handle, &data));
-  BOOL result = FindClose(handle);
-  LOG_SYSRESULT(result != 0);
-#else
-# error There is no way to do glob.
-#endif
-}
-
-// Delete files patching pattern
-static void DeleteFiles(const string& pattern) {
-  vector<string> files;
-  GetFiles(pattern, &files);
-  for (size_t i = 0; i < files.size(); i++) {
-    CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
-  }
-}
-
-//check string is in file (or is *NOT*, depending on optional checkInFileOrNot)
-static void CheckFile(const string& name, const string& expected_string, const bool checkInFileOrNot = true) {
-  vector<string> files;
-  GetFiles(name + "*", &files);
-  CHECK_EQ(files.size(), 1UL);
-
-  FILE* file = fopen(files[0].c_str(), "r");
-  CHECK(file != NULL) << ": could not open " << files[0];
-  char buf[1000];
-  while (fgets(buf, sizeof(buf), file) != NULL) {
-    char* first = strstr(buf, expected_string.c_str());
-    //if first == NULL, not found.
-    //Terser than if (checkInFileOrNot && first != NULL || !check...
-    if (checkInFileOrNot != (first == NULL)) {
-      fclose(file);
-      return;
-    }
-  }
-  fclose(file);
-  LOG(FATAL) << "Did " << (checkInFileOrNot? "not " : "") << "find " << expected_string << " in " << files[0];
-}
-
-static void TestBasename() {
-  fprintf(stderr, "==== Test setting log file basename\n");
-  const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
-  DeleteFiles(dest + "*");
-
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new base";
-  FlushLogFiles(GLOG_INFO);
-
-  CheckFile(dest, "message to new base");
-
-  // Release file handle for the destination file to unlock the file in Windows.
-  LogToStderr();
-  DeleteFiles(dest + "*");
-}
-
-static void TestBasenameAppendWhenNoTimestamp() {
-  fprintf(stderr, "==== Test setting log file basename without timestamp and appending properly\n");
-  const string dest = FLAGS_test_tmpdir + "/logging_test_basename_append_when_no_timestamp";
-  DeleteFiles(dest + "*");
-
-  ofstream out(dest.c_str());
-  out << "test preexisting content" << endl;
-  out.close();
-
-  CheckFile(dest, "test preexisting content");
-
-  FLAGS_timestamp_in_logfile_name=false;
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new base, appending to preexisting file";
-  FlushLogFiles(GLOG_INFO);
-  FLAGS_timestamp_in_logfile_name=true;
-
-  //if the logging overwrites the file instead of appending it will fail.
-  CheckFile(dest, "test preexisting content");
-  CheckFile(dest, "message to new base, appending to preexisting file");
-
-  // Release file handle for the destination file to unlock the file in Windows.
-  LogToStderr();
-  DeleteFiles(dest + "*");
-}
-
-static void TestTwoProcessesWrite() {
-// test only implemented for platforms with fork & wait; the actual implementation relies on flock
-#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL)
-  fprintf(stderr, "==== Test setting log file basename and two processes writing - second should fail\n");
-  const string dest = FLAGS_test_tmpdir + "/logging_test_basename_two_processes_writing";
-  DeleteFiles(dest + "*");
-
-  //make both processes write into the same file (easier test)
-  FLAGS_timestamp_in_logfile_name=false;
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new base, parent";
-  FlushLogFiles(GLOG_INFO);
-
-  pid_t pid = fork();
-  CHECK_ERR(pid);
-  if (pid == 0) {
-    LOG(INFO) << "message to new base, child - should only appear on STDERR not on the file";
-    ShutdownGoogleLogging(); //for children proc
-    exit(EXIT_SUCCESS);
-  } else if (pid > 0) {
-    wait(NULL);
-  }
-  FLAGS_timestamp_in_logfile_name=true;
-
-  CheckFile(dest, "message to new base, parent");
-  CheckFile(dest, "message to new base, child - should only appear on STDERR not on the file", false);
-
-  // Release
-  LogToStderr();
-  DeleteFiles(dest + "*");
-#endif
-}
-
-static void TestSymlink() {
-#ifndef GLOG_OS_WINDOWS
-  fprintf(stderr, "==== Test setting log file symlink\n");
-  string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
-  string sym = FLAGS_test_tmpdir + "/symlinkbase";
-  DeleteFiles(dest + "*");
-  DeleteFiles(sym + "*");
-
-  SetLogSymlink(GLOG_INFO, "symlinkbase");
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  LOG(INFO) << "message to new symlink";
-  FlushLogFiles(GLOG_INFO);
-  CheckFile(sym, "message to new symlink");
-
-  DeleteFiles(dest + "*");
-  DeleteFiles(sym + "*");
-#endif
-}
-
-static void TestExtension() {
-  fprintf(stderr, "==== Test setting log file extension\n");
-  string dest = FLAGS_test_tmpdir + "/logging_test_extension";
-  DeleteFiles(dest + "*");
-
-  SetLogDestination(GLOG_INFO, dest.c_str());
-  SetLogFilenameExtension("specialextension");
-  LOG(INFO) << "message to new extension";
-  FlushLogFiles(GLOG_INFO);
-  CheckFile(dest, "message to new extension");
-
-  // Check that file name ends with extension
-  vector<string> filenames;
-  GetFiles(dest + "*", &filenames);
-  CHECK_EQ(filenames.size(), 1UL);
-  CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
-
-  // Release file handle for the destination file to unlock the file in Windows.
-  LogToStderr();
-  DeleteFiles(dest + "*");
-}
-
-struct MyLogger : public base::Logger {
-  string data;
-
-  virtual void Write(bool /* should_flush */,
-                     time_t /* timestamp */,
-                     const char* message,
-                     size_t length) {
-    data.append(message, length);
-  }
-
-  virtual void Flush() { }
-
-  virtual uint32 LogSize() { return data.length(); }
-};
-
-static void TestWrapper() {
-  fprintf(stderr, "==== Test log wrapper\n");
-
-  MyLogger my_logger;
-  base::Logger* old_logger = base::GetLogger(GLOG_INFO);
-  base::SetLogger(GLOG_INFO, &my_logger);
-  LOG(INFO) << "Send to wrapped logger";
-  FlushLogFiles(GLOG_INFO);
-  base::SetLogger(GLOG_INFO, old_logger);
-
-  CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
-}
-
-static void TestErrno() {
-  fprintf(stderr, "==== Test errno preservation\n");
-
-  errno = ENOENT;
-  TestLogging(false);
-  CHECK_EQ(errno, ENOENT);
-}
-
-static void TestOneTruncate(const char *path, uint64 limit, uint64 keep,
-                            size_t dsize, size_t ksize, size_t expect) {
-  int fd;
-  CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
-
-  const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
-  const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr);
-
-  // Fill the file with the requested data; first discard data, then kept data
-  size_t written = 0;
-  while (written < dsize) {
-    size_t bytes = min(dsize - written, discard_size);
-    CHECK_ERR(write(fd, discardstr, bytes));
-    written += bytes;
-  }
-  written = 0;
-  while (written < ksize) {
-    size_t bytes = min(ksize - written, keep_size);
-    CHECK_ERR(write(fd, keepstr, bytes));
-    written += bytes;
-  }
-
-  TruncateLogFile(path, limit, keep);
-
-  // File should now be shorter
-  struct stat statbuf;
-  CHECK_ERR(fstat(fd, &statbuf));
-  CHECK_EQ(static_cast<size_t>(statbuf.st_size), expect);
-  CHECK_ERR(lseek(fd, 0, SEEK_SET));
-
-  // File should contain the suffix of the original file
-  const size_t buf_size = static_cast<size_t>(statbuf.st_size) + 1;
-  char* buf = new char[buf_size];
-  memset(buf, 0, buf_size);
-  CHECK_ERR(read(fd, buf, buf_size));
-
-  const char* p = buf;
-  size_t checked = 0;
-  while (checked < expect) {
-    size_t bytes = min(expect - checked, keep_size);
-    CHECK(!memcmp(p, keepstr, bytes));
-    checked += bytes;
-  }
-  close(fd);
-  delete[] buf;
-}
-
-static void TestTruncate() {
-#ifdef HAVE_UNISTD_H
-  fprintf(stderr, "==== Test log truncation\n");
-  string path = FLAGS_test_tmpdir + "/truncatefile";
-
-  // Test on a small file
-  TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
-
-  // And a big file (multiple blocks to copy)
-  TestOneTruncate(path.c_str(), 2U << 20U, 4U << 10U, 3U << 20U, 4U << 10U,
-                  4U << 10U);
-
-  // Check edge-case limits
-  TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
-  TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
-  TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
-  TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
-
-  // MacOSX 10.4 doesn't fail in this case.
-  // Windows doesn't have symlink.
-  // Let's just ignore this test for these cases.
-#if !defined(GLOG_OS_MACOSX) && !defined(GLOG_OS_WINDOWS)
-  // Through a symlink should fail to truncate
-  string linkname = path + ".link";
-  unlink(linkname.c_str());
-  CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
-  TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
-#endif
-
-  // The /proc/self path makes sense only for linux.
-#if defined(GLOG_OS_LINUX)
-  // Through an open fd symlink should work
-  int fd;
-  CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
-  char fdpath[64];
-  snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
-  TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
-#endif
-
-#endif
-}
-
-struct RecordDeletionLogger : public base::Logger {
-  RecordDeletionLogger(bool* set_on_destruction,
-                       base::Logger* wrapped_logger) :
-      set_on_destruction_(set_on_destruction),
-      wrapped_logger_(wrapped_logger)
-  {
-    *set_on_destruction_ = false;
-  }
-  virtual ~RecordDeletionLogger() {
-    *set_on_destruction_ = true;
-  }
-  virtual void Write(bool force_flush,
-                     time_t timestamp,
-                     const char* message,
-                     size_t length) {
-    wrapped_logger_->Write(force_flush, timestamp, message, length);
-  }
-  virtual void Flush() { wrapped_logger_->Flush(); }
-  virtual uint32 LogSize() { return wrapped_logger_->LogSize(); }
- private:
-  bool* set_on_destruction_;
-  base::Logger* wrapped_logger_;
-};
-
-static void TestCustomLoggerDeletionOnShutdown() {
-  bool custom_logger_deleted = false;
-  base::SetLogger(GLOG_INFO,
-                  new RecordDeletionLogger(&custom_logger_deleted,
-                                           base::GetLogger(GLOG_INFO)));
-  EXPECT_TRUE(IsGoogleLoggingInitialized());
-  ShutdownGoogleLogging();
-  EXPECT_TRUE(custom_logger_deleted);
-  EXPECT_FALSE(IsGoogleLoggingInitialized());
-}
-
-namespace LogTimes {
-// Log a "message" every 10ms, 10 times. These numbers are nice compromise
-// between total running time of 100ms and the period of 10ms. The period is
-// large enough such that any CPU and OS scheduling variation shouldn't affect
-// the results from the ideal case by more than 5% (500us or 0.5ms)
-GLOG_CONSTEXPR int64_t LOG_PERIOD_NS     = 10000000;  // 10ms
-GLOG_CONSTEXPR int64_t LOG_PERIOD_TOL_NS = 500000;    // 500us
-
-// Set an upper limit for the number of times the stream operator can be
-// called. Make sure not to exceed this number of times the stream operator is
-// called, since it is also the array size and will be indexed by the stream
-// operator.
-GLOG_CONSTEXPR size_t MAX_CALLS = 10;
-}  // namespace LogTimes
-
-#if defined(HAVE_CXX11_CHRONO) && __cplusplus >= 201103L
-struct LogTimeRecorder {
-  LogTimeRecorder() : m_streamTimes(0) {}
-  size_t m_streamTimes;
-  std::chrono::steady_clock::time_point m_callTimes[LogTimes::MAX_CALLS];
-};
-// The stream operator is called by LOG_EVERY_T every time a logging event
-// occurs. Make sure to save the times for each call as they will be used later
-// to verify the time delta between each call.
-std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
-  t.m_callTimes[t.m_streamTimes++] = std::chrono::steady_clock::now();
-  return stream;
-}
-// get elapsed time in nanoseconds
-int64 elapsedTime_ns(const std::chrono::steady_clock::time_point& begin,
-        const std::chrono::steady_clock::time_point& end) {
-  return std::chrono::duration_cast<std::chrono::nanoseconds>((end - begin))
-          .count();
-}
-#elif defined(GLOG_OS_WINDOWS)
-struct LogTimeRecorder {
-  LogTimeRecorder() : m_streamTimes(0) {}
-  size_t m_streamTimes;
-  LARGE_INTEGER m_callTimes[LogTimes::MAX_CALLS];
-};
-std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
-  QueryPerformanceCounter(&t.m_callTimes[t.m_streamTimes++]);
-  return stream;
-}
-// get elapsed time in nanoseconds
-int64 elapsedTime_ns(const LARGE_INTEGER& begin, const LARGE_INTEGER& end) {
-  LARGE_INTEGER freq;
-  QueryPerformanceFrequency(&freq);
-  return (end.QuadPart - begin.QuadPart) * LONGLONG(1000000000) / freq.QuadPart;
-}
-#else
-struct LogTimeRecorder {
-  LogTimeRecorder() : m_streamTimes(0) {}
-  size_t m_streamTimes;
-  timespec m_callTimes[LogTimes::MAX_CALLS];
-};
-std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
-  clock_gettime(CLOCK_MONOTONIC, &t.m_callTimes[t.m_streamTimes++]);
-  return stream;
-}
-// get elapsed time in nanoseconds
-int64 elapsedTime_ns(const timespec& begin, const timespec& end) {
-  return (end.tv_sec - begin.tv_sec) * 1000000000 +
-         (end.tv_nsec - begin.tv_nsec);
-}
-#endif
-
-static void TestLogPeriodically() {
-  fprintf(stderr, "==== Test log periodically\n");
-
-  LogTimeRecorder timeLogger;
-
-  GLOG_CONSTEXPR double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9;
-
-  while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) {
-      LOG_EVERY_T(INFO, LOG_PERIOD_SEC)
-          << timeLogger << "Timed Message #" << timeLogger.m_streamTimes;
-  }
-
-  // Calculate time between each call in nanoseconds for higher resolution to
-  // minimize error.
-  int64 nsBetweenCalls[LogTimes::MAX_CALLS - 1];
-  for (size_t i = 1; i < LogTimes::MAX_CALLS; ++i) {
-    nsBetweenCalls[i - 1] = elapsedTime_ns(
-            timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]);
-  }
-
-  for (size_t idx = 0; idx < LogTimes::MAX_CALLS - 1; ++idx) {
-    int64 time_ns = nsBetweenCalls[idx];
-    EXPECT_NEAR(time_ns, LogTimes::LOG_PERIOD_NS, LogTimes::LOG_PERIOD_TOL_NS);
-  }
-}
-
-_START_GOOGLE_NAMESPACE_
-namespace glog_internal_namespace_ {
-extern  // in logging.cc
-bool SafeFNMatch_(const char* pattern, size_t patt_len,
-                  const char* str, size_t str_len);
-} // namespace glog_internal_namespace_
-using glog_internal_namespace_::SafeFNMatch_;
-_END_GOOGLE_NAMESPACE_
-
-static bool WrapSafeFNMatch(string pattern, string str) {
-  pattern += "abc";
-  str += "defgh";
-  return SafeFNMatch_(pattern.data(), pattern.size() - 3,
-                      str.data(), str.size() - 5);
-}
-
-TEST(SafeFNMatch, logging) {
-  CHECK(WrapSafeFNMatch("foo", "foo"));
-  CHECK(!WrapSafeFNMatch("foo", "bar"));
-  CHECK(!WrapSafeFNMatch("foo", "fo"));
-  CHECK(!WrapSafeFNMatch("foo", "foo2"));
-  CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
-  CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
-  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
-  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
-  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
-  CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
-  CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
-  CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
-  CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
-  CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
-  CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
-  CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
-  CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
-}
-
-// TestWaitingLogSink will save messages here
-// No lock: Accessed only by TestLogSinkWriter thread
-// and after its demise by its creator.
-static vector<string> global_messages;
-
-// helper for TestWaitingLogSink below.
-// Thread that does the logic of TestWaitingLogSink
-// It's free to use LOG() itself.
-class TestLogSinkWriter : public Thread {
- public:
-
-  TestLogSinkWriter() : should_exit_(false) {
-    SetJoinable(true);
-    Start();
-  }
-
-  // Just buffer it (can't use LOG() here).
-  void Buffer(const string& message) {
-    mutex_.Lock();
-    RAW_LOG(INFO, "Buffering");
-    messages_.push(message);
-    mutex_.Unlock();
-    RAW_LOG(INFO, "Buffered");
-  }
-
-  // Wait for the buffer to clear (can't use LOG() here).
-  void Wait() {
-    RAW_LOG(INFO, "Waiting");
-    mutex_.Lock();
-    while (!NoWork()) {
-      mutex_.Unlock();
-      SleepForMilliseconds(1);
-      mutex_.Lock();
-    }
-    RAW_LOG(INFO, "Waited");
-    mutex_.Unlock();
-  }
-
-  // Trigger thread exit.
-  void Stop() {
-    MutexLock l(&mutex_);
-    should_exit_ = true;
-  }
-
- private:
-
-  // helpers ---------------
-
-  // For creating a "Condition".
-  bool NoWork() { return messages_.empty(); }
-  bool HaveWork() { return !messages_.empty() || should_exit_; }
-
-  // Thread body; CAN use LOG() here!
-  virtual void Run() {
-    while (1) {
-      mutex_.Lock();
-      while (!HaveWork()) {
-        mutex_.Unlock();
-        SleepForMilliseconds(1);
-        mutex_.Lock();
-      }
-      if (should_exit_ && messages_.empty()) {
-        mutex_.Unlock();
-        break;
-      }
-      // Give the main thread time to log its message,
-      // so that we get a reliable log capture to compare to golden file.
-      // Same for the other sleep below.
-      SleepForMilliseconds(20);
-      RAW_LOG(INFO, "Sink got a messages");  // only RAW_LOG under mutex_ here
-      string message = messages_.front();
-      messages_.pop();
-      // Normally this would be some more real/involved logging logic
-      // where LOG() usage can't be eliminated,
-      // e.g. pushing the message over with an RPC:
-      size_t messages_left = messages_.size();
-      mutex_.Unlock();
-      SleepForMilliseconds(20);
-      // May not use LOG while holding mutex_, because Buffer()
-      // acquires mutex_, and Buffer is called from LOG(),
-      // which has its own internal mutex:
-      // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
-      LOG(INFO) << "Sink is sending out a message: " << message;
-      LOG(INFO) << "Have " << messages_left << " left";
-      global_messages.push_back(message);
-    }
-  }
-
-  // data ---------------
-
-  Mutex mutex_;
-  bool should_exit_;
-  queue<string> messages_;  // messages to be logged
-};
-
-// A log sink that exercises WaitTillSent:
-// it pushes data to a buffer and wakes up another thread to do the logging
-// (that other thread can than use LOG() itself),
-class TestWaitingLogSink : public LogSink {
- public:
-
-  TestWaitingLogSink() {
-    tid_ = pthread_self();  // for thread-specific behavior
-    AddLogSink(this);
-  }
-  ~TestWaitingLogSink() {
-    RemoveLogSink(this);
-    writer_.Stop();
-    writer_.Join();
-  }
-
-  // (re)define LogSink interface
-
-  virtual void send(LogSeverity severity, const char* /* full_filename */,
-                    const char* base_filename, int line,
-                    const LogMessageTime &logmsgtime,
-                    const char* message, size_t message_len) {
-    // Push it to Writer thread if we are the original logging thread.
-    // Note: Something like ThreadLocalLogSink is a better choice
-    //       to do thread-specific LogSink logic for real.
-    if (pthread_equal(tid_, pthread_self())) {
-      writer_.Buffer(ToString(severity, base_filename, line,
-                              logmsgtime, message, message_len));
-    }
-  }
-
-  virtual void WaitTillSent() {
-    // Wait for Writer thread if we are the original logging thread.
-    if (pthread_equal(tid_, pthread_self()))  writer_.Wait();
-  }
-
- private:
-
-  pthread_t tid_;
-  TestLogSinkWriter writer_;
-};
-
-// Check that LogSink::WaitTillSent can be used in the advertised way.
-// We also do golden-stderr comparison.
-static void TestLogSinkWaitTillSent() {
-  // Clear global_messages here to make sure that this test case can be
-  // reentered
-  global_messages.clear();
-  { TestWaitingLogSink sink;
-    // Sleeps give the sink threads time to do all their work,
-    // so that we get a reliable log capture to compare to the golden file.
-    LOG(INFO) << "Message 1";
-    SleepForMilliseconds(60);
-    LOG(ERROR) << "Message 2";
-    SleepForMilliseconds(60);
-    LOG(WARNING) << "Message 3";
-    SleepForMilliseconds(60);
-  }
-  for (size_t i = 0; i < global_messages.size(); ++i) {
-    LOG(INFO) << "Sink capture: " << global_messages[i];
-  }
-  CHECK_EQ(global_messages.size(), 3UL);
-}
-
-TEST(Strerror, logging) {
-  int errcode = EINTR;
-  char *msg = strdup(strerror(errcode));
-  const size_t buf_size = strlen(msg) + 1;
-  char *buf = new char[buf_size];
-  CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
-  buf[0] = 'A';
-  CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
-  CHECK_EQ(buf[0], 'A');
-  CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
-#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
-  // MacOSX or FreeBSD considers this case is an error since there is
-  // no enough space.
-  CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
-#else
-  CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
-#endif
-  CHECK_STREQ(buf, "");
-  CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
-  CHECK_STREQ(buf, msg);
-  delete[] buf;
-  CHECK_EQ(msg, StrError(errcode));
-  free(msg);
-}
-
-// Simple routines to look at the sizes of generated code for LOG(FATAL) and
-// CHECK(..) via objdump
-/*
-static void MyFatal() {
-  LOG(FATAL) << "Failed";
-}
-static void MyCheck(bool a, bool b) {
-  CHECK_EQ(a, b);
-}
-*/
-#ifdef HAVE_LIB_GMOCK
-
-TEST(DVLog, Basic) {
-  ScopedMockLog log;
-
-#if defined(NDEBUG)
-  // We are expecting that nothing is logged.
-  EXPECT_CALL(log, Log(_, _, _)).Times(0);
-#else
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "debug log"));
-#endif
-
-  FLAGS_v = 1;
-  DVLOG(1) << "debug log";
-}
-
-TEST(DVLog, V0) {
-  ScopedMockLog log;
-
-  // We are expecting that nothing is logged.
-  EXPECT_CALL(log, Log(_, _, _)).Times(0);
-
-  FLAGS_v = 0;
-  DVLOG(1) << "debug log";
-}
-
-TEST(LogAtLevel, Basic) {
-  ScopedMockLog log;
-
-  // The function version outputs "logging.h" as a file name.
-  EXPECT_CALL(log, Log(GLOG_WARNING, StrNe(__FILE__), "function version"));
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "macro version"));
-
-  int severity = GLOG_WARNING;
-  LogAtLevel(severity, "function version");
-
-  severity = GLOG_INFO;
-  // We can use the macro version as a C++ stream.
-  LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
-}
-
-TEST(TestExitOnDFatal, ToBeOrNotToBe) {
-  // Check the default setting...
-  EXPECT_TRUE(base::internal::GetExitOnDFatal());
-
-  // Turn off...
-  base::internal::SetExitOnDFatal(false);
-  EXPECT_FALSE(base::internal::GetExitOnDFatal());
-
-  // We don't die.
-  {
-    ScopedMockLog log;
-    //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
-    // LOG(DFATAL) has severity FATAL if debugging, but is
-    // downgraded to ERROR if not debugging.
-    const LogSeverity severity =
-#if defined(NDEBUG)
-        GLOG_ERROR;
-#else
-        GLOG_FATAL;
-#endif
-    EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
-    LOG(DFATAL) << "This should not be fatal";
-  }
-
-  // Turn back on...
-  base::internal::SetExitOnDFatal(true);
-  EXPECT_TRUE(base::internal::GetExitOnDFatal());
-
-#ifdef GTEST_HAS_DEATH_TEST
-  // Death comes on little cats' feet.
-  EXPECT_DEBUG_DEATH({
-      LOG(DFATAL) << "This should be fatal in debug mode";
-    }, "This should be fatal in debug mode");
-#endif
-}
-
-#ifdef HAVE_STACKTRACE
-
-static void BacktraceAtHelper() {
-  LOG(INFO) << "Not me";
-
-// The vertical spacing of the next 3 lines is significant.
-  LOG(INFO) << "Backtrace me";
-}
-static int kBacktraceAtLine = __LINE__ - 2;  // The line of the LOG(INFO) above
-
-TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
-  StrictMock<ScopedMockLog> log;
-
-  FLAGS_log_backtrace_at = "";
-
-  EXPECT_CALL(log, Log(_, _, "Backtrace me"));
-  EXPECT_CALL(log, Log(_, _, "Not me"));
-
-  BacktraceAtHelper();
-}
-
-TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
-  StrictMock<ScopedMockLog> log;
-
-  char where[100];
-  snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
-  FLAGS_log_backtrace_at = where;
-
-  // The LOG at the specified line should include a stacktrace which includes
-  // the name of the containing function, followed by the log message.
-  // We use HasSubstr()s instead of ContainsRegex() for environments
-  // which don't have regexp.
-  EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
-                                   HasSubstr("BacktraceAtHelper"),
-                                   HasSubstr("main"),
-                                   HasSubstr("Backtrace me"))));
-  // Other LOGs should not include a backtrace.
-  EXPECT_CALL(log, Log(_, _, "Not me"));
-
-  BacktraceAtHelper();
-}
-
-#endif // HAVE_STACKTRACE
-
-#endif // HAVE_LIB_GMOCK
-
-struct UserDefinedClass {
-  bool operator==(const UserDefinedClass&) const { return true; }
-};
-
-inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
-  out << "OK";
-  return out;
-}
-
-TEST(UserDefinedClass, logging) {
-  UserDefinedClass u;
-  vector<string> buf;
-  LOG_STRING(INFO, &buf) << u;
-  CHECK_EQ(1UL, buf.size());
-  CHECK(buf[0].find("OK") != string::npos);
-
-  // We must be able to compile this.
-  CHECK_EQ(u, u);
-}
diff --git a/third_party/google-glog/src/logging_unittest.err b/third_party/google-glog/src/logging_unittest.err
deleted file mode 100644
index 21517cb..0000000
--- a/third_party/google-glog/src/logging_unittest.err
+++ /dev/null
@@ -1,308 +0,0 @@
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-WARNING: Logging before InitGoogleLogging() is written to STDERR
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo bar 10 3.4
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0]
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 1
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 1
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 1
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 2
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2]
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 3
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 3
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 4
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 4
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4]
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 5
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 5
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 6
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 6
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6]
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 7
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 7
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 8
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8]
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 9
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 9
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 10
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 10
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] array
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] const array
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000       1000 3e8
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo          1
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] inner
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] outer
-no prefix
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: const array
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __PTRTEST__
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __NULLP__
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 on
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 on
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 2 on
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected warning
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK:
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
diff --git a/third_party/google-glog/src/logging_unittest.out b/third_party/google-glog/src/logging_unittest.out
deleted file mode 100644
index 18795e1..0000000
--- a/third_party/google-glog/src/logging_unittest.out
+++ /dev/null
@@ -1,150 +0,0 @@
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected warning
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK:
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
-EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
-WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
-IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
diff --git a/third_party/google-glog/src/mock-log.h b/third_party/google-glog/src/mock-log.h
deleted file mode 100644
index bdfb3c5..0000000
--- a/third_party/google-glog/src/mock-log.h
+++ /dev/null
@@ -1,156 +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: Zhanyong Wan
-//
-// Defines the ScopedMockLog class (using Google C++ Mocking
-// Framework), which is convenient for testing code that uses LOG().
-
-#ifndef GLOG_SRC_MOCK_LOG_H_
-#define GLOG_SRC_MOCK_LOG_H_
-
-// For GOOGLE_NAMESPACE. This must go first so we get _XOPEN_SOURCE.
-#include "utilities.h"
-
-#include <string>
-
-#include <gmock/gmock.h>
-
-#include <glog/logging.h>
-
-_START_GOOGLE_NAMESPACE_
-namespace glog_testing {
-
-// A ScopedMockLog object intercepts LOG() messages issued during its
-// lifespan.  Using this together with Google C++ Mocking Framework,
-// it's very easy to test how a piece of code calls LOG().  The
-// typical usage:
-//
-//   TEST(FooTest, LogsCorrectly) {
-//     ScopedMockLog log;
-//
-//     // We expect the WARNING "Something bad!" exactly twice.
-//     EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
-//         .Times(2);
-//
-//     // We allow foo.cc to call LOG(INFO) any number of times.
-//     EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
-//         .Times(AnyNumber());
-//
-//     Foo();  // Exercises the code under test.
-//   }
-class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
- public:
-  // When a ScopedMockLog object is constructed, it starts to
-  // intercept logs.
-  ScopedMockLog() { AddLogSink(this); }
-
-  // When the object is destructed, it stops intercepting logs.
-  ~ScopedMockLog() { RemoveLogSink(this); }
-
-  // Implements the mock method:
-  //
-  //   void Log(LogSeverity severity, const string& file_path,
-  //            const string& message);
-  //
-  // The second argument to Send() is the full path of the source file
-  // in which the LOG() was issued.
-  //
-  // Note, that in a multi-threaded environment, all LOG() messages from a
-  // single thread will be handled in sequence, but that cannot be guaranteed
-  // for messages from different threads. In fact, if the same or multiple
-  // expectations are matched on two threads concurrently, their actions will
-  // be executed concurrently as well and may interleave.
-  MOCK_METHOD3(Log, void(GOOGLE_NAMESPACE::LogSeverity severity,
-                         const std::string& file_path,
-                         const std::string& message));
-
- private:
-  // Implements the send() virtual function in class LogSink.
-  // Whenever a LOG() statement is executed, this function will be
-  // invoked with information presented in the LOG().
-  //
-  // The method argument list is long and carries much information a
-  // test usually doesn't care about, so we trim the list before
-  // forwarding the call to Log(), which is much easier to use in
-  // tests.
-  //
-  // We still cannot call Log() directly, as it may invoke other LOG()
-  // messages, either due to Invoke, or due to an error logged in
-  // Google C++ Mocking Framework code, which would trigger a deadlock
-  // since a lock is held during send().
-  //
-  // Hence, we save the message for WaitTillSent() which will be called after
-  // the lock on send() is released, and we'll call Log() inside
-  // WaitTillSent(). Since while a single send() call may be running at a
-  // time, multiple WaitTillSent() calls (along with the one send() call) may
-  // be running simultaneously, we ensure thread-safety of the exchange between
-  // send() and WaitTillSent(), and that for each message, LOG(), send(),
-  // WaitTillSent() and Log() are executed in the same thread.
-  virtual void send(GOOGLE_NAMESPACE::LogSeverity severity,
-                    const char* full_filename,
-                    const char* /*base_filename*/, int /*line*/,
-                    const LogMessageTime & /*logmsgtime*/,
-                    const char* message, size_t message_len) {
-    // We are only interested in the log severity, full file name, and
-    // log message.
-    message_info_.severity = severity;
-    message_info_.file_path = full_filename;
-    message_info_.message = std::string(message, message_len);
-  }
-
-  // Implements the WaitTillSent() virtual function in class LogSink.
-  // It will be executed after send() and after the global logging lock is
-  // released, so calls within it (or rather within the Log() method called
-  // within) may also issue LOG() statements.
-  //
-  // LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
-  // a given log message.
-  virtual void WaitTillSent() {
-    // First, and very importantly, we save a copy of the message being
-    // processed before calling Log(), since Log() may indirectly call send()
-    // and WaitTillSent() in the same thread again.
-    MessageInfo message_info = message_info_;
-    Log(message_info.severity, message_info.file_path, message_info.message);
-  }
-
-  // All relevant information about a logged message that needs to be passed
-  // from send() to WaitTillSent().
-  struct MessageInfo {
-    GOOGLE_NAMESPACE::LogSeverity severity;
-    std::string file_path;
-    std::string message;
-  };
-  MessageInfo message_info_;
-};
-
-}  // namespace glog_testing
-_END_GOOGLE_NAMESPACE_
-
-#endif  // GLOG_SRC_MOCK_LOG_H_
diff --git a/third_party/google-glog/src/mock-log_unittest.cc b/third_party/google-glog/src/mock-log_unittest.cc
deleted file mode 100644
index b9bef4e..0000000
--- a/third_party/google-glog/src/mock-log_unittest.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2022, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Zhanyong Wan
-
-// Tests the ScopedMockLog class.
-
-#include "mock-log.h"
-
-#include <string>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace {
-
-using GOOGLE_NAMESPACE::GLOG_ERROR;
-using GOOGLE_NAMESPACE::GLOG_INFO;
-using GOOGLE_NAMESPACE::GLOG_WARNING;
-using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
-using std::string;
-using testing::_;
-using testing::EndsWith;
-using testing::InSequence;
-using testing::InvokeWithoutArgs;
-
-// Tests that ScopedMockLog intercepts LOG()s when it's alive.
-TEST(ScopedMockLogTest, InterceptsLog) {
-  ScopedMockLog log;
-
-  InSequence s;
-  EXPECT_CALL(log,
-              Log(GLOG_WARNING, EndsWith("mock-log_unittest.cc"), "Fishy."));
-  EXPECT_CALL(log, Log(GLOG_INFO, _, "Working..."))
-      .Times(2);
-  EXPECT_CALL(log, Log(GLOG_ERROR, _, "Bad!!"));
-
-  LOG(WARNING) << "Fishy.";
-  LOG(INFO) << "Working...";
-  LOG(INFO) << "Working...";
-  LOG(ERROR) << "Bad!!";
-}
-
-void LogBranch() {
-  LOG(INFO) << "Logging a branch...";
-}
-
-void LogTree() {
-  LOG(INFO) << "Logging the whole tree...";
-}
-
-void LogForest() {
-  LOG(INFO) << "Logging the entire forest.";
-  LOG(INFO) << "Logging the entire forest..";
-  LOG(INFO) << "Logging the entire forest...";
-}
-
-// The purpose of the following test is to verify that intercepting logging
-// continues to work properly if a LOG statement is executed within the scope
-// of a mocked call.
-TEST(ScopedMockLogTest, LogDuringIntercept) {
-  ScopedMockLog log;
-  InSequence s;
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging a branch..."))
-      .WillOnce(InvokeWithoutArgs(LogTree));
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the whole tree..."))
-      .WillOnce(InvokeWithoutArgs(LogForest));
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest."));
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest.."));
-  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest..."));
-  LogBranch();
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  GOOGLE_NAMESPACE::InitGoogleLogging(argv[0]);
-  testing::InitGoogleTest(&argc, argv);
-  testing::InitGoogleMock(&argc, argv);
-
-  return RUN_ALL_TESTS();
-}
diff --git a/third_party/google-glog/src/package_config_unittest/working_config/CMakeLists.txt b/third_party/google-glog/src/package_config_unittest/working_config/CMakeLists.txt
deleted file mode 100644
index 5fcfe7f..0000000
--- a/third_party/google-glog/src/package_config_unittest/working_config/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-cmake_minimum_required (VERSION 3.16)
-project (glog_package_config LANGUAGES CXX)
-
-find_package (glog REQUIRED NO_MODULE)
-
-add_executable (glog_package_config glog_package_config.cc)
-
-target_link_libraries (glog_package_config PRIVATE glog::glog)
diff --git a/third_party/google-glog/src/package_config_unittest/working_config/glog_package_config.cc b/third_party/google-glog/src/package_config_unittest/working_config/glog_package_config.cc
deleted file mode 100644
index b7b5cf6..0000000
--- a/third_party/google-glog/src/package_config_unittest/working_config/glog_package_config.cc
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <glog/logging.h>
-
-int main(int /*argc*/, char** argv)
-{
-    google::InitGoogleLogging(argv[0]);
-}
diff --git a/third_party/google-glog/src/raw_logging.cc b/third_party/google-glog/src/raw_logging.cc
deleted file mode 100644
index be02981..0000000
--- a/third_party/google-glog/src/raw_logging.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// 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
-//
-// logging_unittest.cc covers the functionality herein
-
-#include "utilities.h"
-
-#include <stdarg.h>
-#include <cstdio>
-#include <cerrno>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>               // for close() and write()
-#endif
-#include <fcntl.h>                 // for open()
-#include <ctime>
-#include "config.h"
-#include <glog/logging.h>          // To pick up flag settings etc.
-#include <glog/raw_logging.h>
-#include "base/commandlineflags.h"
-
-#ifdef HAVE_STACKTRACE
-# include "stacktrace.h"
-#endif
-
-#if defined(HAVE_SYSCALL_H)
-#include <syscall.h>                 // for syscall()
-#elif defined(HAVE_SYS_SYSCALL_H)
-#include <sys/syscall.h>                 // for syscall()
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#if (defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)) && \
-    (!(defined(GLOG_OS_MACOSX))) && !defined(GLOG_OS_EMSCRIPTEN)
-#define safe_write(fd, s, len) syscall(SYS_write, fd, s, len)
-#else
-// Not so safe, but what can you do?
-#define safe_write(fd, s, len) write(fd, s, len)
-#endif
-
-namespace aos {
-void FatalUnsetRealtimePriority() __attribute__((weak));
-}
-
-static void MaybeUnsetRealtime() {
-  if (&aos::FatalUnsetRealtimePriority != nullptr) {
-    aos::FatalUnsetRealtimePriority();
-  }
-}
-
-_START_GOOGLE_NAMESPACE_
-
-#if defined(__GNUC__)
-#define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck) \
-  __attribute__((format(archetype, stringIndex, firstToCheck)))
-#define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex) \
-  __attribute__((format_arg(stringIndex)))
-#else
-#define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck)
-#define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex)
-#endif
-
-// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
-// that invoke malloc() and getenv() that might acquire some locks.
-// If this becomes a problem we should reimplement a subset of vsnprintf
-// that does not need locks and malloc.
-
-// Helper for RawLog__ below.
-// *DoRawLog writes to *buf of *size and move them past the written portion.
-// It returns true iff there was no overflow or error.
-GLOG_ATTRIBUTE_FORMAT(printf, 3, 4)
-static bool DoRawLog(char** buf, size_t* size, const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  int n = vsnprintf(*buf, *size, format, ap);
-  va_end(ap);
-  if (n < 0 || static_cast<size_t>(n) > *size) return false;
-  *size -= static_cast<size_t>(n);
-  *buf += n;
-  return true;
-}
-
-// Helper for RawLog__ below.
-inline static bool VADoRawLog(char** buf, size_t* size,
-                              const char* format, va_list ap) {
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
-#endif
-  int n = vsnprintf(*buf, *size, format, ap);
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-  if (n < 0 || static_cast<size_t>(n) > *size) return false;
-  *size -= static_cast<size_t>(n);
-  *buf += n;
-  return true;
-}
-
-static const int kLogBufSize = 3000;
-static bool crashed = false;
-static CrashReason crash_reason;
-static char crash_buf[kLogBufSize + 1] = { 0 };  // Will end in '\0'
-
-GLOG_ATTRIBUTE_FORMAT(printf, 4, 5)
-void RawLog__(LogSeverity severity, const char* file, int line,
-              const char* format, ...) {
-  if (!(FLAGS_logtostdout || FLAGS_logtostderr ||
-        severity >= FLAGS_stderrthreshold || FLAGS_alsologtostderr ||
-        !IsGoogleLoggingInitialized())) {
-    return;  // this stderr log message is suppressed
-  }
-  // can't call localtime_r here: it can allocate
-  char buffer[kLogBufSize];
-  char* buf = buffer;
-  size_t size = sizeof(buffer);
-
-  // NOTE: this format should match the specification in base/logging.h
-  DoRawLog(&buf, &size, "%c00000000 00:00:00.000000 %5u %s:%d] RAW: ",
-           LogSeverityNames[severity][0],
-           static_cast<unsigned int>(GetTID()),
-           const_basename(const_cast<char *>(file)), line);
-
-  // Record the position and size of the buffer after the prefix
-  const char* msg_start = buf;
-  const size_t msg_size = size;
-
-  va_list ap;
-  va_start(ap, format);
-  bool no_chop = VADoRawLog(&buf, &size, format, ap);
-  va_end(ap);
-  if (no_chop) {
-    DoRawLog(&buf, &size, "\n");
-  } else {
-    DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n");
-  }
-  // We make a raw syscall to write directly to the stderr file descriptor,
-  // avoiding FILE buffering (to avoid invoking malloc()), and bypassing
-  // libc (to side-step any libc interception).
-  // We write just once to avoid races with other invocations of RawLog__.
-  safe_write(STDERR_FILENO, buffer, strlen(buffer));
-  if (severity == GLOG_FATAL)  {
-    MaybeUnsetRealtime();
-    if (!sync_val_compare_and_swap(&crashed, false, true)) {
-      crash_reason.filename = file;
-      crash_reason.line_number = line;
-      memcpy(crash_buf, msg_start, msg_size);  // Don't include prefix
-      crash_reason.message = crash_buf;
-#ifdef HAVE_STACKTRACE
-      crash_reason.depth =
-          GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1);
-#else
-      crash_reason.depth = 0;
-#endif
-      SetCrashReason(&crash_reason);
-    }
-    LogMessage::Fail();  // abort()
-  }
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/signalhandler.cc b/third_party/google-glog/src/signalhandler.cc
deleted file mode 100644
index 5e43fa3..0000000
--- a/third_party/google-glog/src/signalhandler.cc
+++ /dev/null
@@ -1,427 +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: Satoru Takabayashi
-//
-// Implementation of InstallFailureSignalHandler().
-
-#include "utilities.h"
-#include "stacktrace.h"
-#include "symbolize.h"
-#include <glog/logging.h>
-
-#include <csignal>
-#include <ctime>
-#ifdef HAVE_UCONTEXT_H
-# include <ucontext.h>
-#endif
-#ifdef HAVE_SYS_UCONTEXT_H
-# include <sys/ucontext.h>
-#endif
-#include <algorithm>
-
-namespace aos {
-void FatalUnsetRealtimePriority() __attribute__((weak));
-}
-
-_START_GOOGLE_NAMESPACE_
-
-namespace {
-
-void MaybeUnsetRealtime() {
-  if (&aos::FatalUnsetRealtimePriority != nullptr) {
-    aos::FatalUnsetRealtimePriority();
-  }
-}
-
-// We'll install the failure signal handler for these signals.  We could
-// use strsignal() to get signal names, but we don't use it to avoid
-// introducing yet another #ifdef complication.
-//
-// The list should be synced with the comment in signalhandler.h.
-const struct {
-  int number;
-  const char *name;
-} kFailureSignals[] = {
-  { SIGSEGV, "SIGSEGV" },
-  { SIGILL, "SIGILL" },
-  { SIGFPE, "SIGFPE" },
-  { SIGABRT, "SIGABRT" },
-#if !defined(GLOG_OS_WINDOWS)
-  { SIGBUS, "SIGBUS" },
-#endif
-  { SIGTERM, "SIGTERM" },
-};
-
-static bool kFailureSignalHandlerInstalled = false;
-
-#if !defined(GLOG_OS_WINDOWS)
-// Returns the program counter from signal context, NULL if unknown.
-void* GetPC(void* ucontext_in_void) {
-#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
-  if (ucontext_in_void != NULL) {
-    ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
-    return (void*)context->PC_FROM_UCONTEXT;
-  }
-#else
-  (void)ucontext_in_void;
-#endif
-  return NULL;
-}
-#endif
-
-// The class is used for formatting error messages.  We don't use printf()
-// as it's not async signal safe.
-class MinimalFormatter {
- public:
-  MinimalFormatter(char *buffer, size_t size)
-      : buffer_(buffer),
-        cursor_(buffer),
-        end_(buffer + size) {
-  }
-
-  // Returns the number of bytes written in the buffer.
-  std::size_t num_bytes_written() const { return static_cast<std::size_t>(cursor_ - buffer_); }
-
-  // Appends string from "str" and updates the internal cursor.
-  void AppendString(const char* str) {
-    ptrdiff_t i = 0;
-    while (str[i] != '\0' && cursor_ + i < end_) {
-      cursor_[i] = str[i];
-      ++i;
-    }
-    cursor_ += i;
-  }
-
-  // Formats "number" in "radix" and updates the internal cursor.
-  // Lowercase letters are used for 'a' - 'z'.
-  void AppendUint64(uint64 number, unsigned radix) {
-    unsigned i = 0;
-    while (cursor_ + i < end_) {
-      const uint64 tmp = number % radix;
-      number /= radix;
-      cursor_[i] = static_cast<char>(tmp < 10 ? '0' + tmp : 'a' + tmp - 10);
-      ++i;
-      if (number == 0) {
-        break;
-      }
-    }
-    // Reverse the bytes written.
-    std::reverse(cursor_, cursor_ + i);
-    cursor_ += i;
-  }
-
-  // Formats "number" as hexadecimal number, and updates the internal
-  // cursor.  Padding will be added in front if needed.
-  void AppendHexWithPadding(uint64 number, int width) {
-    char* start = cursor_;
-    AppendString("0x");
-    AppendUint64(number, 16);
-    // Move to right and add padding in front if needed.
-    if (cursor_ < start + width) {
-      const int64 delta = start + width - cursor_;
-      std::copy(start, cursor_, start + delta);
-      std::fill(start, start + delta, ' ');
-      cursor_ = start + width;
-    }
-  }
-
- private:
-  char *buffer_;
-  char *cursor_;
-  const char * const end_;
-};
-
-// Writes the given data with the size to the standard error.
-void WriteToStderr(const char* data, size_t size) {
-  if (write(STDERR_FILENO, data, size) < 0) {
-    // Ignore errors.
-  }
-}
-
-// The writer function can be changed by InstallFailureWriter().
-void (*g_failure_writer)(const char* data, size_t size) = WriteToStderr;
-
-// Dumps time information.  We don't dump human-readable time information
-// as localtime() is not guaranteed to be async signal safe.
-void DumpTimeInfo() {
-  time_t time_in_sec = time(NULL);
-  char buf[256];  // Big enough for time info.
-  MinimalFormatter formatter(buf, sizeof(buf));
-  formatter.AppendString("*** Aborted at ");
-  formatter.AppendUint64(static_cast<uint64>(time_in_sec), 10);
-  formatter.AppendString(" (unix time)");
-  formatter.AppendString(" try \"date -d @");
-  formatter.AppendUint64(static_cast<uint64>(time_in_sec), 10);
-  formatter.AppendString("\" if you are using GNU date ***\n");
-  g_failure_writer(buf, formatter.num_bytes_written());
-}
-
-// TODO(hamaji): Use signal instead of sigaction?
-#if defined(HAVE_STACKTRACE) && defined(HAVE_SIGACTION)
-
-// Dumps information about the signal to STDERR.
-void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
-  // Get the signal name.
-  const char* signal_name = NULL;
-  for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
-    if (signal_number == kFailureSignals[i].number) {
-      signal_name = kFailureSignals[i].name;
-    }
-  }
-
-  char buf[256];  // Big enough for signal info.
-  MinimalFormatter formatter(buf, sizeof(buf));
-
-  formatter.AppendString("*** ");
-  if (signal_name) {
-    formatter.AppendString(signal_name);
-  } else {
-    // Use the signal number if the name is unknown.  The signal name
-    // should be known, but just in case.
-    formatter.AppendString("Signal ");
-    formatter.AppendUint64(static_cast<uint64>(signal_number), 10);
-  }
-  formatter.AppendString(" (@0x");
-  formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16);
-  formatter.AppendString(")");
-  formatter.AppendString(" received by PID ");
-  formatter.AppendUint64(static_cast<uint64>(getpid()), 10);
-  formatter.AppendString(" (TID 0x");
-  // We assume pthread_t is an integral number or a pointer, rather
-  // than a complex struct.  In some environments, pthread_self()
-  // returns an uint64 but in some other environments pthread_self()
-  // returns a pointer.
-  pthread_t id = pthread_self();
-  formatter.AppendUint64(
-      reinterpret_cast<uint64>(reinterpret_cast<const char*>(id)), 16);
-  formatter.AppendString(") ");
-  // Only linux has the PID of the signal sender in si_pid.
-#ifdef GLOG_OS_LINUX
-  formatter.AppendString("from PID ");
-  formatter.AppendUint64(static_cast<uint64>(siginfo->si_pid), 10);
-  formatter.AppendString("; ");
-#endif
-  formatter.AppendString("stack trace: ***\n");
-  g_failure_writer(buf, formatter.num_bytes_written());
-}
-
-#endif  // HAVE_SIGACTION
-
-// Dumps information about the stack frame to STDERR.
-void DumpStackFrameInfo(const char* prefix, void* pc) {
-  // Get the symbol name.
-  const char *symbol = "(unknown)";
-  char symbolized[1024];  // Big enough for a sane symbol.
-  // Symbolizes the previous address of pc because pc may be in the
-  // next function.
-  if (Symbolize(reinterpret_cast<char *>(pc) - 1,
-                symbolized, sizeof(symbolized))) {
-    symbol = symbolized;
-  }
-
-  char buf[1024];  // Big enough for stack frame info.
-  MinimalFormatter formatter(buf, sizeof(buf));
-
-  formatter.AppendString(prefix);
-  formatter.AppendString("@ ");
-  const int width = 2 * sizeof(void*) + 2;  // + 2  for "0x".
-  formatter.AppendHexWithPadding(reinterpret_cast<uintptr_t>(pc), width);
-  formatter.AppendString(" ");
-  formatter.AppendString(symbol);
-  formatter.AppendString("\n");
-  g_failure_writer(buf, formatter.num_bytes_written());
-}
-
-// Invoke the default signal handler.
-void InvokeDefaultSignalHandler(int signal_number) {
-#ifdef HAVE_SIGACTION
-  struct sigaction sig_action;
-  memset(&sig_action, 0, sizeof(sig_action));
-  sigemptyset(&sig_action.sa_mask);
-  sig_action.sa_handler = SIG_DFL;
-  sigaction(signal_number, &sig_action, NULL);
-  kill(getpid(), signal_number);
-#elif defined(GLOG_OS_WINDOWS)
-  signal(signal_number, SIG_DFL);
-  raise(signal_number);
-#endif
-}
-
-// This variable is used for protecting FailureSignalHandler() from
-// dumping stuff while another thread is doing it.  Our policy is to let
-// the first thread dump stuff and let other threads wait.
-// See also comments in FailureSignalHandler().
-static pthread_t* g_entered_thread_id_pointer = NULL;
-
-// Dumps signal and stack frame information, and invokes the default
-// signal handler once our job is done.
-#if defined(GLOG_OS_WINDOWS)
-void FailureSignalHandler(int signal_number)
-#else
-void FailureSignalHandler(int signal_number,
-                          siginfo_t *signal_info,
-                          void *ucontext)
-#endif
-{
-  // First check if we've already entered the function.  We use an atomic
-  // compare and swap operation for platforms that support it.  For other
-  // platforms, we use a naive method that could lead to a subtle race.
-
-  // We assume pthread_self() is async signal safe, though it's not
-  // officially guaranteed.
-  pthread_t my_thread_id = pthread_self();
-  // NOTE: We could simply use pthread_t rather than pthread_t* for this,
-  // if pthread_self() is guaranteed to return non-zero value for thread
-  // ids, but there is no such guarantee.  We need to distinguish if the
-  // old value (value returned from __sync_val_compare_and_swap) is
-  // different from the original value (in this case NULL).
-  pthread_t* old_thread_id_pointer =
-      glog_internal_namespace_::sync_val_compare_and_swap(
-          &g_entered_thread_id_pointer,
-          static_cast<pthread_t*>(NULL),
-          &my_thread_id);
-  if (old_thread_id_pointer != NULL) {
-    // We've already entered the signal handler.  What should we do?
-    if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
-      // It looks the current thread is reentering the signal handler.
-      // Something must be going wrong (maybe we are reentering by another
-      // type of signal?).  Kill ourself by the default signal handler.
-      InvokeDefaultSignalHandler(signal_number);
-    }
-    // Another thread is dumping stuff.  Let's wait until that thread
-    // finishes the job and kills the process.
-    while (true) {
-      sleep(1);
-    }
-  }
-  MaybeUnsetRealtime();
-
-  // This is the first time we enter the signal handler.  We are going to
-  // do some interesting stuff from here.
-  // TODO(satorux): We might want to set timeout here using alarm(), but
-  // mixing alarm() and sleep() can be a bad idea.
-
-  // First dump time info.
-  DumpTimeInfo();
-
-#if !defined(GLOG_OS_WINDOWS)
-  // Get the program counter from ucontext.
-  void *pc = GetPC(ucontext);
-  DumpStackFrameInfo("PC: ", pc);
-#else
-  (void)ucontext;
-#endif
-
-#ifdef HAVE_STACKTRACE
-  // Get the stack traces.
-  void *stack[32];
-  // +1 to exclude this function.
-  const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1);
-# ifdef HAVE_SIGACTION
-  DumpSignalInfo(signal_number, signal_info);
-#elif !defined(GLOG_OS_WINDOWS)
-  (void)signal_info;
-# endif
-  // Dump the stack traces.
-  for (int i = 0; i < depth; ++i) {
-    DumpStackFrameInfo("    ", stack[i]);
-  }
-#elif !defined(GLOG_OS_WINDOWS)
-  (void)signal_info;
-#endif
-
-  // *** TRANSITION ***
-  //
-  // BEFORE this point, all code must be async-termination-safe!
-  // (See WARNING above.)
-  //
-  // AFTER this point, we do unsafe things, like using LOG()!
-  // The process could be terminated or hung at any time.  We try to
-  // do more useful things first and riskier things later.
-
-  // Flush the logs before we do anything in case 'anything'
-  // causes problems.
-  FlushLogFilesUnsafe(0);
-
-  // Kill ourself by the default signal handler.
-  InvokeDefaultSignalHandler(signal_number);
-}
-
-}  // namespace
-
-namespace glog_internal_namespace_ {
-
-bool IsFailureSignalHandlerInstalled() {
-#ifdef HAVE_SIGACTION
-  // TODO(andschwa): Return kFailureSignalHandlerInstalled?
-  struct sigaction sig_action;
-  memset(&sig_action, 0, sizeof(sig_action));
-  sigemptyset(&sig_action.sa_mask);
-  sigaction(SIGABRT, NULL, &sig_action);
-  if (sig_action.sa_sigaction == &FailureSignalHandler) {
-    return true;
-  }
-#elif defined(GLOG_OS_WINDOWS)
-  return kFailureSignalHandlerInstalled;
-#endif  // HAVE_SIGACTION
-  return false;
-}
-
-}  // namespace glog_internal_namespace_
-
-void InstallFailureSignalHandler() {
-#ifdef HAVE_SIGACTION
-  // Build the sigaction struct.
-  struct sigaction sig_action;
-  memset(&sig_action, 0, sizeof(sig_action));
-  sigemptyset(&sig_action.sa_mask);
-  sig_action.sa_flags |= SA_SIGINFO;
-  sig_action.sa_sigaction = &FailureSignalHandler;
-
-  for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
-    CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL));
-  }
-  kFailureSignalHandlerInstalled = true;
-#elif defined(GLOG_OS_WINDOWS)
-  for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
-    CHECK_NE(signal(kFailureSignals[i].number, &FailureSignalHandler),
-             SIG_ERR);
-  }
-  kFailureSignalHandlerInstalled = true;
-#endif  // HAVE_SIGACTION
-}
-
-void InstallFailureWriter(void (*writer)(const char* data, size_t size)) {
-#if defined(HAVE_SIGACTION) || defined(GLOG_OS_WINDOWS)
-  g_failure_writer = writer;
-#endif  // HAVE_SIGACTION
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/signalhandler_unittest.cc b/third_party/google-glog/src/signalhandler_unittest.cc
deleted file mode 100644
index c4c99cc..0000000
--- a/third_party/google-glog/src/signalhandler_unittest.cc
+++ /dev/null
@@ -1,113 +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: Satoru Takabayashi
-//
-// This is a helper binary for testing signalhandler.cc.  The actual test
-// is done in signalhandler_unittest.sh.
-
-#include "utilities.h"
-
-#if defined(HAVE_PTHREAD)
-# include <pthread.h>
-#endif
-#include <csignal>
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-#include <glog/logging.h>
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-using namespace GOOGLE_NAMESPACE;
-
-static void* DieInThread(void*) {
-  // We assume pthread_t is an integral number or a pointer, rather
-  // than a complex struct.  In some environments, pthread_self()
-  // returns an uint64 but in some other environments pthread_self()
-  // returns a pointer.
-  fprintf(
-      stderr, "0x%px is dying\n",
-      static_cast<const void*>(reinterpret_cast<const char*>(pthread_self())));
-  // Use volatile to prevent from these to be optimized away.
-  volatile int a = 0;
-  volatile int b = 1 / a;
-  fprintf(stderr, "We should have died: b=%d\n", b);
-  return NULL;
-}
-
-static void WriteToStdout(const char* data, size_t size) {
-  if (write(STDOUT_FILENO, data, size) < 0) {
-    // Ignore errors.
-  }
-}
-
-int main(int argc, char **argv) {
-#if defined(HAVE_STACKTRACE) && defined(HAVE_SYMBOLIZE)
-  InitGoogleLogging(argv[0]);
-#ifdef HAVE_LIB_GFLAGS
-  ParseCommandLineFlags(&argc, &argv, true);
-#endif
-  InstallFailureSignalHandler();
-  const std::string command = argc > 1 ? argv[1] : "none";
-  if (command == "segv") {
-    // We'll check if this is outputted.
-    LOG(INFO) << "create the log file";
-    LOG(INFO) << "a message before segv";
-    // We assume 0xDEAD is not writable.
-    int *a = (int*)0xDEAD;
-    *a = 0;
-  } else if (command == "loop") {
-    fprintf(stderr, "looping\n");
-    while (true);
-  } else if (command == "die_in_thread") {
-#if defined(HAVE_PTHREAD)
-    pthread_t thread;
-    pthread_create(&thread, NULL, &DieInThread, NULL);
-    pthread_join(thread, NULL);
-#else
-    fprintf(stderr, "no pthread\n");
-    return 1;
-#endif
-  } else if (command == "dump_to_stdout") {
-    InstallFailureWriter(WriteToStdout);
-    abort();
-  } else if (command == "installed") {
-    fprintf(stderr, "signal handler installed: %s\n",
-        IsFailureSignalHandlerInstalled() ? "true" : "false");
-  } else {
-    // Tell the shell script
-    puts("OK");
-  }
-#endif
-  return 0;
-}
diff --git a/third_party/google-glog/src/signalhandler_unittest.sh b/third_party/google-glog/src/signalhandler_unittest.sh
deleted file mode 100755
index 265cd45..0000000
--- a/third_party/google-glog/src/signalhandler_unittest.sh
+++ /dev/null
@@ -1,131 +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: Satoru Takabayashi
-#
-# Unit tests for signalhandler.cc.
-
-die () {
-    echo $1
-    exit 1
-}
-
-BINDIR=".libs"
-LIBGLOG="$BINDIR/libglog.so"
-
-BINARY="$BINDIR/signalhandler_unittest"
-LOG_INFO="./signalhandler_unittest.INFO"
-
-# Remove temporary files.
-rm -f signalhandler.out*
-
-if test -e "$BINARY"; then
-  # We need shared object.
-  export LD_LIBRARY_PATH=$BINDIR
-  export DYLD_LIBRARY_PATH=$BINDIR
-else
-  # For windows
-  BINARY="./signalhandler_unittest.exe"
-  if ! test -e "$BINARY"; then
-    echo "We coundn't find demangle_unittest binary."
-    exit 1
-  fi
-fi
-
-if [ x`$BINARY` != 'xOK' ]; then
-  echo "PASS (No stacktrace support. We don't run this test.)"
-  exit 0
-fi
-
-# The PC cannot be obtained in signal handlers on PowerPC correctly.
-# We just skip the test for PowerPC.
-if [ x`uname -p` = x"powerpc" ]; then
-  echo "PASS (We don't test the signal handler on PowerPC.)"
-  exit 0
-fi
-
-# Test for a case the program kills itself by SIGSEGV.
-GOOGLE_LOG_DIR=. $BINARY segv 2> signalhandler.out1
-for pattern in SIGSEGV 0xdead main "Aborted at [0-9]"; do
-  if ! grep --quiet "$pattern" signalhandler.out1; then
-    die "'$pattern' should appear in the output"
-  fi
-done
-if ! grep --quiet "a message before segv" $LOG_INFO; then
-  die "'a message before segv' should appear in the INFO log"
-fi
-rm -f $LOG_INFO
-
-# Test for a case the program is killed by this shell script.
-# $! = the process id of the last command run in the background.
-# $$ = the process id of this shell.
-$BINARY loop 2> signalhandler.out2 &
-# Wait until "looping" is written in the file.  This indicates the program
-# is ready to accept signals.
-while true; do
-  if grep --quiet looping signalhandler.out2; then
-    break
-  fi
-done
-kill -TERM $!
-wait $!
-
-from_pid=''
-# Only linux has the process ID of the signal sender.
-if [ x`uname` = "xLinux" ]; then
-  from_pid="from PID $$"
-fi
-for pattern in SIGTERM "by PID $!" "$from_pid" main "Aborted at [0-9]"; do
-  if ! grep --quiet "$pattern" signalhandler.out2; then
-    die "'$pattern' should appear in the output"
-  fi
-done
-
-# Test for a case the program dies in a non-main thread.
-$BINARY die_in_thread 2> signalhandler.out3
-EXPECTED_TID="`sed 's/ .*//; q' signalhandler.out3`"
-
-for pattern in SIGFPE DieInThread "TID $EXPECTED_TID" "Aborted at [0-9]"; do
-  if ! grep --quiet "$pattern" signalhandler.out3; then
-    die "'$pattern' should appear in the output"
-  fi
-done
-
-# Test for a case the program installs a custom failure writer that writes
-# stuff to stdout instead of stderr.
-$BINARY dump_to_stdout 1> signalhandler.out4
-for pattern in SIGABRT main "Aborted at [0-9]"; do
-  if ! grep --quiet "$pattern" signalhandler.out4; then
-    die "'$pattern' should appear in the output"
-  fi
-done
-
-echo PASS
diff --git a/third_party/google-glog/src/stacktrace.h b/third_party/google-glog/src/stacktrace.h
deleted file mode 100644
index 55b98b2..0000000
--- a/third_party/google-glog/src/stacktrace.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2000 - 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.
-//
-// Routines to extract the current stack trace.  These functions are
-// thread-safe.
-
-#ifndef BASE_STACKTRACE_H_
-#define BASE_STACKTRACE_H_
-
-#include "config.h"
-#include <glog/logging.h>
-
-_START_GOOGLE_NAMESPACE_
-
-// 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 = GetStackFrames(result, 10, 1);
-//      }
-//
-// This produces:
-//      result[0]       foo
-//      result[1]       main
-//           ....       ...
-//
-// "result" must not be NULL.
-GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
-
-_END_GOOGLE_NAMESPACE_
-
-#endif  // BASE_STACKTRACE_H_
diff --git a/third_party/google-glog/src/stacktrace_generic-inl.h b/third_party/google-glog/src/stacktrace_generic-inl.h
deleted file mode 100644
index 96397d0..0000000
--- a/third_party/google-glog/src/stacktrace_generic-inl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2000 - 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.
-//
-// Portable implementation - just use glibc
-//
-// Note:  The glibc implementation may cause a call to malloc.
-// This can cause a deadlock in HeapProfiler.
-#include <execinfo.h>
-#include <string.h>
-#include "stacktrace.h"
-
-_START_GOOGLE_NAMESPACE_
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
-  static const int kStackLength = 64;
-  void * stack[kStackLength];
-  int size;
-
-  size = backtrace(stack, kStackLength);
-  skip_count++;  // we want to skip the current 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];
-  }
-
-  return result_count;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_libunwind-inl.h b/third_party/google-glog/src/stacktrace_libunwind-inl.h
deleted file mode 100644
index 0b20d23..0000000
--- a/third_party/google-glog/src/stacktrace_libunwind-inl.h
+++ /dev/null
@@ -1,93 +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: Arun Sharma
-//
-// Produce stack trace using libunwind
-
-#include "utilities.h"
-
-extern "C" {
-#define UNW_LOCAL_ONLY
-#include <libunwind.h>
-}
-#include <glog/raw_logging.h>
-#include "stacktrace.h"
-
-_START_GOOGLE_NAMESPACE_
-
-// 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.
-// We can use the GCC __thread syntax here since libunwind is not supported on
-// Windows.
-static __thread bool g_tl_entered; // Initialized to false.
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
-  void *ip;
-  int n = 0;
-  unw_cursor_t cursor;
-  unw_context_t uc;
-
-  if (g_tl_entered) {
-    return 0;
-  }
-  g_tl_entered = true;
-
-  unw_getcontext(&uc);
-  RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
-  skip_count++;         // Do not include the "GetStackTrace" frame
-
-  while (n < max_depth) {
-    int ret =
-        unw_get_reg(&cursor, UNW_REG_IP, reinterpret_cast<unw_word_t *>(&ip));
-    if (ret < 0) {
-      break;
-    }
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n++] = ip;
-    }
-    ret = unw_step(&cursor);
-    if (ret <= 0) {
-      break;
-    }
-  }
-
-  g_tl_entered = false;
-  return n;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_powerpc-inl.h b/third_party/google-glog/src/stacktrace_powerpc-inl.h
deleted file mode 100644
index 911970c..0000000
--- a/third_party/google-glog/src/stacktrace_powerpc-inl.h
+++ /dev/null
@@ -1,130 +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
-//
-// 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
-
-#include <cstdio>
-#include <stdint.h>   // for uintptr_t
-#include "stacktrace.h"
-
-_START_GOOGLE_NAMESPACE_
-
-// 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 = static_cast<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(""); }
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
-  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__.
-#ifdef __APPLE__
-  __asm__ volatile ("mr %0,r1" : "=r" (sp));
-#else
-  __asm__ volatile ("mr %0,1" : "=r" (sp));
-#endif
-
-  // 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();
-
-  // The LR save area is used by the callee, so the top entry is bogus.
-  skip_count++;
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    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(_CALL_AIX) || defined(_CALL_DARWIN)
-      result[n++] = *(sp+2);
-#elif defined(_CALL_SYSV)
-      result[n++] = *(sp+1);
-#elif defined(__APPLE__) || ((defined(__linux) || defined(__linux__)) && defined(__PPC64__))
-      // This check is in case the compiler doesn't define _CALL_AIX/etc.
-      result[n++] = *(sp+2);
-#elif defined(__linux) || defined(__OpenBSD__)
-      // This check is in case the compiler doesn't define _CALL_SYSV.
-      result[n++] = *(sp+1);
-#else
-#error Need to specify the PPC ABI for your archiecture.
-#endif
-    }
-    // Use strict unwinding rules.
-    sp = NextStackFrame<true>(sp);
-  }
-  return n;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_unittest.cc b/third_party/google-glog/src/stacktrace_unittest.cc
deleted file mode 100644
index 7213284..0000000
--- a/third_party/google-glog/src/stacktrace_unittest.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// 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.
-
-#include "utilities.h"
-
-#include <cstdio>
-#include <cstdlib>
-#include "config.h"
-#include "base/commandlineflags.h"
-#include <glog/logging.h>
-#include "stacktrace.h"
-
-#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
-# include <execinfo.h>
-#endif
-
-using namespace GOOGLE_NAMESPACE;
-
-#ifdef HAVE_STACKTRACE
-
-// 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__
-
-//-----------------------------------------------------------------------//
-
-static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
-{
-  CHECK_GE(ret_addr, range.start);
-  CHECK_LE(ret_addr, range.end);
-}
-
-//-----------------------------------------------------------------------//
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wgnu-label-as-value"
-#endif
-
-void ATTRIBUTE_NOINLINE CheckStackTrace(int);
-static 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);
-
-  if (1) {
-#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
-    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]);
-    }
-
-    union {
-      void (*p1)(int);
-      void* p2;
-    } p = {&CheckStackTrace};
-
-    printf("CheckStackTrace() addr: %p\n", p.p2);
-    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. */
-static 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);
-}
-static 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);
-}
-static 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);
-}
-static 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);
-}
-
-#ifndef __GNUC__
-// On non-GNU environment, we use the address of `CheckStackTrace` to
-// guess the address range of this function. This guess is wrong for
-// non-static function on Windows. This is probably because
-// `&CheckStackTrace` returns the address of a trampoline like PLT,
-// not the actual address of `CheckStackTrace`.
-// See https://github.com/google/glog/issues/421 for the detail.
-static
-#endif
-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);
-}
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-//-----------------------------------------------------------------------//
-
-int main(int, char ** argv) {
-  FLAGS_logtostderr = true;
-  InitGoogleLogging(argv[0]);
-
-  CheckStackTrace(0);
-
-  printf("PASS\n");
-  return 0;
-}
-
-#else
-int main() {
-  printf("PASS (no stacktrace support)\n");
-  return 0;
-}
-#endif  // HAVE_STACKTRACE
diff --git a/third_party/google-glog/src/stacktrace_unwind-inl.h b/third_party/google-glog/src/stacktrace_unwind-inl.h
deleted file mode 100644
index dc1665b..0000000
--- a/third_party/google-glog/src/stacktrace_unwind-inl.h
+++ /dev/null
@@ -1,106 +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: Arun Sharma
-//
-// Produce stack trace using libgcc
-
-#include <cstdlib> // for NULL
-#include <unwind.h> // ABI defined unwinder
-
-#include "stacktrace.h"
-
-_START_GOOGLE_NAMESPACE_
-
-typedef struct {
-  void **result;
-  int max_depth;
-  int skip_count;
-  int count;
-} trace_arg_t;
-
-
-// Workaround for the malloc() in _Unwind_Backtrace() issue.
-static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context */*uc*/, void */*opq*/) {
-  return _URC_NO_REASON;
-}
-
-
-// This code is not considered ready to run until
-// static initializers run so that we are guaranteed
-// that any malloc-related initialization is done.
-static bool ready_to_run = false;
-class StackTraceInit {
- public:
-   StackTraceInit() {
-     // Extra call to force initialization
-     _Unwind_Backtrace(nop_backtrace, NULL);
-     ready_to_run = true;
-   }
-};
-
-static StackTraceInit module_initializer;  // Force initialization
-
-static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
-  trace_arg_t *targ = static_cast<trace_arg_t *>(opq);
-
-  if (targ->skip_count > 0) {
-    targ->skip_count--;
-  } else {
-    targ->result[targ->count++] = reinterpret_cast<void *>(_Unwind_GetIP(uc));
-  }
-
-  if (targ->count == targ->max_depth) {
-    return _URC_END_OF_STACK;
-  }
-
-  return _URC_NO_REASON;
-}
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
-  if (!ready_to_run) {
-    return 0;
-  }
-
-  trace_arg_t targ;
-
-  skip_count += 1;         // Do not include the "GetStackTrace" frame
-
-  targ.result = result;
-  targ.max_depth = max_depth;
-  targ.skip_count = skip_count;
-  targ.count = 0;
-
-  _Unwind_Backtrace(GetOneFrame, &targ);
-
-  return targ.count;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_windows-inl.h b/third_party/google-glog/src/stacktrace_windows-inl.h
deleted file mode 100644
index e6af561..0000000
--- a/third_party/google-glog/src/stacktrace_windows-inl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2000 - 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: Andrew Schwartzmeyer
-//
-// Windows implementation - just use CaptureStackBackTrace
-
-#include "config.h"
-#include "port.h"
-#include "stacktrace.h"
-#include <dbghelp.h>
-
-_START_GOOGLE_NAMESPACE_
-
-int GetStackTrace(void** result, int max_depth, int skip_count) {
-  if (max_depth > 64) {
-    max_depth = 64;
-  }
-  skip_count++;  // we want to skip the current frame as well
-  // This API is thread-safe (moreover it walks only the current thread).
-  return CaptureStackBackTrace(static_cast<DWORD>(skip_count), static_cast<DWORD>(max_depth), result, NULL);
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_x86-inl.h b/third_party/google-glog/src/stacktrace_x86-inl.h
deleted file mode 100644
index 48e87f7..0000000
--- a/third_party/google-glog/src/stacktrace_x86-inl.h
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (c) 2000 - 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
-
-#include <stdint.h>   // for uintptr_t
-
-#include "utilities.h"   // for OS_* macros
-
-#if !defined(GLOG_OS_WINDOWS)
-#include <unistd.h>
-#include <sys/mman.h>
-#endif
-
-#include <cstdio>  // for NULL
-#include "stacktrace.h"
-
-_START_GOOGLE_NAMESPACE_
-
-// 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 = static_cast<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 (reinterpret_cast<uintptr_t>(new_sp) -
-            reinterpret_cast<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) && (reinterpret_cast<uintptr_t>(new_sp) -
-                                  reinterpret_cast<uintptr_t>(old_sp) >
-                              1000000))
-      return NULL;
-  }
-  if (reinterpret_cast<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
-#if !defined(GLOG_OS_WINDOWS)
-  if (!STRICT_UNWINDING) {
-    // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test
-    // 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 =
-        reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) &
-                                 static_cast<uintptr_t>(~(page_size - 1)));
-    if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) {
-      return NULL;
-    }
-  }
-#endif
-  return new_sp;
-}
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
-  void **sp;
-
-#ifdef __GNUC__
-#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
-#define USE_BUILTIN_FRAME_ADDRESS
-#endif
-#endif
-
-#ifdef USE_BUILTIN_FRAME_ADDRESS
-  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
-  //    ...
-  sp = (void **)&result - 2;
-#elif defined(__x86_64__)
-  // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8
-  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;
-#endif
-
-  int n = 0;
-  while (sp && n < max_depth) {
-    if (*(sp + 1) == NULL) {
-      // In 64-bit code, we often see a frame that
-      // points to itself and has a return address of 0.
-      break;
-    }
-    if (skip_count > 0) {
-      skip_count--;
-    } else {
-      result[n++] = *(sp+1);
-    }
-    // Use strict unwinding rules.
-    sp = NextStackFrame<true>(sp);
-  }
-  return n;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stl_logging_unittest.cc b/third_party/google-glog/src/stl_logging_unittest.cc
deleted file mode 100644
index 5ab2414..0000000
--- a/third_party/google-glog/src/stl_logging_unittest.cc
+++ /dev/null
@@ -1,207 +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.
-
-#include "config.h"
-
-#ifdef HAVE_USING_OPERATOR
-
-#include <functional>
-#include <iostream>
-#include <map>
-#include <ostream>
-#include <string>
-#include <vector>
-
-#ifdef __GNUC__
-// C++0x isn't enabled by default in GCC and libc++ does not have
-// non-standard ext/* and tr1/unordered_*.
-# if defined(_LIBCPP_VERSION)
-#  ifndef GLOG_STL_LOGGING_FOR_UNORDERED
-#  define GLOG_STL_LOGGING_FOR_UNORDERED
-#  endif
-# else
-#  ifndef GLOG_STL_LOGGING_FOR_EXT_HASH
-#  define GLOG_STL_LOGGING_FOR_EXT_HASH
-#  endif
-#  ifndef GLOG_STL_LOGGING_FOR_EXT_SLIST
-#  define GLOG_STL_LOGGING_FOR_EXT_SLIST
-#  endif
-#  ifndef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
-#  define GLOG_STL_LOGGING_FOR_TR1_UNORDERED
-#  endif
-# endif
-#endif
-
-#include <glog/logging.h>
-#include <glog/stl_logging.h>
-#include "googletest.h"
-
-using namespace std;
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-using namespace __gnu_cxx;
-#endif
-
-struct user_hash {
-  size_t operator()(int x) const { return static_cast<size_t>(x); }
-};
-
-static void TestSTLLogging() {
-  {
-    // Test a sequence.
-    vector<int> v;
-    v.push_back(10);
-    v.push_back(20);
-    v.push_back(30);
-    ostringstream ss;
-    ss << v;
-    EXPECT_EQ(ss.str(), "10 20 30");
-    vector<int> copied_v(v);
-    CHECK_EQ(v, copied_v);  // This must compile.
-  }
-
-  {
-    // Test a sorted pair associative container.
-    map< int, string > m;
-    m[20] = "twenty";
-    m[10] = "ten";
-    m[30] = "thirty";
-    ostringstream ss;
-    ss << m;
-    EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)");
-    map< int, string > copied_m(m);
-    CHECK_EQ(m, copied_m);  // This must compile.
-  }
-
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-  {
-    // Test a hashed simple associative container.
-    hash_set<int> hs;
-    hs.insert(10);
-    hs.insert(20);
-    hs.insert(30);
-    ostringstream ss;
-    ss << hs;
-    EXPECT_EQ(ss.str().size(), 8);
-    EXPECT_TRUE(ss.str().find("10") != string::npos);
-    EXPECT_TRUE(ss.str().find("20") != string::npos);
-    EXPECT_TRUE(ss.str().find("30") != string::npos);
-    hash_set<int> copied_hs(hs);
-    CHECK_EQ(hs, copied_hs);  // This must compile.
-  }
-#endif
-
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-  {
-    // Test a hashed pair associative container.
-    hash_map<int, string> hm;
-    hm[10] = "ten";
-    hm[20] = "twenty";
-    hm[30] = "thirty";
-    ostringstream ss;
-    ss << hm;
-    EXPECT_EQ(ss.str().size(), 35);
-    EXPECT_TRUE(ss.str().find("(10, ten)") != string::npos);
-    EXPECT_TRUE(ss.str().find("(20, twenty)") != string::npos);
-    EXPECT_TRUE(ss.str().find("(30, thirty)") != string::npos);
-    hash_map<int, string> copied_hm(hm);
-    CHECK_EQ(hm, copied_hm);  // this must compile
-  }
-#endif
-
-  {
-    // Test a long sequence.
-    vector<int> v;
-    string expected;
-    for (int i = 0; i < 100; i++) {
-      v.push_back(i);
-      if (i > 0) expected += ' ';
-      const size_t buf_size = 256;
-      char buf[buf_size];
-      snprintf(buf, buf_size, "%d", i);
-      expected += buf;
-    }
-    v.push_back(100);
-    expected += " ...";
-    ostringstream ss;
-    ss << v;
-    CHECK_EQ(ss.str(), expected.c_str());
-  }
-
-  {
-    // Test a sorted pair associative container.
-    // Use a non-default comparison functor.
-    map< int, string, greater<int> > m;
-    m[20] = "twenty";
-    m[10] = "ten";
-    m[30] = "thirty";
-    ostringstream ss;
-    ss << m;
-    EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)");
-    map< int, string, greater<int> > copied_m(m);
-    CHECK_EQ(m, copied_m);  // This must compile.
-  }
-
-#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
-  {
-    // Test a hashed simple associative container.
-    // Use a user defined hash function.
-    hash_set<int, user_hash> hs;
-    hs.insert(10);
-    hs.insert(20);
-    hs.insert(30);
-    ostringstream ss;
-    ss << hs;
-    EXPECT_EQ(ss.str().size(), 8);
-    EXPECT_TRUE(ss.str().find("10") != string::npos);
-    EXPECT_TRUE(ss.str().find("20") != string::npos);
-    EXPECT_TRUE(ss.str().find("30") != string::npos);
-    hash_set<int, user_hash> copied_hs(hs);
-    CHECK_EQ(hs, copied_hs);  // This must compile.
-  }
-#endif
-}
-
-int main(int, char**) {
-  TestSTLLogging();
-  std::cout << "PASS\n";
-  return 0;
-}
-
-#else
-
-#include <iostream>
-
-int main(int, char**) {
-  std::cout << "We don't support stl_logging for this compiler.\n"
-            << "(we need compiler support of 'using ::operator<<' "
-            << "for this feature.)\n";
-  return 0;
-}
-
-#endif  // HAVE_USING_OPERATOR
diff --git a/third_party/google-glog/src/symbolize.cc b/third_party/google-glog/src/symbolize.cc
deleted file mode 100644
index f56e97c..0000000
--- a/third_party/google-glog/src/symbolize.cc
+++ /dev/null
@@ -1,955 +0,0 @@
-// 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: Satoru Takabayashi
-// Stack-footprint reduction work done by Raksit Ashok
-//
-// Implementation note:
-//
-// We don't use heaps but only use stacks.  We want to reduce the
-// stack consumption so that the symbolizer can run on small stacks.
-//
-// Here are some numbers collected with GCC 4.1.0 on x86:
-// - sizeof(Elf32_Sym)  = 16
-// - sizeof(Elf32_Shdr) = 40
-// - sizeof(Elf64_Sym)  = 24
-// - sizeof(Elf64_Shdr) = 64
-//
-// This implementation is intended to be async-signal-safe but uses
-// some functions which are not guaranteed to be so, such as memchr()
-// and memmove().  We assume they are async-signal-safe.
-//
-// Additional header can be specified by the GLOG_BUILD_CONFIG_INCLUDE
-// macro to add platform specific defines (e.g. GLOG_OS_OPENBSD).
-
-#ifdef GLOG_BUILD_CONFIG_INCLUDE
-#include GLOG_BUILD_CONFIG_INCLUDE
-#endif  // GLOG_BUILD_CONFIG_INCLUDE
-
-#include "utilities.h"
-
-#if defined(HAVE_SYMBOLIZE)
-
-#include <cstring>
-
-#include <algorithm>
-#include <limits>
-
-#include "symbolize.h"
-#include "demangle.h"
-
-_START_GOOGLE_NAMESPACE_
-
-// We don't use assert() since it's not guaranteed to be
-// async-signal-safe.  Instead we define a minimal assertion
-// macro. So far, we don't need pretty printing for __FILE__, etc.
-
-// A wrapper for abort() to make it callable in ? :.
-static int AssertFail() {
-  abort();
-  return 0;  // Should not reach.
-}
-
-#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
-
-static SymbolizeCallback g_symbolize_callback = NULL;
-void InstallSymbolizeCallback(SymbolizeCallback callback) {
-  g_symbolize_callback = callback;
-}
-
-static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
-    NULL;
-void InstallSymbolizeOpenObjectFileCallback(
-    SymbolizeOpenObjectFileCallback callback) {
-  g_symbolize_open_object_file_callback = callback;
-}
-
-// This function wraps the Demangle function to provide an interface
-// where the input symbol is demangled in-place.
-// To keep stack consumption low, we would like this function to not
-// get inlined.
-static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, size_t out_size) {
-  char demangled[256];  // Big enough for sane demangled symbols.
-  if (Demangle(out, demangled, sizeof(demangled))) {
-    // Demangling succeeded. Copy to out if the space allows.
-    size_t len = strlen(demangled);
-    if (len + 1 <= out_size) {  // +1 for '\0'.
-      SAFE_ASSERT(len < sizeof(demangled));
-      memmove(out, demangled, len + 1);
-    }
-  }
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#if defined(__ELF__)
-
-#if defined(HAVE_DLFCN_H)
-#include <dlfcn.h>
-#endif
-#if defined(GLOG_OS_OPENBSD)
-#include <sys/exec_elf.h>
-#else
-#include <elf.h>
-#endif
-#include <cerrno>
-#include <climits>
-#include <cstddef>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <fcntl.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "symbolize.h"
-#include "config.h"
-#include <glog/raw_logging.h>
-
-// Re-runs fn until it doesn't cause EINTR.
-#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
-
-_START_GOOGLE_NAMESPACE_
-
-// Read up to "count" bytes from "offset" in the file pointed by 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 ReadFromOffset(const int fd, void *buf, const size_t count,
-                              const size_t offset) {
-  SAFE_ASSERT(fd >= 0);
-  SAFE_ASSERT(count <= static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
-  char *buf0 = reinterpret_cast<char *>(buf);
-  size_t num_bytes = 0;
-  while (num_bytes < count) {
-    ssize_t len;
-    NO_INTR(len = pread(fd, buf0 + num_bytes, count - num_bytes,
-                        static_cast<off_t>(offset + num_bytes)));
-    if (len < 0) {  // There was an error other than EINTR.
-      return -1;
-    }
-    if (len == 0) {  // Reached EOF.
-      break;
-    }
-    num_bytes += static_cast<size_t>(len);
-  }
-  SAFE_ASSERT(num_bytes <= count);
-  return static_cast<ssize_t>(num_bytes);
-}
-
-// Try reading exactly "count" bytes from "offset" bytes in a file
-// pointed by "fd" into the buffer starting at "buf" while handling
-// short reads and EINTR.  On success, return true. Otherwise, return
-// false.
-static bool ReadFromOffsetExact(const int fd, void *buf,
-                                const size_t count, const size_t offset) {
-  ssize_t len = ReadFromOffset(fd, buf, count, offset);
-  return static_cast<size_t>(len) == count;
-}
-
-// Returns elf_header.e_type if the file pointed by fd is an ELF binary.
-static int FileGetElfType(const int fd) {
-  ElfW(Ehdr) elf_header;
-  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
-    return -1;
-  }
-  if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) {
-    return -1;
-  }
-  return elf_header.e_type;
-}
-
-// Read the section headers in the given ELF binary, and if a section
-// of the specified type is found, set the output to this section header
-// and return true.  Otherwise, return false.
-// To keep stack consumption low, we would like this function to not get
-// inlined.
-static ATTRIBUTE_NOINLINE bool
-GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const size_t sh_offset,
-                       ElfW(Word) type, ElfW(Shdr) *out) {
-  // Read at most 16 section headers at a time to save read calls.
-  ElfW(Shdr) buf[16];
-  for (size_t i = 0; i < sh_num;) {
-    const size_t num_bytes_left = (sh_num - i) * sizeof(buf[0]);
-    const size_t num_bytes_to_read =
-        (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf);
-    const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read,
-                                       sh_offset + i * sizeof(buf[0]));
-    if (len == -1) {
-      return false;
-    }
-    SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0);
-    const size_t num_headers_in_buf = static_cast<size_t>(len) / sizeof(buf[0]);
-    SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0]));
-    for (size_t j = 0; j < num_headers_in_buf; ++j) {
-      if (buf[j].sh_type == type) {
-        *out = buf[j];
-        return true;
-      }
-    }
-    i += num_headers_in_buf;
-  }
-  return false;
-}
-
-// There is no particular reason to limit section name to 63 characters,
-// but there has (as yet) been no need for anything longer either.
-const int kMaxSectionNameLen = 64;
-
-// name_len should include terminating '\0'.
-bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
-                            ElfW(Shdr) *out) {
-  ElfW(Ehdr) elf_header;
-  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
-    return false;
-  }
-
-  ElfW(Shdr) shstrtab;
-  size_t shstrtab_offset =
-      (elf_header.e_shoff + static_cast<size_t>(elf_header.e_shentsize) *
-                                static_cast<size_t>(elf_header.e_shstrndx));
-  if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
-    return false;
-  }
-
-  for (size_t i = 0; i < elf_header.e_shnum; ++i) {
-    size_t section_header_offset = (elf_header.e_shoff +
-                                   elf_header.e_shentsize * i);
-    if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) {
-      return false;
-    }
-    char header_name[kMaxSectionNameLen];
-    if (sizeof(header_name) < name_len) {
-      RAW_LOG(WARNING, "Section name '%s' is too long (%" PRIuS "); "
-              "section will not be found (even if present).", name, name_len);
-      // No point in even trying.
-      return false;
-    }
-    size_t name_offset = shstrtab.sh_offset + out->sh_name;
-    ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset);
-    if (n_read == -1) {
-      return false;
-    } else if (static_cast<size_t>(n_read) != name_len) {
-      // Short read -- name could be at end of file.
-      continue;
-    }
-    if (memcmp(header_name, name, name_len) == 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// Read a symbol table and look for the symbol containing the
-// pc. Iterate over symbols in a symbol table and look for the symbol
-// containing "pc".  On success, return true and write the symbol name
-// to out.  Otherwise, return false.
-// To keep stack consumption low, we would like this function to not get
-// inlined.
-static ATTRIBUTE_NOINLINE bool
-FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
-           uint64_t symbol_offset, const ElfW(Shdr) *strtab,
-           const ElfW(Shdr) *symtab) {
-  if (symtab == NULL) {
-    return false;
-  }
-  const size_t num_symbols = symtab->sh_size / symtab->sh_entsize;
-  for (unsigned i = 0; i < num_symbols;) {
-    size_t offset = symtab->sh_offset + i * symtab->sh_entsize;
-
-    // If we are reading Elf64_Sym's, we want to limit this array to
-    // 32 elements (to keep stack consumption low), otherwise we can
-    // have a 64 element Elf32_Sym array.
-#if defined(__WORDSIZE) && __WORDSIZE == 64
-    const size_t NUM_SYMBOLS = 32U;
-#else
-    const size_t NUM_SYMBOLS = 64U;
-#endif
-
-    // Read at most NUM_SYMBOLS symbols at once to save read() calls.
-    ElfW(Sym) buf[NUM_SYMBOLS];
-    size_t num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i);
-    const ssize_t len =
-        ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset);
-    SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0);
-    const size_t num_symbols_in_buf = static_cast<size_t>(len) / sizeof(buf[0]);
-    SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read);
-    for (unsigned j = 0; j < num_symbols_in_buf; ++j) {
-      const ElfW(Sym)& symbol = buf[j];
-      uint64_t start_address = symbol.st_value;
-      start_address += symbol_offset;
-      uint64_t end_address = start_address + symbol.st_size;
-      if (symbol.st_value != 0 &&  // Skip null value symbols.
-          symbol.st_shndx != 0 &&  // Skip undefined symbols.
-          start_address <= pc && pc < end_address) {
-        ssize_t len1 = ReadFromOffset(fd, out, out_size,
-                                      strtab->sh_offset + symbol.st_name);
-        if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) {
-          memset(out, 0, out_size);
-          return false;
-        }
-        return true;  // Obtained the symbol name.
-      }
-    }
-    i += num_symbols_in_buf;
-  }
-  return false;
-}
-
-// Get the symbol name of "pc" from the file pointed by "fd".  Process
-// both regular and dynamic symbol tables if necessary.  On success,
-// write the symbol name to "out" and return true.  Otherwise, return
-// false.
-static bool GetSymbolFromObjectFile(const int fd,
-                                    uint64_t pc,
-                                    char* out,
-                                    size_t out_size,
-                                    uint64_t base_address) {
-  // Read the ELF header.
-  ElfW(Ehdr) elf_header;
-  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
-    return false;
-  }
-
-  ElfW(Shdr) symtab, strtab;
-
-  // Consult a regular symbol table first.
-  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
-                             SHT_SYMTAB, &symtab)) {
-    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
-                             symtab.sh_link * sizeof(symtab))) {
-      return false;
-    }
-    if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) {
-      return true;  // Found the symbol in a regular symbol table.
-    }
-  }
-
-  // If the symbol is not found, then consult a dynamic symbol table.
-  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
-                             SHT_DYNSYM, &symtab)) {
-    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
-                             symtab.sh_link * sizeof(symtab))) {
-      return false;
-    }
-    if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) {
-      return true;  // Found the symbol in a dynamic symbol table.
-    }
-  }
-
-  return false;
-}
-
-namespace {
-// 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) {
-      close(fd_);
-    }
-  }
-  int get() { return fd_; }
-
- private:
-  FileDescriptor(const FileDescriptor &);
-  void operator=(const FileDescriptor&);
-};
-
-// Helper class for reading lines from file.
-//
-// Note: we don't use ProcMapsIterator since the object is big (it has
-// a 5k array member) and uses async-unsafe functions such as sscanf()
-// and snprintf().
-class LineReader {
- public:
-  explicit LineReader(int fd, char *buf, size_t buf_len, size_t offset)
-      : fd_(fd),
-        buf_(buf),
-        buf_len_(buf_len),
-        offset_(offset),
-        bol_(buf),
-        eol_(buf),
-        eod_(buf) {}
-
-  // Read '\n'-terminated line from file.  On success, modify "bol"
-  // and "eol", then return true.  Otherwise, return false.
-  //
-  // Note: if the last line doesn't end with '\n', the line will be
-  // dropped.  It's an intentional behavior to make the code simple.
-  bool ReadLine(const char **bol, const char **eol) {
-    if (BufferIsEmpty()) {  // First time.
-      const ssize_t num_bytes = ReadFromOffset(fd_, buf_, buf_len_, offset_);
-      if (num_bytes <= 0) {  // EOF or error.
-        return false;
-      }
-      offset_ += static_cast<size_t>(num_bytes);
-      eod_ = buf_ + num_bytes;
-      bol_ = buf_;
-    } else {
-      bol_ = eol_ + 1;  // Advance to the next line in the buffer.
-      SAFE_ASSERT(bol_ <= eod_);  // "bol_" can point to "eod_".
-      if (!HasCompleteLine()) {
-        const size_t incomplete_line_length = static_cast<size_t>(eod_ - bol_);
-        // Move the trailing incomplete line to the beginning.
-        memmove(buf_, bol_, incomplete_line_length);
-        // Read text from file and append it.
-        char * const append_pos = buf_ + incomplete_line_length;
-        const size_t capacity_left = buf_len_ - incomplete_line_length;
-        const ssize_t num_bytes =
-            ReadFromOffset(fd_, append_pos, capacity_left, offset_);
-        if (num_bytes <= 0) {  // EOF or error.
-          return false;
-        }
-        offset_ += static_cast<size_t>(num_bytes);
-        eod_ = append_pos + num_bytes;
-        bol_ = buf_;
-      }
-    }
-    eol_ = FindLineFeed();
-    if (eol_ == NULL) {  // '\n' not found.  Malformed line.
-      return false;
-    }
-    *eol_ = '\0';  // Replace '\n' with '\0'.
-
-    *bol = bol_;
-    *eol = eol_;
-    return true;
-  }
-
-  // Beginning of line.
-  const char *bol() {
-    return bol_;
-  }
-
-  // End of line.
-  const char *eol() {
-    return eol_;
-  }
-
- private:
-  LineReader(const LineReader &);
-  void operator=(const LineReader&);
-
-  char *FindLineFeed() {
-    return reinterpret_cast<char *>(memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_)));
-  }
-
-  bool BufferIsEmpty() {
-    return buf_ == eod_;
-  }
-
-  bool HasCompleteLine() {
-    return !BufferIsEmpty() && FindLineFeed() != NULL;
-  }
-
-  const int fd_;
-  char * const buf_;
-  const size_t buf_len_;
-  size_t offset_;
-  char *bol_;
-  char *eol_;
-  const char *eod_;  // End of data in "buf_".
-};
-}  // namespace
-
-// Place the hex number read from "start" into "*hex".  The pointer to
-// the first non-hex character or "end" is returned.
-static char *GetHex(const char *start, const char *end, uint64_t *hex) {
-  *hex = 0;
-  const char *p;
-  for (p = start; p < end; ++p) {
-    int ch = *p;
-    if ((ch >= '0' && ch <= '9') ||
-        (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
-      *hex = (*hex << 4U) | (ch < 'A' ? static_cast<uint64_t>(ch - '0') : (ch & 0xF) + 9U);
-    } else {  // Encountered the first non-hex character.
-      break;
-    }
-  }
-  SAFE_ASSERT(p <= end);
-  return const_cast<char *>(p);
-}
-
-// Searches for the object file (from /proc/self/maps) that contains
-// the specified pc.  If found, sets |start_address| to the start address
-// of where this object file is mapped in memory, sets the module base
-// address into |base_address|, copies the object file name into
-// |out_file_name|, and attempts to open the object file.  If the object
-// file is opened successfully, returns the file descriptor.  Otherwise,
-// returns -1.  |out_file_name_size| is the size of the file name buffer
-// (including the null-terminator).
-static ATTRIBUTE_NOINLINE int
-OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
-                                             uint64_t &start_address,
-                                             uint64_t &base_address,
-                                             char *out_file_name,
-                                             size_t out_file_name_size) {
-  int object_fd;
-
-  int maps_fd;
-  NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY));
-  FileDescriptor wrapped_maps_fd(maps_fd);
-  if (wrapped_maps_fd.get() < 0) {
-    return -1;
-  }
-
-  int mem_fd;
-  NO_INTR(mem_fd = open("/proc/self/mem", O_RDONLY));
-  FileDescriptor wrapped_mem_fd(mem_fd);
-  if (wrapped_mem_fd.get() < 0) {
-    return -1;
-  }
-
-  // Iterate over maps and look for the map containing the pc.  Then
-  // look into the symbol tables inside.
-  char buf[1024];  // Big enough for line of sane /proc/self/maps
-  unsigned num_maps = 0;
-  LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf), 0);
-  while (true) {
-    num_maps++;
-    const char *cursor;
-    const char *eol;
-    if (!reader.ReadLine(&cursor, &eol)) {  // EOF or malformed line.
-      return -1;
-    }
-
-    // Start parsing line in /proc/self/maps.  Here is an example:
-    //
-    // 08048000-0804c000 r-xp 00000000 08:01 2142121    /bin/cat
-    //
-    // We want start address (08048000), end address (0804c000), flags
-    // (r-xp) and file name (/bin/cat).
-
-    // Read start address.
-    cursor = GetHex(cursor, eol, &start_address);
-    if (cursor == eol || *cursor != '-') {
-      return -1;  // Malformed line.
-    }
-    ++cursor;  // Skip '-'.
-
-    // Read end address.
-    uint64_t end_address;
-    cursor = GetHex(cursor, eol, &end_address);
-    if (cursor == eol || *cursor != ' ') {
-      return -1;  // Malformed line.
-    }
-    ++cursor;  // Skip ' '.
-
-    // Read flags.  Skip flags until we encounter a space or eol.
-    const char * const flags_start = cursor;
-    while (cursor < eol && *cursor != ' ') {
-      ++cursor;
-    }
-    // We expect at least four letters for flags (ex. "r-xp").
-    if (cursor == eol || cursor < flags_start + 4) {
-      return -1;  // Malformed line.
-    }
-
-    // Determine the base address by reading ELF headers in process memory.
-    ElfW(Ehdr) ehdr;
-    // Skip non-readable maps.
-    if (flags_start[0] == 'r' &&
-        ReadFromOffsetExact(mem_fd, &ehdr, sizeof(ElfW(Ehdr)), start_address) &&
-        memcmp(ehdr.e_ident, ELFMAG, SELFMAG) == 0) {
-      switch (ehdr.e_type) {
-        case ET_EXEC:
-          base_address = 0;
-          break;
-        case ET_DYN:
-          // Find the segment containing file offset 0. This will correspond
-          // to the ELF header that we just read. Normally this will have
-          // virtual address 0, but this is not guaranteed. We must subtract
-          // the virtual address from the address where the ELF header was
-          // mapped to get the base address.
-          //
-          // If we fail to find a segment for file offset 0, use the address
-          // of the ELF header as the base address.
-          base_address = start_address;
-          for (unsigned i = 0; i != ehdr.e_phnum; ++i) {
-            ElfW(Phdr) phdr;
-            if (ReadFromOffsetExact(
-                    mem_fd, &phdr, sizeof(phdr),
-                    start_address + ehdr.e_phoff + i * sizeof(phdr)) &&
-                phdr.p_type == PT_LOAD && phdr.p_offset == 0) {
-              base_address = start_address - phdr.p_vaddr;
-              break;
-            }
-          }
-          break;
-        default:
-          // ET_REL or ET_CORE. These aren't directly executable, so they don't
-          // affect the base address.
-          break;
-      }
-    }
-
-    // Check start and end addresses.
-    if (!(start_address <= pc && pc < end_address)) {
-      continue;  // We skip this map.  PC isn't in this map.
-    }
-
-   // Check flags.  We are only interested in "r*x" maps.
-    if (flags_start[0] != 'r' || flags_start[2] != 'x') {
-      continue;  // We skip this map.
-    }
-    ++cursor;  // Skip ' '.
-
-    // Read file offset.
-    uint64_t file_offset;
-    cursor = GetHex(cursor, eol, &file_offset);
-    if (cursor == eol || *cursor != ' ') {
-      return -1;  // Malformed line.
-    }
-    ++cursor;  // Skip ' '.
-
-    // Skip to file name.  "cursor" now points to dev.  We need to
-    // skip at least two spaces for dev and inode.
-    int num_spaces = 0;
-    while (cursor < eol) {
-      if (*cursor == ' ') {
-        ++num_spaces;
-      } else if (num_spaces >= 2) {
-        // The first non-space character after skipping two spaces
-        // is the beginning of the file name.
-        break;
-      }
-      ++cursor;
-    }
-    if (cursor == eol) {
-      return -1;  // Malformed line.
-    }
-
-    // Finally, "cursor" now points to file name of our interest.
-    NO_INTR(object_fd = open(cursor, O_RDONLY));
-    if (object_fd < 0) {
-      // Failed to open object file.  Copy the object file name to
-      // |out_file_name|.
-      strncpy(out_file_name, cursor, out_file_name_size);
-      // Making sure |out_file_name| is always null-terminated.
-      out_file_name[out_file_name_size - 1] = '\0';
-      return -1;
-    }
-    return object_fd;
-  }
-}
-
-// POSIX doesn't define any async-signal safe function for converting
-// an integer to ASCII. We'll have to define our own version.
-// itoa_r() converts an (unsigned) integer to ASCII. It returns "buf", if the
-// conversion was successful or NULL otherwise. It never writes more than "sz"
-// bytes. Output will be truncated as needed, and a NUL character is always
-// appended.
-// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
-static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t padding) {
-  // Make sure we can write at least one NUL byte.
-  size_t n = 1;
-  if (n > sz) {
-    return NULL;
-  }
-
-  if (base < 2 || base > 16) {
-    buf[0] = '\000';
-    return NULL;
-  }
-
-  char *start = buf;
-
-  // Loop until we have converted the entire number. Output at least one
-  // character (i.e. '0').
-  char *ptr = start;
-  do {
-    // Make sure there is still enough space left in our output buffer.
-    if (++n > sz) {
-      buf[0] = '\000';
-      return NULL;
-    }
-
-    // Output the next digit.
-    *ptr++ = "0123456789abcdef"[i % base];
-    i /= base;
-
-    if (padding > 0) {
-      padding--;
-    }
-  } while (i > 0 || padding > 0);
-
-  // Terminate the output with a NUL character.
-  *ptr = '\000';
-
-  // Conversion to ASCII actually resulted in the digits being in reverse
-  // order. We can't easily generate them in forward order, as we can't tell
-  // the number of characters needed until we are done converting.
-  // So, now, we reverse the string (except for the possible "-" sign).
-  while (--ptr > start) {
-    char ch = *ptr;
-    *ptr = *start;
-    *start++ = ch;
-  }
-  return buf;
-}
-
-// Safely appends string |source| to string |dest|.  Never writes past the
-// buffer size |dest_size| and guarantees that |dest| is null-terminated.
-static void SafeAppendString(const char* source, char* dest, size_t dest_size) {
-  size_t dest_string_length = strlen(dest);
-  SAFE_ASSERT(dest_string_length < dest_size);
-  dest += dest_string_length;
-  dest_size -= dest_string_length;
-  strncpy(dest, source, dest_size);
-  // Making sure |dest| is always null-terminated.
-  dest[dest_size - 1] = '\0';
-}
-
-// Converts a 64-bit value into a hex string, and safely appends it to |dest|.
-// Never writes past the buffer size |dest_size| and guarantees that |dest| is
-// null-terminated.
-static void SafeAppendHexNumber(uint64_t value, char* dest, size_t dest_size) {
-  // 64-bit numbers in hex can have up to 16 digits.
-  char buf[17] = {'\0'};
-  SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size);
-}
-
-// The implementation of our symbolization routine.  If it
-// successfully finds the symbol containing "pc" and obtains the
-// symbol name, returns true and write the symbol name to "out".
-// Otherwise, returns false. If Callback function is installed via
-// InstallSymbolizeCallback(), the function is also called in this function,
-// and "out" is used as its output.
-// To keep stack consumption low, we would like this function to not
-// get inlined.
-static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
-                                                    size_t out_size) {
-  uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
-  uint64_t start_address = 0;
-  uint64_t base_address = 0;
-  int object_fd = -1;
-
-  if (out_size < 1) {
-    return false;
-  }
-  out[0] = '\0';
-  SafeAppendString("(", out, out_size);
-
-  if (g_symbolize_open_object_file_callback) {
-    object_fd = g_symbolize_open_object_file_callback(pc0, start_address,
-                                                      base_address, out + 1,
-                                                      out_size - 1);
-  } else {
-    object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address,
-                                                             base_address,
-                                                             out + 1,
-                                                             out_size - 1);
-  }
-
-  FileDescriptor wrapped_object_fd(object_fd);
-
-#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES)
-  {
-#else
-  // Check whether a file name was returned.
-  if (object_fd < 0) {
-#endif
-    if (out[1]) {
-      // The object file containing PC was determined successfully however the
-      // object file was not opened successfully.  This is still considered
-      // success because the object file name and offset are known and tools
-      // like asan_symbolize.py can be used for the symbolization.
-      out[out_size - 1] = '\0';  // Making sure |out| is always null-terminated.
-      SafeAppendString("+0x", out, out_size);
-      SafeAppendHexNumber(pc0 - base_address, out, out_size);
-      SafeAppendString(")", out, out_size);
-      return true;
-    }
-    // Failed to determine the object file containing PC.  Bail out.
-    return false;
-  }
-  int elf_type = FileGetElfType(wrapped_object_fd.get());
-  if (elf_type == -1) {
-    return false;
-  }
-  if (g_symbolize_callback) {
-    // Run the call back if it's installed.
-    // Note: relocation (and much of the rest of this code) will be
-    // wrong for prelinked shared libraries and PIE executables.
-    uint64_t relocation = (elf_type == ET_DYN) ? start_address : 0;
-    int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
-                                                 pc, out, out_size,
-                                                 relocation);
-    if (num_bytes_written > 0) {
-      out += static_cast<size_t>(num_bytes_written);
-      out_size -= static_cast<size_t>(num_bytes_written);
-    }
-  }
-  if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0,
-                               out, out_size, base_address)) {
-    if (out[1] && !g_symbolize_callback) {
-      // The object file containing PC was opened successfully however the
-      // symbol was not found. The object may have been stripped. This is still
-      // considered success because the object file name and offset are known
-      // and tools like asan_symbolize.py can be used for the symbolization.
-      out[out_size - 1] = '\0';  // Making sure |out| is always null-terminated.
-      SafeAppendString("+0x", out, out_size);
-      SafeAppendHexNumber(pc0 - base_address, out, out_size);
-      SafeAppendString(")", out, out_size);
-      return true;
-    }
-    return false;
-  }
-
-  // Symbolization succeeded.  Now we try to demangle the symbol.
-  DemangleInplace(out, out_size);
-  return true;
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#elif (defined(GLOG_OS_MACOSX) || defined(GLOG_OS_EMSCRIPTEN)) && defined(HAVE_DLADDR)
-
-#include <dlfcn.h>
-#include <cstring>
-
-_START_GOOGLE_NAMESPACE_
-
-static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
-                                                    size_t out_size) {
-  Dl_info info;
-  if (dladdr(pc, &info)) {
-    if (info.dli_sname) {
-      if (strlen(info.dli_sname) < out_size) {
-        strcpy(out, info.dli_sname);
-        // Symbolization succeeded.  Now we try to demangle the symbol.
-        DemangleInplace(out, out_size);
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
-
-#include <windows.h>
-#include <dbghelp.h>
-
-#ifdef _MSC_VER
-#pragma comment(lib, "dbghelp")
-#endif
-
-_START_GOOGLE_NAMESPACE_
-
-class SymInitializer {
-public:
-  HANDLE process;
-  bool ready;
-  SymInitializer() : process(NULL), ready(false) {
-    // Initialize the symbol handler.
-    // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
-    process = GetCurrentProcess();
-    // Defer symbol loading.
-    // We do not request undecorated symbols with SYMOPT_UNDNAME
-    // because the mangling library calls UnDecorateSymbolName.
-    SymSetOptions(SYMOPT_DEFERRED_LOADS);
-    if (SymInitialize(process, NULL, true)) {
-      ready = true;
-    }
-  }
-  ~SymInitializer() {
-    SymCleanup(process);
-    // We do not need to close `HANDLE process` because it's a "pseudo handle."
-  }
-private:
-  SymInitializer(const SymInitializer&);
-  SymInitializer& operator=(const SymInitializer&);
-};
-
-static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
-                                                    size_t out_size) {
-  const static SymInitializer symInitializer;
-  if (!symInitializer.ready) {
-    return false;
-  }
-  // Resolve symbol information from address.
-  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx
-  char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
-  SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(buf);
-  symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
-  symbol->MaxNameLen = MAX_SYM_NAME;
-  // We use the ANSI version to ensure the string type is always `char *`.
-  // This could break if a symbol has Unicode in it.
-  BOOL ret = SymFromAddr(symInitializer.process,
-                         reinterpret_cast<DWORD64>(pc), 0, symbol);
-  if (ret == 1 && static_cast<ssize_t>(symbol->NameLen) < out_size) {
-    // `NameLen` does not include the null terminating character.
-    strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1);
-    out[static_cast<size_t>(symbol->NameLen)] = '\0';
-    // Symbolization succeeded.  Now we try to demangle the symbol.
-    DemangleInplace(out, out_size);
-    return true;
-  }
-  return false;
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#else
-# error BUG: HAVE_SYMBOLIZE was wrongly set
-#endif
-
-_START_GOOGLE_NAMESPACE_
-
-bool Symbolize(void *pc, char *out, size_t out_size) {
-  return SymbolizeAndDemangle(pc, out, out_size);
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#else  /* HAVE_SYMBOLIZE */
-
-#include <cassert>
-
-#include "config.h"
-
-_START_GOOGLE_NAMESPACE_
-
-// TODO: Support other environments.
-bool Symbolize(void* /*pc*/, char* /*out*/, size_t /*out_size*/) {
-  assert(0);
-  return false;
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#endif
diff --git a/third_party/google-glog/src/symbolize.h b/third_party/google-glog/src/symbolize.h
deleted file mode 100644
index dcbb194..0000000
--- a/third_party/google-glog/src/symbolize.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// 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: Satoru Takabayashi
-//
-// This library provides Symbolize() function that symbolizes program
-// counters to their corresponding symbol names on linux platforms.
-// This library has a minimal implementation of an ELF symbol table
-// reader (i.e. it doesn't depend on libelf, etc.).
-//
-// The algorithm used in Symbolize() is as follows.
-//
-//   1. Go through a list of maps in /proc/self/maps and find the map
-//   containing the program counter.
-//
-//   2. Open the mapped file and find a regular symbol table inside.
-//   Iterate over symbols in the symbol table and look for the symbol
-//   containing the program counter.  If such a symbol is found,
-//   obtain the symbol name, and demangle the symbol if possible.
-//   If the symbol isn't found in the regular symbol table (binary is
-//   stripped), try the same thing with a dynamic symbol table.
-//
-// Note that Symbolize() is originally implemented to be used in
-// FailureSignalHandler() in base/google.cc.  Hence it doesn't use
-// malloc() and other unsafe operations.  It should be both
-// thread-safe and async-signal-safe.
-
-#ifndef BASE_SYMBOLIZE_H_
-#define BASE_SYMBOLIZE_H_
-
-#include "utilities.h"
-#include "config.h"
-#include <glog/logging.h>
-
-#ifdef HAVE_SYMBOLIZE
-
-#if defined(__ELF__)  // defined by gcc
-#if defined(__OpenBSD__)
-#include <sys/exec_elf.h>
-#else
-#include <elf.h>
-#endif
-
-#if !defined(ANDROID)
-#include <link.h>  // For ElfW() macro.
-#endif
-
-// For systems where SIZEOF_VOID_P is not defined, determine it
-// based on __LP64__ (defined by gcc on 64-bit systems)
-#if !defined(SIZEOF_VOID_P)
-# if defined(__LP64__)
-#  define SIZEOF_VOID_P 8
-# else
-#  define SIZEOF_VOID_P 4
-# endif
-#endif
-
-// If there is no ElfW macro, let's define it by ourself.
-#ifndef ElfW
-# if SIZEOF_VOID_P == 4
-#  define ElfW(type) Elf32_##type
-# elif SIZEOF_VOID_P == 8
-#  define ElfW(type) Elf64_##type
-# else
-#  error "Unknown sizeof(void *)"
-# endif
-#endif
-
-_START_GOOGLE_NAMESPACE_
-
-// Gets the section header for the given name, if it exists. Returns true on
-// success. Otherwise, returns false.
-bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
-                            ElfW(Shdr) *out);
-
-_END_GOOGLE_NAMESPACE_
-
-#endif  /* __ELF__ */
-
-_START_GOOGLE_NAMESPACE_
-
-// Restrictions on the callbacks that follow:
-//  - The callbacks must not use heaps but only use stacks.
-//  - The callbacks must be async-signal-safe.
-
-// Installs a callback function, which will be called right before a symbol name
-// is printed. The callback is intended to be used for showing a file name and a
-// line number preceding a symbol name.
-// "fd" is a file descriptor of the object file containing the program
-// counter "pc". The callback function should write output to "out"
-// and return the size of the output written. On error, the callback
-// function should return -1.
-typedef int (*SymbolizeCallback)(int fd,
-                                 void* pc,
-                                 char* out,
-                                 size_t out_size,
-                                 uint64_t relocation);
-GLOG_EXPORT
-void InstallSymbolizeCallback(SymbolizeCallback callback);
-
-// Installs a callback function, which will be called instead of
-// OpenObjectFileContainingPcAndGetStartAddress.  The callback is expected
-// to searches for the object file (from /proc/self/maps) that contains
-// the specified pc.  If found, sets |start_address| to the start address
-// of where this object file is mapped in memory, sets the module base
-// address into |base_address|, copies the object file name into
-// |out_file_name|, and attempts to open the object file.  If the object
-// file is opened successfully, returns the file descriptor.  Otherwise,
-// returns -1.  |out_file_name_size| is the size of the file name buffer
-// (including the null-terminator).
-typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
-                                               uint64_t& start_address,
-                                               uint64_t& base_address,
-                                               char* out_file_name,
-                                               size_t out_file_name_size);
-void InstallSymbolizeOpenObjectFileCallback(
-    SymbolizeOpenObjectFileCallback callback);
-
-_END_GOOGLE_NAMESPACE_
-
-#endif
-
-_START_GOOGLE_NAMESPACE_
-
-// Symbolizes a program counter.  On success, returns true and write the
-// symbol name to "out".  The symbol name is demangled if possible
-// (supports symbols generated by GCC 3.x or newer).  Otherwise,
-// returns false.
-GLOG_EXPORT bool Symbolize(void* pc, char* out, size_t out_size);
-
-_END_GOOGLE_NAMESPACE_
-
-#endif  // BASE_SYMBOLIZE_H_
diff --git a/third_party/google-glog/src/symbolize_unittest.cc b/third_party/google-glog/src/symbolize_unittest.cc
deleted file mode 100644
index 2522e73..0000000
--- a/third_party/google-glog/src/symbolize_unittest.cc
+++ /dev/null
@@ -1,468 +0,0 @@
-// 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: Satoru Takabayashi
-//
-// Unit tests for functions in symbolize.cc.
-
-#include "symbolize.h"
-
-#include <glog/logging.h>
-
-#include <csignal>
-#include <iostream>
-
-#include "config.h"
-#include "googletest.h"
-#include "utilities.h"
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-using namespace std;
-using namespace GOOGLE_NAMESPACE;
-
-// Avoid compile error due to "cast between pointer-to-function and
-// pointer-to-object is an extension" warnings.
-#if defined(__GNUG__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpedantic"
-#endif
-
-#if defined(HAVE_STACKTRACE)
-
-#define always_inline
-
-#if defined(__ELF__) || defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
-// A wrapper function for Symbolize() to make the unit test simple.
-static const char *TrySymbolize(void *pc) {
-  static char symbol[4096];
-  if (Symbolize(pc, symbol, sizeof(symbol))) {
-    return symbol;
-  } else {
-    return NULL;
-  }
-}
-#endif
-
-# if defined(__ELF__)
-
-// This unit tests make sense only with GCC.
-// Uses lots of GCC specific features.
-#if defined(__GNUC__) && !defined(__OPENCC__)
-#  if __GNUC__ >= 4
-#    define TEST_WITH_MODERN_GCC
-#    if defined(__i386__) && __i386__  // always_inline isn't supported for x86_64 with GCC 4.1.0.
-#      undef always_inline
-#      define always_inline __attribute__((always_inline))
-#      define HAVE_ALWAYS_INLINE
-#    endif  // __i386__
-#  else
-#  endif  // __GNUC__ >= 4
-#  if defined(__i386__) || defined(__x86_64__)
-#    define TEST_X86_32_AND_64 1
-#  endif  // defined(__i386__) || defined(__x86_64__)
-#endif
-
-// Make them C linkage to avoid mangled names.
-extern "C" {
-void nonstatic_func();
-void nonstatic_func() {
-  volatile int a = 0;
-  // NOTE: In C++20, increment of object of volatile-qualified type is
-  // deprecated.
-  a = a + 1;
-}
-
-static void static_func() {
-  volatile int a = 0;
-  // NOTE: In C++20, increment of object of volatile-qualified type is
-  // deprecated.
-  a = a + 1;
-}
-}
-
-TEST(Symbolize, Symbolize) {
-  // We do C-style cast since GCC 2.95.3 doesn't allow
-  // reinterpret_cast<void *>(&func).
-
-  // Compilers should give us pointers to them.
-  EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
-
-  // The name of an internal linkage symbol is not specified; allow either a
-  // mangled or an unmangled name here.
-  const char *static_func_symbol =
-      TrySymbolize(reinterpret_cast<void *>(&static_func));
-
-#if !defined(_MSC_VER) || !defined(NDEBUG)
-  CHECK(NULL != static_func_symbol);
-  EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
-              strcmp("static_func()", static_func_symbol) == 0);
-#endif
-
-  EXPECT_TRUE(NULL == TrySymbolize(NULL));
-}
-
-struct Foo {
-  static void func(int x);
-};
-
-void ATTRIBUTE_NOINLINE Foo::func(int x) {
-  volatile int a = x;
-  // NOTE: In C++20, increment of object of volatile-qualified type is
-  // deprecated.
-  a = a + 1;
-}
-
-// With a modern GCC, Symbolize() should return demangled symbol
-// names.  Function parameters should be omitted.
-#ifdef TEST_WITH_MODERN_GCC
-TEST(Symbolize, SymbolizeWithDemangling) {
-  Foo::func(100);
-#if !defined(_MSC_VER) || !defined(NDEBUG)
-  EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func)));
-#endif
-}
-#endif
-
-// Tests that verify that Symbolize footprint is within some limit.
-
-// To measure the stack footprint of the Symbolize function, we create
-// a signal handler (for SIGUSR1 say) that calls the Symbolize function
-// on an alternate stack. This alternate stack is initialized to some
-// known pattern (0x55, 0x55, 0x55, ...). We then self-send this signal,
-// and after the signal handler returns, look at the alternate stack
-// buffer to see what portion has been touched.
-//
-// This trick gives us the the stack footprint of the signal handler.
-// But the signal handler, even before the call to Symbolize, consumes
-// some stack already. We however only want the stack usage of the
-// Symbolize function. To measure this accurately, we install two signal
-// handlers: one that does nothing and just returns, and another that
-// calls Symbolize. The difference between the stack consumption of these
-// two signals handlers should give us the Symbolize stack foorprint.
-
-static void *g_pc_to_symbolize;
-static char g_symbolize_buffer[4096];
-static char *g_symbolize_result;
-
-static void EmptySignalHandler(int /*signo*/) {}
-
-static void SymbolizeSignalHandler(int /*signo*/) {
-  if (Symbolize(g_pc_to_symbolize, g_symbolize_buffer,
-                sizeof(g_symbolize_buffer))) {
-    g_symbolize_result = g_symbolize_buffer;
-  } else {
-    g_symbolize_result = NULL;
-  }
-}
-
-const int kAlternateStackSize = 8096;
-const char kAlternateStackFillValue = 0x55;
-
-// These helper functions look at the alternate stack buffer, and figure
-// out what portion of this buffer has been touched - this is the stack
-// consumption of the signal handler running on this alternate stack.
-static ATTRIBUTE_NOINLINE bool StackGrowsDown(int *x) {
-  int y;
-  return &y < x;
-}
-static int GetStackConsumption(const char* alt_stack) {
-  int x;
-  if (StackGrowsDown(&x)) {
-    for (int i = 0; i < kAlternateStackSize; i++) {
-      if (alt_stack[i] != kAlternateStackFillValue) {
-        return (kAlternateStackSize - i);
-      }
-    }
-  } else {
-    for (int i = (kAlternateStackSize - 1); i >= 0; i--) {
-      if (alt_stack[i] != kAlternateStackFillValue) {
-        return i;
-      }
-    }
-  }
-  return -1;
-}
-
-#ifdef HAVE_SIGALTSTACK
-
-// Call Symbolize and figure out the stack footprint of this call.
-static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
-
-  g_pc_to_symbolize = pc;
-
-  // The alt-signal-stack cannot be heap allocated because there is a
-  // bug in glibc-2.2 where some signal handler setup code looks at the
-  // current stack pointer to figure out what thread is currently running.
-  // Therefore, the alternate stack must be allocated from the main stack
-  // itself.
-  char altstack[kAlternateStackSize];
-  memset(altstack, kAlternateStackFillValue, kAlternateStackSize);
-
-  // Set up the alt-signal-stack (and save the older one).
-  stack_t sigstk;
-  memset(&sigstk, 0, sizeof(stack_t));
-  stack_t old_sigstk;
-  sigstk.ss_sp = altstack;
-  sigstk.ss_size = kAlternateStackSize;
-  sigstk.ss_flags = 0;
-  CHECK_ERR(sigaltstack(&sigstk, &old_sigstk));
-
-  // Set up SIGUSR1 and SIGUSR2 signal handlers (and save the older ones).
-  struct sigaction sa;
-  memset(&sa, 0, sizeof(struct sigaction));
-  struct sigaction old_sa1, old_sa2;
-  sigemptyset(&sa.sa_mask);
-  sa.sa_flags = SA_ONSTACK;
-
-  // SIGUSR1 maps to EmptySignalHandler.
-  sa.sa_handler = EmptySignalHandler;
-  CHECK_ERR(sigaction(SIGUSR1, &sa, &old_sa1));
-
-  // SIGUSR2 maps to SymbolizeSignalHanlder.
-  sa.sa_handler = SymbolizeSignalHandler;
-  CHECK_ERR(sigaction(SIGUSR2, &sa, &old_sa2));
-
-  // Send SIGUSR1 signal and measure the stack consumption of the empty
-  // signal handler.
-  CHECK_ERR(kill(getpid(), SIGUSR1));
-  int stack_consumption1 = GetStackConsumption(altstack);
-
-  // Send SIGUSR2 signal and measure the stack consumption of the symbolize
-  // signal handler.
-  CHECK_ERR(kill(getpid(), SIGUSR2));
-  int stack_consumption2 = GetStackConsumption(altstack);
-
-  // The difference between the two stack consumption values is the
-  // stack footprint of the Symbolize function.
-  if (stack_consumption1 != -1 && stack_consumption2 != -1) {
-    *stack_consumed = stack_consumption2 - stack_consumption1;
-  } else {
-    *stack_consumed = -1;
-  }
-
-  // Log the stack consumption values.
-  LOG(INFO) << "Stack consumption of empty signal handler: "
-            << stack_consumption1;
-  LOG(INFO) << "Stack consumption of symbolize signal handler: "
-            << stack_consumption2;
-  LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed;
-
-  // Now restore the old alt-signal-stack and signal handlers.
-  CHECK_ERR(sigaltstack(&old_sigstk, NULL));
-  CHECK_ERR(sigaction(SIGUSR1, &old_sa1, NULL));
-  CHECK_ERR(sigaction(SIGUSR2, &old_sa2, NULL));
-
-  return g_symbolize_result;
-}
-
-#ifdef __ppc64__
-// Symbolize stack consumption should be within 4kB.
-const int kStackConsumptionUpperLimit = 4096;
-#else
-// Symbolize stack consumption should be within 2kB.
-const int kStackConsumptionUpperLimit = 2048;
-#endif
-
-TEST(Symbolize, SymbolizeStackConsumption) {
-  int stack_consumed;
-  const char* symbol;
-
-  symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&nonstatic_func),
-                                     &stack_consumed);
-  EXPECT_STREQ("nonstatic_func", symbol);
-  EXPECT_GT(stack_consumed, 0);
-  EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
-
-  // The name of an internal linkage symbol is not specified; allow either a
-  // mangled or an unmangled name here.
-  symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&static_func),
-                                     &stack_consumed);
-  CHECK(NULL != symbol);
-  EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
-              strcmp("static_func()", symbol) == 0);
-  EXPECT_GT(stack_consumed, 0);
-  EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
-}
-
-#ifdef TEST_WITH_MODERN_GCC
-TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
-  Foo::func(100);
-  int stack_consumed;
-  const char* symbol;
-
-  symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&Foo::func),
-                                     &stack_consumed);
-
-  EXPECT_STREQ("Foo::func()", symbol);
-  EXPECT_GT(stack_consumed, 0);
-  EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
-}
-#endif
-
-#endif  // HAVE_SIGALTSTACK
-
-// x86 specific tests.  Uses some inline assembler.
-extern "C" {
-inline void* always_inline inline_func() {
-  void *pc = NULL;
-#ifdef TEST_X86_32_AND_64
-  __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
-#endif
-  return pc;
-}
-
-void* ATTRIBUTE_NOINLINE non_inline_func();
-void* ATTRIBUTE_NOINLINE non_inline_func() {
-  void *pc = NULL;
-#ifdef TEST_X86_32_AND_64
-  __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
-#endif
-  return pc;
-}
-
-static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
-#if defined(TEST_X86_32_AND_64) && defined(HAVE_ATTRIBUTE_NOINLINE)
-  void *pc = non_inline_func();
-  const char *symbol = TrySymbolize(pc);
-
-#if !defined(_MSC_VER) || !defined(NDEBUG)
-  CHECK(symbol != NULL);
-  CHECK_STREQ(symbol, "non_inline_func");
-#endif
-  cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
-#endif
-}
-
-static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
-#if defined(TEST_X86_32_AND_64) && defined(HAVE_ALWAYS_INLINE)
-  void *pc = inline_func();  // Must be inlined.
-  const char *symbol = TrySymbolize(pc);
-
-#if !defined(_MSC_VER) || !defined(NDEBUG)
-  CHECK(symbol != NULL);
-  CHECK_STREQ(symbol, __FUNCTION__);
-#endif
-  cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
-#endif
-}
-}
-
-// Test with a return address.
-static void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
-#if defined(HAVE_ATTRIBUTE_NOINLINE)
-  void *return_address = __builtin_return_address(0);
-  const char *symbol = TrySymbolize(return_address);
-
-#if !defined(_MSC_VER) || !defined(NDEBUG)
-  CHECK(symbol != NULL);
-  CHECK_STREQ(symbol, "main");
-#endif
-  cout << "Test case TestWithReturnAddress passed." << endl;
-#endif
-}
-
-# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
-
-#ifdef _MSC_VER
-#include <intrin.h>
-#pragma intrinsic(_ReturnAddress)
-#endif
-
-struct Foo {
-  static void func(int x);
-};
-
-__declspec(noinline) void Foo::func(int x) {
-  volatile int a = x;
-  // NOTE: In C++20, increment of object of volatile-qualified type is
-  // deprecated.
-  a = a + 1;
-}
-
-TEST(Symbolize, SymbolizeWithDemangling) {
-  Foo::func(100);
-  const char* ret = TrySymbolize((void *)(&Foo::func));
-
-#if defined(HAVE_DBGHELP) && !defined(NDEBUG)
-  EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret);
-#endif
-}
-
-__declspec(noinline) void TestWithReturnAddress() {
-  void *return_address =
-#ifdef __GNUC__ // Cygwin and MinGW support
-	  __builtin_return_address(0)
-#else
-	  _ReturnAddress()
-#endif
-	  ;
-  const char *symbol = TrySymbolize(return_address);
-#if !defined(_MSC_VER) || !defined(NDEBUG)
-  CHECK(symbol != NULL);
-  CHECK_STREQ(symbol, "main");
-#endif
-  cout << "Test case TestWithReturnAddress passed." << endl;
-}
-# endif  // __ELF__
-#endif  // HAVE_STACKTRACE
-
-int main(int argc, char **argv) {
-  FLAGS_logtostderr = true;
-  InitGoogleLogging(argv[0]);
-  InitGoogleTest(&argc, argv);
-#if defined(HAVE_SYMBOLIZE) && defined(HAVE_STACKTRACE)
-# if defined(__ELF__)
-  // We don't want to get affected by the callback interface, that may be
-  // used to install some callback function at InitGoogle() time.
-  InstallSymbolizeCallback(NULL);
-
-  TestWithPCInsideInlineFunction();
-  TestWithPCInsideNonInlineFunction();
-  TestWithReturnAddress();
-  return RUN_ALL_TESTS();
-# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
-  TestWithReturnAddress();
-  return RUN_ALL_TESTS();
-# else  // GLOG_OS_WINDOWS
-  printf("PASS (no symbolize_unittest support)\n");
-  return 0;
-# endif  // __ELF__
-#else
-  printf("PASS (no symbolize support)\n");
-  return 0;
-#endif  // HAVE_SYMBOLIZE
-}
-
-#if defined(__GNUG__)
-#pragma GCC diagnostic pop
-#endif
diff --git a/third_party/google-glog/src/utilities.cc b/third_party/google-glog/src/utilities.cc
deleted file mode 100644
index a332f1a..0000000
--- a/third_party/google-glog/src/utilities.cc
+++ /dev/null
@@ -1,402 +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: Shinichiro Hamaji
-
-#include "config.h"
-#include "utilities.h"
-
-#include <cstdio>
-#include <cstdlib>
-
-#include <csignal>
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#include <ctime>
-#if defined(HAVE_SYSCALL_H)
-#include <syscall.h>                 // for syscall()
-#elif defined(HAVE_SYS_SYSCALL_H)
-#include <sys/syscall.h>                 // for syscall()
-#endif
-#ifdef HAVE_SYSLOG_H
-# include <syslog.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>  // For geteuid.
-#endif
-#ifdef HAVE_PWD_H
-# include <pwd.h>
-#endif
-#ifdef __ANDROID__
-#include <android/log.h>
-#endif
-
-#include "base/googleinit.h"
-
-using std::string;
-
-_START_GOOGLE_NAMESPACE_
-
-static const char* g_program_invocation_short_name = NULL;
-
-bool IsGoogleLoggingInitialized() {
-  return g_program_invocation_short_name != NULL;
-}
-
-_END_GOOGLE_NAMESPACE_
-
-// The following APIs are all internal.
-#ifdef HAVE_STACKTRACE
-
-#include "stacktrace.h"
-#include "symbolize.h"
-#include "base/commandlineflags.h"
-
-GLOG_DEFINE_bool(symbolize_stacktrace, true,
-                 "Symbolize the stack trace in the tombstone");
-
-_START_GOOGLE_NAMESPACE_
-
-typedef void DebugWriter(const char*, void*);
-
-// The %p field width for printf() functions is two characters per byte.
-// For some environments, add two extra bytes for the leading "0x".
-static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);
-
-static void DebugWriteToStderr(const char* data, void *) {
-  // This one is signal-safe.
-  if (write(STDERR_FILENO, data, strlen(data)) < 0) {
-    // Ignore errors.
-  }
-#if defined(__ANDROID__)
-  // ANDROID_LOG_FATAL as fatal error occurred and now is dumping call stack.
-  __android_log_write(ANDROID_LOG_FATAL,
-                      glog_internal_namespace_::ProgramInvocationShortName(),
-                      data);
-#endif
-}
-
-static void DebugWriteToString(const char* data, void *arg) {
-  reinterpret_cast<string*>(arg)->append(data);
-}
-
-#ifdef HAVE_SYMBOLIZE
-// Print a program counter and its symbol name.
-static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc,
-                            const char * const prefix) {
-  char tmp[1024];
-  const char *symbol = "(unknown)";
-  // Symbolizes the previous address of pc because pc may be in the
-  // next function.  The overrun happens when the function ends with
-  // a call to a function annotated noreturn (e.g. CHECK).
-  if (Symbolize(reinterpret_cast<char *>(pc) - 1, tmp, sizeof(tmp))) {
-      symbol = tmp;
-  }
-  char buf[1024];
-  snprintf(buf, sizeof(buf), "%s@ %*p  %s\n",
-           prefix, kPrintfPointerFieldWidth, pc, symbol);
-  writerfn(buf, arg);
-}
-#endif
-
-static void DumpPC(DebugWriter *writerfn, void *arg, void *pc,
-                   const char * const prefix) {
-  char buf[100];
-  snprintf(buf, sizeof(buf), "%s@ %*p\n",
-           prefix, kPrintfPointerFieldWidth, pc);
-  writerfn(buf, arg);
-}
-
-// Dump current stack trace as directed by writerfn
-static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
-  // Print stack trace
-  void* stack[32];
-  int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1);
-  for (int i = 0; i < depth; i++) {
-#if defined(HAVE_SYMBOLIZE)
-    if (FLAGS_symbolize_stacktrace) {
-      DumpPCAndSymbol(writerfn, arg, stack[i], "    ");
-    } else {
-      DumpPC(writerfn, arg, stack[i], "    ");
-    }
-#else
-    DumpPC(writerfn, arg, stack[i], "    ");
-#endif
-  }
-}
-
-#if defined(__GNUC__)
-__attribute__((noreturn))
-#elif defined(_MSC_VER)
-__declspec(noreturn)
-#endif
-static void DumpStackTraceAndExit() {
-  DumpStackTrace(1, DebugWriteToStderr, NULL);
-
-  // TODO(hamaji): Use signal instead of sigaction?
-  if (IsFailureSignalHandlerInstalled()) {
-    // Set the default signal handler for SIGABRT, to avoid invoking our
-    // own signal handler installed by InstallFailureSignalHandler().
-#ifdef HAVE_SIGACTION
-    struct sigaction sig_action;
-    memset(&sig_action, 0, sizeof(sig_action));
-    sigemptyset(&sig_action.sa_mask);
-    sig_action.sa_handler = SIG_DFL;
-    sigaction(SIGABRT, &sig_action, NULL);
-#elif defined(GLOG_OS_WINDOWS)
-    signal(SIGABRT, SIG_DFL);
-#endif  // HAVE_SIGACTION
-  }
-
-  abort();
-}
-
-_END_GOOGLE_NAMESPACE_
-
-#endif  // HAVE_STACKTRACE
-
-_START_GOOGLE_NAMESPACE_
-
-namespace glog_internal_namespace_ {
-
-const char* ProgramInvocationShortName() {
-  if (g_program_invocation_short_name != NULL) {
-    return g_program_invocation_short_name;
-  } else {
-    // TODO(hamaji): Use /proc/self/cmdline and so?
-    return "UNKNOWN";
-  }
-}
-
-#ifdef GLOG_OS_WINDOWS
-struct timeval {
-  long tv_sec, tv_usec;
-};
-
-// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd
-// See COPYING for copyright information.
-static int gettimeofday(struct timeval *tv, void* /*tz*/) {
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlong-long"
-#endif
-#define EPOCHFILETIME (116444736000000000ULL)
-  FILETIME ft;
-  ULARGE_INTEGER li;
-  uint64 tt;
-
-  GetSystemTimeAsFileTime(&ft);
-  li.LowPart = ft.dwLowDateTime;
-  li.HighPart = ft.dwHighDateTime;
-  tt = (li.QuadPart - EPOCHFILETIME) / 10;
-  tv->tv_sec = tt / 1000000;
-  tv->tv_usec = tt % 1000000;
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
-  return 0;
-}
-#endif
-
-int64 CycleClock_Now() {
-  // TODO(hamaji): temporary impementation - it might be too slow.
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
-}
-
-int64 UsecToCycles(int64 usec) {
-  return usec;
-}
-
-WallTime WallTime_Now() {
-  // Now, cycle clock is retuning microseconds since the epoch.
-  return CycleClock_Now() * 0.000001;
-}
-
-static int32 g_main_thread_pid = getpid();
-int32 GetMainThreadPid() {
-  return g_main_thread_pid;
-}
-
-bool PidHasChanged() {
-  int32 pid = getpid();
-  if (g_main_thread_pid == pid) {
-    return false;
-  }
-  g_main_thread_pid = pid;
-  return true;
-}
-
-pid_t GetTID() {
-  // On Linux and MacOSX, we try to use gettid().
-#if defined GLOG_OS_LINUX || defined GLOG_OS_MACOSX
-#ifndef __NR_gettid
-#ifdef GLOG_OS_MACOSX
-#define __NR_gettid SYS_gettid
-#elif ! defined __i386__
-#error "Must define __NR_gettid for non-x86 platforms"
-#else
-#define __NR_gettid 224
-#endif
-#endif
-  static bool lacks_gettid = false;
-  if (!lacks_gettid) {
-#if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP))
-    uint64_t tid64;
-    const int error = pthread_threadid_np(NULL, &tid64);
-    pid_t tid = error ? -1 : static_cast<pid_t>(tid64);
-#else
-    pid_t tid = static_cast<pid_t>(syscall(__NR_gettid));
-#endif
-    if (tid != -1) {
-      return tid;
-    }
-    // Technically, this variable has to be volatile, but there is a small
-    // performance penalty in accessing volatile variables and there should
-    // not be any serious adverse effect if a thread does not immediately see
-    // the value change to "true".
-    lacks_gettid = true;
-  }
-#endif  // GLOG_OS_LINUX || GLOG_OS_MACOSX
-
-  // If gettid() could not be used, we use one of the following.
-#if defined GLOG_OS_LINUX
-  return getpid();  // Linux:  getpid returns thread ID when gettid is absent
-#elif defined GLOG_OS_WINDOWS && !defined GLOG_OS_CYGWIN
-  return static_cast<pid_t>(GetCurrentThreadId());
-#elif defined(HAVE_PTHREAD)
-  // If none of the techniques above worked, we use pthread_self().
-  return (pid_t)(uintptr_t)pthread_self();
-#else
-  return -1;
-#endif
-}
-
-const char* const_basename(const char* filepath) {
-  const char* base = strrchr(filepath, '/');
-#ifdef GLOG_OS_WINDOWS  // Look for either path separator in Windows
-  if (!base)
-    base = strrchr(filepath, '\\');
-#endif
-  return base ? (base+1) : filepath;
-}
-
-static string g_my_user_name;
-const string& MyUserName() {
-  return g_my_user_name;
-}
-static void MyUserNameInitializer() {
-  // TODO(hamaji): Probably this is not portable.
-#if defined(GLOG_OS_WINDOWS)
-  const char* user = getenv("USERNAME");
-#else
-  const char* user = getenv("USER");
-#endif
-  if (user != NULL) {
-    g_my_user_name = user;
-  } else {
-#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H)
-    struct passwd pwd;
-    struct passwd* result = NULL;
-    char buffer[1024] = {'\0'};
-    uid_t uid = geteuid();
-    int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result);
-    if (pwuid_res == 0 && result) {
-      g_my_user_name = pwd.pw_name;
-    } else {
-      snprintf(buffer, sizeof(buffer), "uid%d", uid);
-      g_my_user_name = buffer;
-    }
-#endif
-    if (g_my_user_name.empty()) {
-      g_my_user_name = "invalid-user";
-    }
-  }
-
-}
-REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer())
-
-#ifdef HAVE_STACKTRACE
-void DumpStackTraceToString(string* stacktrace) {
-  DumpStackTrace(1, DebugWriteToString, stacktrace);
-}
-#endif
-
-// We use an atomic operation to prevent problems with calling CrashReason
-// from inside the Mutex implementation (potentially through RAW_CHECK).
-static const CrashReason* g_reason = 0;
-
-void SetCrashReason(const CrashReason* r) {
-  sync_val_compare_and_swap(&g_reason,
-                            reinterpret_cast<const CrashReason*>(0),
-                            r);
-}
-
-void InitGoogleLoggingUtilities(const char* argv0) {
-  CHECK(!IsGoogleLoggingInitialized())
-      << "You called InitGoogleLogging() twice!";
-  const char* slash = strrchr(argv0, '/');
-#ifdef GLOG_OS_WINDOWS
-  if (!slash)  slash = strrchr(argv0, '\\');
-#endif
-  g_program_invocation_short_name = slash ? slash + 1 : argv0;
-
-#ifdef HAVE_STACKTRACE
-  InstallFailureFunction(&DumpStackTraceAndExit);
-#endif
-}
-
-void ShutdownGoogleLoggingUtilities() {
-  CHECK(IsGoogleLoggingInitialized())
-      << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
-  g_program_invocation_short_name = NULL;
-#ifdef HAVE_SYSLOG_H
-  closelog();
-#endif
-}
-
-}  // namespace glog_internal_namespace_
-
-_END_GOOGLE_NAMESPACE_
-
-// Make an implementation of stacktrace compiled.
-#ifdef STACKTRACE_H
-# include STACKTRACE_H
-# if 0
-// For include scanners which can't handle macro expansions.
-#  include "stacktrace_libunwind-inl.h"
-#  include "stacktrace_x86-inl.h"
-#  include "stacktrace_x86_64-inl.h"
-#  include "stacktrace_powerpc-inl.h"
-#  include "stacktrace_generic-inl.h"
-# endif
-#endif
diff --git a/third_party/google-glog/src/utilities.h b/third_party/google-glog/src/utilities.h
deleted file mode 100644
index 760c142..0000000
--- a/third_party/google-glog/src/utilities.h
+++ /dev/null
@@ -1,217 +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: Shinichiro Hamaji
-//
-// Define utilties for glog internal usage.
-
-#ifndef UTILITIES_H__
-#define UTILITIES_H__
-
-// printf macros for size_t, in the style of inttypes.h
-#ifdef _LP64
-#define __PRIS_PREFIX "z"
-#else
-#define __PRIS_PREFIX
-#endif
-
-// Use these macros after a % in a printf format string
-// to get correct 32/64 bit behavior, like this:
-// size_t size = records.size();
-// printf("%"PRIuS"\n", size);
-
-#define PRIdS __PRIS_PREFIX "d"
-#define PRIxS __PRIS_PREFIX "x"
-#define PRIuS __PRIS_PREFIX "u"
-#define PRIXS __PRIS_PREFIX "X"
-#define PRIoS __PRIS_PREFIX "o"
-
-#include "base/mutex.h"  // This must go first so we get _XOPEN_SOURCE
-
-#include <string>
-
-#include <glog/logging.h>
-
-#if defined(GLOG_OS_WINDOWS)
-# include "port.h"
-#endif
-
-#include "config.h"
-
-// There are three different ways we can try to get the stack trace:
-//
-// 1) The libunwind library.  This is still in development, and as a
-//    separate library adds a new dependency, but doesn't need a frame
-//    pointer.  It also doesn't call malloc.
-//
-// 2) 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.
-//
-// 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().
-//
-// 4) The Windows API CaptureStackTrace.
-//
-// 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.
-
-#if defined(HAVE_LIB_UNWIND)
-# define STACKTRACE_H "stacktrace_libunwind-inl.h"
-#elif defined(HAVE__UNWIND_BACKTRACE) && defined(HAVE__UNWIND_GETIP)
-# define STACKTRACE_H "stacktrace_unwind-inl.h"
-#elif !defined(NO_FRAME_POINTER)
-# if defined(__i386__) && __GNUC__ >= 2
-#  define STACKTRACE_H "stacktrace_x86-inl.h"
-# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
-#  define STACKTRACE_H "stacktrace_powerpc-inl.h"
-# elif defined(GLOG_OS_WINDOWS)
-#  define STACKTRACE_H "stacktrace_windows-inl.h"
-# endif
-#endif
-
-#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_BACKTRACE)
-# define STACKTRACE_H "stacktrace_generic-inl.h"
-#endif
-
-#if defined(STACKTRACE_H)
-# define HAVE_STACKTRACE
-#endif
-
-#ifndef GLOG_NO_SYMBOLIZE_DETECTION
-#ifndef HAVE_SYMBOLIZE
-// defined by gcc
-#if defined(__ELF__) && defined(GLOG_OS_LINUX)
-# define HAVE_SYMBOLIZE
-#elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
-// Use dladdr to symbolize.
-# define HAVE_SYMBOLIZE
-#elif defined(GLOG_OS_WINDOWS)
-// Use DbgHelp to symbolize
-# define HAVE_SYMBOLIZE
-#endif
-#endif // !defined(HAVE_SYMBOLIZE)
-#endif // !defined(GLOG_NO_SYMBOLIZE_DETECTION)
-
-#ifndef ARRAYSIZE
-// There is a better way, but this is good enough for our purpose.
-# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
-#endif
-
-_START_GOOGLE_NAMESPACE_
-
-namespace glog_internal_namespace_ {
-
-#ifdef HAVE___ATTRIBUTE__
-# define ATTRIBUTE_NOINLINE __attribute__ ((noinline))
-# define HAVE_ATTRIBUTE_NOINLINE
-#elif defined(GLOG_OS_WINDOWS)
-# define ATTRIBUTE_NOINLINE __declspec(noinline)
-# define HAVE_ATTRIBUTE_NOINLINE
-#else
-# define ATTRIBUTE_NOINLINE
-#endif
-
-const char* ProgramInvocationShortName();
-
-int64 CycleClock_Now();
-
-int64 UsecToCycles(int64 usec);
-WallTime WallTime_Now();
-
-int32 GetMainThreadPid();
-bool PidHasChanged();
-
-pid_t GetTID();
-
-const std::string& MyUserName();
-
-// Get the part of filepath after the last path separator.
-// (Doesn't modify filepath, contrary to basename() in libgen.h.)
-const char* const_basename(const char* filepath);
-
-// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
-// defined, we try the CPU specific logics (we only support x86 and
-// x86_64 for now) first, then use a naive implementation, which has a
-// race condition.
-template<typename T>
-inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
-#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
-  return __sync_val_compare_and_swap(ptr, oldval, newval);
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-  T ret;
-  __asm__ __volatile__("lock; cmpxchg %1, (%2);"
-                       :"=a"(ret)
-                        // GCC may produces %sil or %dil for
-                        // constraint "r", but some of apple's gas
-                        // dosn't know the 8 bit registers.
-                        // We use "q" to avoid these registers.
-                       :"q"(newval), "q"(ptr), "a"(oldval)
-                       :"memory", "cc");
-  return ret;
-#else
-  T ret = *ptr;
-  if (ret == oldval) {
-    *ptr = newval;
-  }
-  return ret;
-#endif
-}
-
-void DumpStackTraceToString(std::string* stacktrace);
-
-struct CrashReason {
-  CrashReason() : filename(0), line_number(0), message(0), depth(0) {}
-
-  const char* filename;
-  int line_number;
-  const char* message;
-
-  // We'll also store a bit of stack trace context at the time of crash as
-  // it may not be available later on.
-  void* stack[32];
-  int depth;
-};
-
-void SetCrashReason(const CrashReason* r);
-
-void InitGoogleLoggingUtilities(const char* argv0);
-void ShutdownGoogleLoggingUtilities();
-
-}  // namespace glog_internal_namespace_
-
-_END_GOOGLE_NAMESPACE_
-
-using namespace GOOGLE_NAMESPACE::glog_internal_namespace_;
-
-#endif  // UTILITIES_H__
diff --git a/third_party/google-glog/src/utilities_unittest.cc b/third_party/google-glog/src/utilities_unittest.cc
deleted file mode 100644
index 93b1acd..0000000
--- a/third_party/google-glog/src/utilities_unittest.cc
+++ /dev/null
@@ -1,58 +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: Shinichiro Hamaji
-#include "utilities.h"
-#include "googletest.h"
-#include <glog/logging.h>
-
-#ifdef HAVE_LIB_GFLAGS
-#include <gflags/gflags.h>
-using namespace GFLAGS_NAMESPACE;
-#endif
-
-using namespace GOOGLE_NAMESPACE;
-
-TEST(utilities, sync_val_compare_and_swap) {
-  bool now_entering = false;
-  EXPECT_FALSE(sync_val_compare_and_swap(&now_entering, false, true));
-  EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true));
-  EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true));
-}
-
-TEST(utilities, InitGoogleLoggingDeathTest) {
-  ASSERT_DEATH(InitGoogleLogging("foobar"), "");
-}
-
-int main(int argc, char **argv) {
-  InitGoogleLogging(argv[0]);
-  InitGoogleTest(&argc, argv);
-
-  CHECK_EQ(RUN_ALL_TESTS(), 0);
-}
diff --git a/third_party/google-glog/src/vlog_is_on.cc b/third_party/google-glog/src/vlog_is_on.cc
deleted file mode 100644
index e478a36..0000000
--- a/third_party/google-glog/src/vlog_is_on.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (c) 1999, 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: Ray Sidney and many others
-//
-// Broken out from logging.cc by Soren Lassen
-// logging_unittest.cc covers the functionality herein
-
-#include "utilities.h"
-
-#include <cstring>
-#include <cstdlib>
-#include <cerrno>
-#include <cstdio>
-#include <string>
-#include "base/commandlineflags.h"
-#include <glog/logging.h>
-#include <glog/raw_logging.h>
-#include "base/googleinit.h"
-
-// glog doesn't have annotation
-#define ANNOTATE_BENIGN_RACE(address, description)
-
-using std::string;
-
-GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this."
-" Overridable by --vmodule.");
-
-GLOG_DEFINE_string(vmodule, "", "per-module verbose level."
-" Argument is a comma-separated list of <module name>=<log level>."
-" <module name> is a glob pattern, matched against the filename base"
-" (that is, name ignoring .cc/.h./-inl.h)."
-" <log level> overrides any value given by --v.");
-
-_START_GOOGLE_NAMESPACE_
-
-namespace glog_internal_namespace_ {
-
-// Used by logging_unittests.cc so can't make it static here.
-GLOG_EXPORT bool SafeFNMatch_(const char* pattern, size_t patt_len,
-                              const char* str, size_t str_len);
-
-// Implementation of fnmatch that does not need 0-termination
-// of arguments and does not allocate any memory,
-// but we only support "*" and "?" wildcards, not the "[...]" patterns.
-// It's not a static function for the unittest.
-GLOG_EXPORT bool SafeFNMatch_(const char* pattern, size_t patt_len,
-                              const char* str, size_t str_len) {
-  size_t p = 0;
-  size_t s = 0;
-  while (1) {
-    if (p == patt_len  &&  s == str_len) return true;
-    if (p == patt_len) return false;
-    if (s == str_len) return p+1 == patt_len  &&  pattern[p] == '*';
-    if (pattern[p] == str[s]  ||  pattern[p] == '?') {
-      p += 1;
-      s += 1;
-      continue;
-    }
-    if (pattern[p] == '*') {
-      if (p+1 == patt_len) return true;
-      do {
-        if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) {
-          return true;
-        }
-        s += 1;
-      } while (s != str_len);
-      return false;
-    }
-    return false;
-  }
-}
-
-}  // namespace glog_internal_namespace_
-
-using glog_internal_namespace_::SafeFNMatch_;
-
-// List of per-module log levels from FLAGS_vmodule.
-// Once created each element is never deleted/modified
-// except for the vlog_level: other threads will read VModuleInfo blobs
-// w/o locks and we'll store pointers to vlog_level at VLOG locations
-// that will never go away.
-// We can't use an STL struct here as we wouldn't know
-// when it's safe to delete/update it: other threads need to use it w/o locks.
-struct VModuleInfo {
-  string module_pattern;
-  mutable int32 vlog_level;  // Conceptually this is an AtomicWord, but it's
-                             // too much work to use AtomicWord type here
-                             // w/o much actual benefit.
-  const VModuleInfo* next;
-};
-
-// This protects the following global variables.
-static Mutex vmodule_lock;
-// Pointer to head of the VModuleInfo list.
-// It's a map from module pattern to logging level for those module(s).
-static VModuleInfo* vmodule_list = 0;
-static SiteFlag* cached_site_list = 0;
-
-// Boolean initialization flag.
-static bool inited_vmodule = false;
-
-// L >= vmodule_lock.
-static void VLOG2Initializer() {
-  vmodule_lock.AssertHeld();
-  // Can now parse --vmodule flag and initialize mapping of module-specific
-  // logging levels.
-  inited_vmodule = false;
-  const char* vmodule = FLAGS_vmodule.c_str();
-  const char* sep;
-  VModuleInfo* head = NULL;
-  VModuleInfo* tail = NULL;
-  while ((sep = strchr(vmodule, '=')) != NULL) {
-    string pattern(vmodule, static_cast<size_t>(sep - vmodule));
-    int module_level;
-    if (sscanf(sep, "=%d", &module_level) == 1) {
-      VModuleInfo* info = new VModuleInfo;
-      info->module_pattern = pattern;
-      info->vlog_level = module_level;
-      if (head) {
-        tail->next = info;
-      } else {
-        head = info;
-      }
-      tail = info;
-    }
-    // Skip past this entry
-    vmodule = strchr(sep, ',');
-    if (vmodule == NULL) break;
-    vmodule++;  // Skip past ","
-  }
-  if (head) {  // Put them into the list at the head:
-    tail->next = vmodule_list;
-    vmodule_list = head;
-  }
-  inited_vmodule = true;
-}
-
-// This can be called very early, so we use SpinLock and RAW_VLOG here.
-int SetVLOGLevel(const char* module_pattern, int log_level) {
-  int result = FLAGS_v;
-  size_t const pattern_len = strlen(module_pattern);
-  bool found = false;
-  {
-    MutexLock l(&vmodule_lock);  // protect whole read-modify-write
-    for (const VModuleInfo* info = vmodule_list;
-         info != NULL; info = info->next) {
-      if (info->module_pattern == module_pattern) {
-        if (!found) {
-          result = info->vlog_level;
-          found = true;
-        }
-        info->vlog_level = log_level;
-      } else if (!found  &&
-                 SafeFNMatch_(info->module_pattern.c_str(),
-                              info->module_pattern.size(),
-                              module_pattern, pattern_len)) {
-        result = info->vlog_level;
-        found = true;
-      }
-    }
-    if (!found) {
-      VModuleInfo* info = new VModuleInfo;
-      info->module_pattern = module_pattern;
-      info->vlog_level = log_level;
-      info->next = vmodule_list;
-      vmodule_list = info;
-
-      SiteFlag** item_ptr = &cached_site_list;
-      SiteFlag* item = cached_site_list;
-
-      // We traverse the list fully because the pattern can match several items
-      // from the list.
-      while (item) {
-        if (SafeFNMatch_(module_pattern, pattern_len, item->base_name,
-                         item->base_len)) {
-          // Redirect the cached value to its module override.
-          item->level = &info->vlog_level;
-          *item_ptr = item->next;  // Remove the item from the list.
-        } else {
-          item_ptr = &item->next;
-        }
-        item = *item_ptr;
-      }
-    }
-  }
-  RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level);
-  return result;
-}
-
-// NOTE: Individual VLOG statements cache the integer log level pointers.
-// NOTE: This function must not allocate memory or require any locks.
-bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
-                 const char* fname, int32 verbose_level) {
-  MutexLock l(&vmodule_lock);
-  bool read_vmodule_flag = inited_vmodule;
-  if (!read_vmodule_flag) {
-    VLOG2Initializer();
-  }
-
-  // protect the errno global in case someone writes:
-  // VLOG(..) << "The last error was " << strerror(errno)
-  int old_errno = errno;
-
-  // site_default normally points to FLAGS_v
-  int32* site_flag_value = level_default;
-
-  // Get basename for file
-  const char* base = strrchr(fname, '/');
-
-#ifdef _WIN32
-  if (!base) {
-    base = strrchr(fname, '\\');
-  }
-#endif
-
-  base = base ? (base+1) : fname;
-  const char* base_end = strchr(base, '.');
-  size_t base_length = base_end ? size_t(base_end - base) : strlen(base);
-
-  // Trim out trailing "-inl" if any
-  if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
-    base_length -= 4;
-  }
-
-  // TODO: Trim out _unittest suffix?  Perhaps it is better to have
-  // the extra control and just leave it there.
-
-  // find target in vector of modules, replace site_flag_value with
-  // a module-specific verbose level, if any.
-  for (const VModuleInfo* info = vmodule_list;
-       info != NULL; info = info->next) {
-    if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
-                     base, base_length)) {
-      site_flag_value = &info->vlog_level;
-        // value at info->vlog_level is now what controls
-        // the VLOG at the caller site forever
-      break;
-    }
-  }
-
-  // Cache the vlog value pointer if --vmodule flag has been parsed.
-  ANNOTATE_BENIGN_RACE(site_flag,
-                       "*site_flag may be written by several threads,"
-                       " but the value will be the same");
-  if (read_vmodule_flag) {
-    site_flag->level = site_flag_value;
-    // If VLOG flag has been cached to the default site pointer,
-    // we want to add to the cached list in order to invalidate in case
-    // SetVModule is called afterwards with new modules.
-    // The performance penalty here is neglible, because InitVLOG3__ is called
-    // once per site.
-    if (site_flag_value == level_default && !site_flag->base_name) {
-      site_flag->base_name = base;
-      site_flag->base_len = base_length;
-      site_flag->next = cached_site_list;
-      cached_site_list = site_flag;
-    }
-  }
-
-  // restore the errno in case something recoverable went wrong during
-  // the initialization of the VLOG mechanism (see above note "protect the..")
-  errno = old_errno;
-  return *site_flag_value >= verbose_level;
-}
-
-_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/windows/dirent.h b/third_party/google-glog/src/windows/dirent.h
deleted file mode 100644
index 12cf00a..0000000
--- a/third_party/google-glog/src/windows/dirent.h
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*
- * Dirent interface for Microsoft Visual Studio
- *
- * Copyright (C) 1998-2019 Toni Ronkko
- * This file is part of dirent.  Dirent may be freely distributed
- * under the MIT license.  For all details and documentation, see
- * https://github.com/tronkko/dirent
- */
-#ifndef DIRENT_H
-#define DIRENT_H
-
-/* Hide warnings about unreferenced local functions */
-#if defined(__clang__)
-#   pragma clang diagnostic ignored "-Wunused-function"
-#elif defined(_MSC_VER)
-#   pragma warning(disable:4505)
-#elif defined(__GNUC__)
-#   pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
-/*
- * Include windows.h without Windows Sockets 1.1 to prevent conflicts with
- * Windows Sockets 2.0.
- */
-#ifndef WIN32_LEAN_AND_MEAN
-#   define WIN32_LEAN_AND_MEAN
-#endif
-#include <windows.h>
-
-#include <cerrno>
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cwchar>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-/* Indicates that d_type field is available in dirent structure */
-#define _DIRENT_HAVE_D_TYPE
-
-/* Indicates that d_namlen field is available in dirent structure */
-#define _DIRENT_HAVE_D_NAMLEN
-
-/* Entries missing from MSVC 6.0 */
-#if !defined(FILE_ATTRIBUTE_DEVICE)
-#   define FILE_ATTRIBUTE_DEVICE 0x40
-#endif
-
-/* File type and permission flags for stat(), general mask */
-#if !defined(S_IFMT)
-#   define S_IFMT _S_IFMT
-#endif
-
-/* Directory bit */
-#if !defined(S_IFDIR)
-#   define S_IFDIR _S_IFDIR
-#endif
-
-/* Character device bit */
-#if !defined(S_IFCHR)
-#   define S_IFCHR _S_IFCHR
-#endif
-
-/* Pipe bit */
-#if !defined(S_IFFIFO)
-#   define S_IFFIFO _S_IFFIFO
-#endif
-
-/* Regular file bit */
-#if !defined(S_IFREG)
-#   define S_IFREG _S_IFREG
-#endif
-
-/* Read permission */
-#if !defined(S_IREAD)
-#   define S_IREAD _S_IREAD
-#endif
-
-/* Write permission */
-#if !defined(S_IWRITE)
-#   define S_IWRITE _S_IWRITE
-#endif
-
-/* Execute permission */
-#if !defined(S_IEXEC)
-#   define S_IEXEC _S_IEXEC
-#endif
-
-/* Pipe */
-#if !defined(S_IFIFO)
-#   define S_IFIFO _S_IFIFO
-#endif
-
-/* Block device */
-#if !defined(S_IFBLK)
-#   define S_IFBLK 0
-#endif
-
-/* Link */
-#if !defined(S_IFLNK)
-#   define S_IFLNK 0
-#endif
-
-/* Socket */
-#if !defined(S_IFSOCK)
-#   define S_IFSOCK 0
-#endif
-
-/* Read user permission */
-#if !defined(S_IRUSR)
-#   define S_IRUSR S_IREAD
-#endif
-
-/* Write user permission */
-#if !defined(S_IWUSR)
-#   define S_IWUSR S_IWRITE
-#endif
-
-/* Execute user permission */
-#if !defined(S_IXUSR)
-#   define S_IXUSR 0
-#endif
-
-/* Read group permission */
-#if !defined(S_IRGRP)
-#   define S_IRGRP 0
-#endif
-
-/* Write group permission */
-#if !defined(S_IWGRP)
-#   define S_IWGRP 0
-#endif
-
-/* Execute group permission */
-#if !defined(S_IXGRP)
-#   define S_IXGRP 0
-#endif
-
-/* Read others permission */
-#if !defined(S_IROTH)
-#   define S_IROTH 0
-#endif
-
-/* Write others permission */
-#if !defined(S_IWOTH)
-#   define S_IWOTH 0
-#endif
-
-/* Execute others permission */
-#if !defined(S_IXOTH)
-#   define S_IXOTH 0
-#endif
-
-/* Maximum length of file name */
-#if !defined(PATH_MAX)
-#   define PATH_MAX MAX_PATH
-#endif
-#if !defined(FILENAME_MAX)
-#   define FILENAME_MAX MAX_PATH
-#endif
-#if !defined(NAME_MAX)
-#   define NAME_MAX FILENAME_MAX
-#endif
-
-/* File type flags for d_type */
-#define DT_UNKNOWN 0
-#define DT_REG S_IFREG
-#define DT_DIR S_IFDIR
-#define DT_FIFO S_IFIFO
-#define DT_SOCK S_IFSOCK
-#define DT_CHR S_IFCHR
-#define DT_BLK S_IFBLK
-#define DT_LNK S_IFLNK
-
-/* Macros for converting between st_mode and d_type */
-#define IFTODT(mode) ((mode) & S_IFMT)
-#define DTTOIF(type) (type)
-
-/*
- * File type macros.  Note that block devices, sockets and links cannot be
- * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
- * only defined for compatibility.  These macros should always return false
- * on Windows.
- */
-#if !defined(S_ISFIFO)
-#   define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
-#endif
-#if !defined(S_ISDIR)
-#   define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#endif
-#if !defined(S_ISREG)
-#   define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
-#endif
-#if !defined(S_ISLNK)
-#   define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
-#endif
-#if !defined(S_ISSOCK)
-#   define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
-#endif
-#if !defined(S_ISCHR)
-#   define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
-#endif
-#if !defined(S_ISBLK)
-#   define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
-#endif
-
-/* Return the exact length of the file name without zero terminator */
-#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
-
-/* Return the maximum size of a file name */
-#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Wide-character version */
-struct _wdirent {
-    /* Always zero */
-    long d_ino;
-
-    /* File position within stream */
-    long d_off;
-
-    /* Structure size */
-    unsigned short d_reclen;
-
-    /* Length of name without \0 */
-    size_t d_namlen;
-
-    /* File type */
-    int d_type;
-
-    /* File name */
-    wchar_t d_name[PATH_MAX+1];
-};
-typedef struct _wdirent _wdirent;
-
-struct _WDIR {
-    /* Current directory entry */
-    struct _wdirent ent;
-
-    /* Private file data */
-    WIN32_FIND_DATAW data;
-
-    /* True if data is valid */
-    int cached;
-
-    /* Win32 search handle */
-    HANDLE handle;
-
-    /* Initial directory name */
-    wchar_t *patt;
-};
-typedef struct _WDIR _WDIR;
-
-/* Multi-byte character version */
-struct dirent {
-    /* Always zero */
-    long d_ino;
-
-    /* File position within stream */
-    long d_off;
-
-    /* Structure size */
-    unsigned short d_reclen;
-
-    /* Length of name without \0 */
-    size_t d_namlen;
-
-    /* File type */
-    int d_type;
-
-    /* File name */
-    char d_name[PATH_MAX+1];
-};
-typedef struct dirent dirent;
-
-struct DIR {
-    struct dirent ent;
-    struct _WDIR *wdirp;
-};
-typedef struct DIR DIR;
-
-
-/* Dirent functions */
-static DIR *opendir (const char *dirname);
-static _WDIR *_wopendir (const wchar_t *dirname);
-
-static struct dirent *readdir (DIR *dirp);
-static struct _wdirent *_wreaddir (_WDIR *dirp);
-
-static int readdir_r(
-    DIR *dirp, struct dirent *entry, struct dirent **result);
-static int _wreaddir_r(
-    _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result);
-
-static int closedir (DIR *dirp);
-static int _wclosedir (_WDIR *dirp);
-
-static void rewinddir (DIR* dirp);
-static void _wrewinddir (_WDIR* dirp);
-
-static int scandir (const char *dirname, struct dirent ***namelist,
-    int (*filter)(const struct dirent*),
-    int (*compare)(const struct dirent**, const struct dirent**));
-
-static int alphasort (const struct dirent **a, const struct dirent **b);
-
-static int versionsort (const struct dirent **a, const struct dirent **b);
-
-
-/* For compatibility with Symbian */
-#define wdirent _wdirent
-#define WDIR _WDIR
-#define wopendir _wopendir
-#define wreaddir _wreaddir
-#define wclosedir _wclosedir
-#define wrewinddir _wrewinddir
-
-
-/* Internal utility functions */
-static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
-static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
-
-static int dirent_mbstowcs_s(
-    size_t *pReturnValue,
-    wchar_t *wcstr,
-    size_t sizeInWords,
-    const char *mbstr,
-    size_t count);
-
-static int dirent_wcstombs_s(
-    size_t *pReturnValue,
-    char *mbstr,
-    size_t sizeInBytes,
-    const wchar_t *wcstr,
-    size_t count);
-
-static void dirent_set_errno (int error);
-
-
-/*
- * Open directory stream DIRNAME for read and return a pointer to the
- * internal working area that is used to retrieve individual directory
- * entries.
- */
-static _WDIR*
-_wopendir(
-    const wchar_t *dirname)
-{
-    _WDIR *dirp;
-    DWORD n;
-    wchar_t *p;
-
-    /* Must have directory name */
-    if (dirname == NULL  ||  dirname[0] == '\0') {
-        dirent_set_errno (ENOENT);
-        return NULL;
-    }
-
-    /* Allocate new _WDIR structure */
-    dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
-    if (!dirp) {
-        return NULL;
-    }
-
-    /* Reset _WDIR structure */
-    dirp->handle = INVALID_HANDLE_VALUE;
-    dirp->patt = NULL;
-    dirp->cached = 0;
-
-    /*
-     * Compute the length of full path plus zero terminator
-     *
-     * Note that on WinRT there's no way to convert relative paths
-     * into absolute paths, so just assume it is an absolute path.
-     */
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-    /* Desktop */
-    n = GetFullPathNameW (dirname, 0, NULL, NULL);
-#else
-    /* WinRT */
-    n = wcslen (dirname);
-#endif
-
-    /* Allocate room for absolute directory name and search pattern */
-    dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
-    if (dirp->patt == NULL) {
-        goto exit_closedir;
-    }
-
-    /*
-     * Convert relative directory name to an absolute one.  This
-     * allows rewinddir() to function correctly even when current
-     * working directory is changed between opendir() and rewinddir().
-     *
-     * Note that on WinRT there's no way to convert relative paths
-     * into absolute paths, so just assume it is an absolute path.
-     */
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-    /* Desktop */
-    n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
-    if (n <= 0) {
-        goto exit_closedir;
-    }
-#else
-    /* WinRT */
-    wcsncpy_s (dirp->patt, n+1, dirname, n);
-#endif
-
-    /* Append search pattern \* to the directory name */
-    p = dirp->patt + n;
-    switch (p[-1]) {
-    case '\\':
-    case '/':
-    case ':':
-        /* Directory ends in path separator, e.g. c:\temp\ */
-        /*NOP*/;
-        break;
-
-    default:
-        /* Directory name doesn't end in path separator */
-        *p++ = '\\';
-    }
-    *p++ = '*';
-    *p = '\0';
-
-    /* Open directory stream and retrieve the first entry */
-    if (!dirent_first (dirp)) {
-        goto exit_closedir;
-    }
-
-    /* Success */
-    return dirp;
-
-    /* Failure */
-exit_closedir:
-    _wclosedir (dirp);
-    return NULL;
-}
-
-/*
- * Read next directory entry.
- *
- * Returns pointer to static directory entry which may be overwritten by
- * subsequent calls to _wreaddir().
- */
-static struct _wdirent*
-_wreaddir(
-    _WDIR *dirp)
-{
-    struct _wdirent *entry;
-
-    /*
-     * Read directory entry to buffer.  We can safely ignore the return value
-     * as entry will be set to NULL in case of error.
-     */
-    (void) _wreaddir_r (dirp, &dirp->ent, &entry);
-
-    /* Return pointer to statically allocated directory entry */
-    return entry;
-}
-
-/*
- * Read next directory entry.
- *
- * Returns zero on success.  If end of directory stream is reached, then sets
- * result to NULL and returns zero.
- */
-static int
-_wreaddir_r(
-    _WDIR *dirp,
-    struct _wdirent *entry,
-    struct _wdirent **result)
-{
-    WIN32_FIND_DATAW *datap;
-
-    /* Read next directory entry */
-    datap = dirent_next (dirp);
-    if (datap) {
-        size_t n;
-        DWORD attr;
-
-        /*
-         * Copy file name as wide-character string.  If the file name is too
-         * long to fit in to the destination buffer, then truncate file name
-         * to PATH_MAX characters and zero-terminate the buffer.
-         */
-        n = 0;
-        while (n < PATH_MAX  &&  datap->cFileName[n] != 0) {
-            entry->d_name[n] = datap->cFileName[n];
-            n++;
-        }
-        entry->d_name[n] = 0;
-
-        /* Length of file name excluding zero terminator */
-        entry->d_namlen = n;
-
-        /* File type */
-        attr = datap->dwFileAttributes;
-        if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
-            entry->d_type = DT_CHR;
-        } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
-            entry->d_type = DT_DIR;
-        } else {
-            entry->d_type = DT_REG;
-        }
-
-        /* Reset dummy fields */
-        entry->d_ino = 0;
-        entry->d_off = 0;
-        entry->d_reclen = sizeof (struct _wdirent);
-
-        /* Set result address */
-        *result = entry;
-
-    } else {
-
-        /* Return NULL to indicate end of directory */
-        *result = NULL;
-
-    }
-
-    return /*OK*/0;
-}
-
-/*
- * Close directory stream opened by opendir() function.  This invalidates the
- * DIR structure as well as any directory entry read previously by
- * _wreaddir().
- */
-static int
-_wclosedir(
-    _WDIR *dirp)
-{
-    int ok;
-    if (dirp) {
-
-        /* Release search handle */
-        if (dirp->handle != INVALID_HANDLE_VALUE) {
-            FindClose (dirp->handle);
-        }
-
-        /* Release search pattern */
-        free (dirp->patt);
-
-        /* Release directory structure */
-        free (dirp);
-        ok = /*success*/0;
-
-    } else {
-
-        /* Invalid directory stream */
-        dirent_set_errno (EBADF);
-        ok = /*failure*/-1;
-
-    }
-    return ok;
-}
-
-/*
- * Rewind directory stream such that _wreaddir() returns the very first
- * file name again.
- */
-static void
-_wrewinddir(
-    _WDIR* dirp)
-{
-    if (dirp) {
-        /* Release existing search handle */
-        if (dirp->handle != INVALID_HANDLE_VALUE) {
-            FindClose (dirp->handle);
-        }
-
-        /* Open new search handle */
-        dirent_first (dirp);
-    }
-}
-
-/* Get first directory entry (internal) */
-static WIN32_FIND_DATAW*
-dirent_first(
-    _WDIR *dirp)
-{
-    WIN32_FIND_DATAW *datap;
-    DWORD error;
-
-    /* Open directory and retrieve the first entry */
-    dirp->handle = FindFirstFileExW(
-        dirp->patt, FindExInfoStandard, &dirp->data,
-        FindExSearchNameMatch, NULL, 0);
-    if (dirp->handle != INVALID_HANDLE_VALUE) {
-
-        /* a directory entry is now waiting in memory */
-        datap = &dirp->data;
-        dirp->cached = 1;
-
-    } else {
-
-        /* Failed to open directory: no directory entry in memory */
-        dirp->cached = 0;
-        datap = NULL;
-
-        /* Set error code */
-        error = GetLastError ();
-        switch (error) {
-        case ERROR_ACCESS_DENIED:
-            /* No read access to directory */
-            dirent_set_errno (EACCES);
-            break;
-
-        case ERROR_DIRECTORY:
-            /* Directory name is invalid */
-            dirent_set_errno (ENOTDIR);
-            break;
-
-        case ERROR_PATH_NOT_FOUND:
-        default:
-            /* Cannot find the file */
-            dirent_set_errno (ENOENT);
-        }
-
-    }
-    return datap;
-}
-
-/*
- * Get next directory entry (internal).
- *
- * Returns
- */
-static WIN32_FIND_DATAW*
-dirent_next(
-    _WDIR *dirp)
-{
-    WIN32_FIND_DATAW *p;
-
-    /* Get next directory entry */
-    if (dirp->cached != 0) {
-
-        /* A valid directory entry already in memory */
-        p = &dirp->data;
-        dirp->cached = 0;
-
-    } else if (dirp->handle != INVALID_HANDLE_VALUE) {
-
-        /* Get the next directory entry from stream */
-        if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
-            /* Got a file */
-            p = &dirp->data;
-        } else {
-            /* The very last entry has been processed or an error occurred */
-            FindClose (dirp->handle);
-            dirp->handle = INVALID_HANDLE_VALUE;
-            p = NULL;
-        }
-
-    } else {
-
-        /* End of directory stream reached */
-        p = NULL;
-
-    }
-
-    return p;
-}
-
-/*
- * Open directory stream using plain old C-string.
- */
-static DIR*
-opendir(
-    const char *dirname)
-{
-    struct DIR *dirp;
-
-    /* Must have directory name */
-    if (dirname == NULL  ||  dirname[0] == '\0') {
-        dirent_set_errno (ENOENT);
-        return NULL;
-    }
-
-    /* Allocate memory for DIR structure */
-    dirp = (DIR*) malloc (sizeof (struct DIR));
-    if (!dirp) {
-        return NULL;
-    }
-    {
-        int error;
-        wchar_t wname[PATH_MAX + 1];
-        size_t n;
-
-        /* Convert directory name to wide-character string */
-        error = dirent_mbstowcs_s(
-            &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1);
-        if (error) {
-            /*
-             * Cannot convert file name to wide-character string.  This
-             * occurs if the string contains invalid multi-byte sequences or
-             * the output buffer is too small to contain the resulting
-             * string.
-             */
-            goto exit_free;
-        }
-
-
-        /* Open directory stream using wide-character name */
-        dirp->wdirp = _wopendir (wname);
-        if (!dirp->wdirp) {
-            goto exit_free;
-        }
-
-    }
-
-    /* Success */
-    return dirp;
-
-    /* Failure */
-exit_free:
-    free (dirp);
-    return NULL;
-}
-
-/*
- * Read next directory entry.
- */
-static struct dirent*
-readdir(
-    DIR *dirp)
-{
-    struct dirent *entry;
-
-    /*
-     * Read directory entry to buffer.  We can safely ignore the return value
-     * as entry will be set to NULL in case of error.
-     */
-    (void) readdir_r (dirp, &dirp->ent, &entry);
-
-    /* Return pointer to statically allocated directory entry */
-    return entry;
-}
-
-/*
- * Read next directory entry into called-allocated buffer.
- *
- * Returns zero on success.  If the end of directory stream is reached, then
- * sets result to NULL and returns zero.
- */
-static int
-readdir_r(
-    DIR *dirp,
-    struct dirent *entry,
-    struct dirent **result)
-{
-    WIN32_FIND_DATAW *datap;
-
-    /* Read next directory entry */
-    datap = dirent_next (dirp->wdirp);
-    if (datap) {
-        size_t n;
-        int error;
-
-        /* Attempt to convert file name to multi-byte string */
-        error = dirent_wcstombs_s(
-            &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1);
-
-        /*
-         * If the file name cannot be represented by a multi-byte string,
-         * then attempt to use old 8+3 file name.  This allows traditional
-         * Unix-code to access some file names despite of unicode
-         * characters, although file names may seem unfamiliar to the user.
-         *
-         * Be ware that the code below cannot come up with a short file
-         * name unless the file system provides one.  At least
-         * VirtualBox shared folders fail to do this.
-         */
-        if (error  &&  datap->cAlternateFileName[0] != '\0') {
-            error = dirent_wcstombs_s(
-                &n, entry->d_name, PATH_MAX + 1,
-                datap->cAlternateFileName, PATH_MAX + 1);
-        }
-
-        if (!error) {
-            DWORD attr;
-
-            /* Length of file name excluding zero terminator */
-            entry->d_namlen = n - 1;
-
-            /* File attributes */
-            attr = datap->dwFileAttributes;
-            if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
-                entry->d_type = DT_CHR;
-            } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
-                entry->d_type = DT_DIR;
-            } else {
-                entry->d_type = DT_REG;
-            }
-
-            /* Reset dummy fields */
-            entry->d_ino = 0;
-            entry->d_off = 0;
-            entry->d_reclen = sizeof (struct dirent);
-
-        } else {
-
-            /*
-             * Cannot convert file name to multi-byte string so construct
-             * an erroneous directory entry and return that.  Note that
-             * we cannot return NULL as that would stop the processing
-             * of directory entries completely.
-             */
-            entry->d_name[0] = '?';
-            entry->d_name[1] = '\0';
-            entry->d_namlen = 1;
-            entry->d_type = DT_UNKNOWN;
-            entry->d_ino = 0;
-            entry->d_off = -1;
-            entry->d_reclen = 0;
-
-        }
-
-        /* Return pointer to directory entry */
-        *result = entry;
-
-    } else {
-
-        /* No more directory entries */
-        *result = NULL;
-
-    }
-
-    return /*OK*/0;
-}
-
-/*
- * Close directory stream.
- */
-static int
-closedir(
-    DIR *dirp)
-{
-    int ok;
-    if (dirp) {
-
-        /* Close wide-character directory stream */
-        ok = _wclosedir (dirp->wdirp);
-        dirp->wdirp = NULL;
-
-        /* Release multi-byte character version */
-        free (dirp);
-
-    } else {
-
-        /* Invalid directory stream */
-        dirent_set_errno (EBADF);
-        ok = /*failure*/-1;
-
-    }
-    return ok;
-}
-
-/*
- * Rewind directory stream to beginning.
- */
-static void
-rewinddir(
-    DIR* dirp)
-{
-    /* Rewind wide-character string directory stream */
-    _wrewinddir (dirp->wdirp);
-}
-
-/*
- * Scan directory for entries.
- */
-static int
-scandir(
-    const char *dirname,
-    struct dirent ***namelist,
-    int (*filter)(const struct dirent*),
-    int (*compare)(const struct dirent**, const struct dirent**))
-{
-    struct dirent **files = NULL;
-    size_t size = 0;
-    size_t allocated = 0;
-    const size_t init_size = 1;
-    DIR *dir = NULL;
-    struct dirent *entry;
-    struct dirent *tmp = NULL;
-    size_t i;
-    int result = 0;
-
-    /* Open directory stream */
-    dir = opendir (dirname);
-    if (dir) {
-
-        /* Read directory entries to memory */
-        while (1) {
-
-            /* Enlarge pointer table to make room for another pointer */
-            if (size >= allocated) {
-                void *p;
-                size_t num_entries;
-
-                /* Compute number of entries in the enlarged pointer table */
-                if (size < init_size) {
-                    /* Allocate initial pointer table */
-                    num_entries = init_size;
-                } else {
-                    /* Double the size */
-                    num_entries = size * 2;
-                }
-
-                /* Allocate first pointer table or enlarge existing table */
-                p = realloc (files, sizeof (void*) * num_entries);
-                if (p != NULL) {
-                    /* Got the memory */
-                    files = (dirent**) p;
-                    allocated = num_entries;
-                } else {
-                    /* Out of memory */
-                    result = -1;
-                    break;
-                }
-
-            }
-
-            /* Allocate room for temporary directory entry */
-            if (tmp == NULL) {
-                tmp = (struct dirent*) malloc (sizeof (struct dirent));
-                if (tmp == NULL) {
-                    /* Cannot allocate temporary directory entry */
-                    result = -1;
-                    break;
-                }
-            }
-
-            /* Read directory entry to temporary area */
-            if (readdir_r (dir, tmp, &entry) == /*OK*/0) {
-
-                /* Did we get an entry? */
-                if (entry != NULL) {
-                    int pass;
-
-                    /* Determine whether to include the entry in result */
-                    if (filter) {
-                        /* Let the filter function decide */
-                        pass = filter (tmp);
-                    } else {
-                        /* No filter function, include everything */
-                        pass = 1;
-                    }
-
-                    if (pass) {
-                        /* Store the temporary entry to pointer table */
-                        files[size++] = tmp;
-                        tmp = NULL;
-
-                        /* Keep up with the number of files */
-                        result++;
-                    }
-
-                } else {
-
-                    /*
-                     * End of directory stream reached => sort entries and
-                     * exit.
-                     */
-                    qsort (files, size, sizeof (void*),
-                        (int (*) (const void*, const void*)) compare);
-                    break;
-
-                }
-
-            } else {
-                /* Error reading directory entry */
-                result = /*Error*/ -1;
-                break;
-            }
-
-        }
-
-    } else {
-        /* Cannot open directory */
-        result = /*Error*/ -1;
-    }
-
-    /* Release temporary directory entry */
-    free (tmp);
-
-    /* Release allocated memory on error */
-    if (result < 0) {
-        for (i = 0; i < size; i++) {
-            free (files[i]);
-        }
-        free (files);
-        files = NULL;
-    }
-
-    /* Close directory stream */
-    if (dir) {
-        closedir (dir);
-    }
-
-    /* Pass pointer table to caller */
-    if (namelist) {
-        *namelist = files;
-    }
-    return result;
-}
-
-/* Alphabetical sorting */
-static int
-alphasort(
-    const struct dirent **a, const struct dirent **b)
-{
-    return strcoll ((*a)->d_name, (*b)->d_name);
-}
-
-/* Sort versions */
-static int
-versionsort(
-    const struct dirent **a, const struct dirent **b)
-{
-    /* FIXME: implement strverscmp and use that */
-    return alphasort (a, b);
-}
-
-/* Convert multi-byte string to wide character string */
-static int
-dirent_mbstowcs_s(
-    size_t *pReturnValue,
-    wchar_t *wcstr,
-    size_t sizeInWords,
-    const char *mbstr,
-    size_t count)
-{
-    int error;
-
-#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
-
-    /* Microsoft Visual Studio 2005 or later */
-    error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
-
-#else
-
-    /* Older Visual Studio or non-Microsoft compiler */
-    size_t n;
-
-    /* Convert to wide-character string (or count characters) */
-    n = mbstowcs (wcstr, mbstr, sizeInWords);
-    if (!wcstr  ||  n < count) {
-
-        /* Zero-terminate output buffer */
-        if (wcstr  &&  sizeInWords) {
-            if (n >= sizeInWords) {
-                n = sizeInWords - 1;
-            }
-            wcstr[n] = 0;
-        }
-
-        /* Length of resulting multi-byte string WITH zero terminator */
-        if (pReturnValue) {
-            *pReturnValue = n + 1;
-        }
-
-        /* Success */
-        error = 0;
-
-    } else {
-
-        /* Could not convert string */
-        error = 1;
-
-    }
-
-#endif
-    return error;
-}
-
-/* Convert wide-character string to multi-byte string */
-static int
-dirent_wcstombs_s(
-    size_t *pReturnValue,
-    char *mbstr,
-    size_t sizeInBytes, /* max size of mbstr */
-    const wchar_t *wcstr,
-    size_t count)
-{
-    int error;
-
-#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
-
-    /* Microsoft Visual Studio 2005 or later */
-    error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
-
-#else
-
-    /* Older Visual Studio or non-Microsoft compiler */
-    size_t n;
-
-    /* Convert to multi-byte string (or count the number of bytes needed) */
-    n = wcstombs (mbstr, wcstr, sizeInBytes);
-    if (!mbstr  ||  n < count) {
-
-        /* Zero-terminate output buffer */
-        if (mbstr  &&  sizeInBytes) {
-            if (n >= sizeInBytes) {
-                n = sizeInBytes - 1;
-            }
-            mbstr[n] = '\0';
-        }
-
-        /* Length of resulting multi-bytes string WITH zero-terminator */
-        if (pReturnValue) {
-            *pReturnValue = n + 1;
-        }
-
-        /* Success */
-        error = 0;
-
-    } else {
-
-        /* Cannot convert string */
-        error = 1;
-
-    }
-
-#endif
-    return error;
-}
-
-/* Set errno variable */
-static void
-dirent_set_errno(
-    int error)
-{
-#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
-
-    /* Microsoft Visual Studio 2005 and later */
-    _set_errno (error);
-
-#else
-
-    /* Non-Microsoft compiler or older Microsoft compiler */
-    errno = error;
-
-#endif
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif /*DIRENT_H*/
diff --git a/third_party/google-glog/src/windows/port.cc b/third_party/google-glog/src/windows/port.cc
deleted file mode 100755
index f0022e7..0000000
--- a/third_party/google-glog/src/windows/port.cc
+++ /dev/null
@@ -1,71 +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
- * Copied from google-perftools and modified by Shinichiro Hamaji
- */
-
-#ifndef _WIN32
-# error You should only be including windows/port.cc in a windows environment!
-#endif
-
-#include "config.h"
-#include <cstdarg>    // for va_list, va_start, va_end
-#include "port.h"
-
-// These call the windows _vsnprintf, but always NUL-terminate.
-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);
-}
-
-#ifndef HAVE_LOCALTIME_R
-struct tm* localtime_r(const time_t* timep, struct tm* result) {
-  localtime_s(result, timep);
-  return result;
-}
-#endif // not HAVE_LOCALTIME_R
-#ifndef HAVE_GMTIME_R
-struct tm* gmtime_r(const time_t* timep, struct tm* result) {
-    gmtime_s(result, timep);
-    return result;
-}
-#endif // not HAVE_GMTIME_R
-#ifndef HAVE_SNPRINTF
-int snprintf(char *str, size_t size, const char *format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  const int r = vsnprintf(str, size, format, ap);
-  va_end(ap);
-  return r;
-}
-#endif
diff --git a/third_party/google-glog/src/windows/port.h b/third_party/google-glog/src/windows/port.h
deleted file mode 100755
index a71979f..0000000
--- a/third_party/google-glog/src/windows/port.h
+++ /dev/null
@@ -1,181 +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
- * Copied from google-perftools and modified by Shinichiro Hamaji
- *
- * 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 CTEMPLATE_WINDOWS_PORT_H_
-#define CTEMPLATE_WINDOWS_PORT_H_
-
-#include "config.h"
-
-#ifdef _WIN32
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
-#endif
-
-#include <windows.h>
-#include <winsock.h>         /* for gethostname */
-#include <io.h>              /* because we so often use open/close/etc */
-#include <direct.h>          /* for _getcwd() */
-#include <process.h>         /* for _getpid() */
-#include <cstdarg>          /* template_dictionary.cc uses va_copy */
-#include <cstdio>           /* read in vsnprintf decl. before redifining it */
-#include <cstring>          /* for _strnicmp(), strerror_s() */
-#include <ctime>            /* for localtime_s() */
-/* Note: the C++ #includes are all together at the bottom.  This file is
- * used by both C and C++ code, so we put all the C++ together.
- */
-
-#include <glog/logging.h>
-
-#ifdef _MSC_VER
-
-/* 4244: otherwise we get problems when substracting two size_t's to an int
- * 4251: it's complaining about a private struct I've chosen not to dllexport
- * 4355: we use this in a constructor, but we do it safely
- * 4715: for some reason VC++ stopped realizing you can't return after abort()
- * 4800: we know we're casting ints/char*'s to bools, and we're ok with that
- * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
- * 4312: Converting uint32_t to a pointer when testing %p
- * 4267: also subtracting two size_t to int
- * 4722: Destructor never returns due to abort()
- */
-#pragma warning(disable:4244 4251 4355 4715 4800 4996 4267 4312 4722)
-
-/* file I/O */
-#define PATH_MAX 1024
-#define access  _access
-#define getcwd  _getcwd
-#define open    _open
-#define read    _read
-#define write   _write
-#define lseek   _lseek
-#define close   _close
-#define popen   _popen
-#define pclose  _pclose
-#define R_OK    04           /* read-only (for access()) */
-#define S_ISDIR(m)  (((m) & _S_IFMT) == _S_IFDIR)
-
-#define O_WRONLY _O_WRONLY
-#define O_CREAT _O_CREAT
-#define O_EXCL _O_EXCL
-
-#ifndef __MINGW32__
-enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
-#endif
-#define S_IRUSR S_IREAD
-#define S_IWUSR S_IWRITE
-
-/* Not quite as lightweight as a hard-link, but more than good enough for us. */
-#define link(oldpath, newpath)  CopyFileA(oldpath, newpath, false)
-
-#define strcasecmp   _stricmp
-#define strncasecmp  _strnicmp
-
-/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */
-/* VC11 provides std::hash */
-#if defined(_MSC_VER) && (_MSC_VER < 1700)
-#define hash  hash_compare
-#endif
-
-/* Sleep is in ms, on windows */
-#define sleep(secs)  Sleep((secs) * 1000)
-
-/* 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 (!)).
- */
-#ifndef HAVE_SNPRINTF
-extern int GLOG_EXPORT snprintf(char* str, size_t size, const char* format,
-                                ...);
-#endif
-extern int GLOG_EXPORT safe_vsnprintf(char* str, size_t size,
-                                      const char* format, va_list ap);
-#define vsnprintf(str, size, format, ap)  safe_vsnprintf(str, size, format, ap)
-#ifndef va_copy
-#define va_copy(dst, src)  (dst) = (src)
-#endif
-
-/* Windows doesn't support specifying the number of buckets as a
- * hash_map constructor arg, so we leave this blank.
- */
-#define CTEMPLATE_SMALL_HASHTABLE
-
-#define DEFAULT_TEMPLATE_ROOTDIR  ".."
-
-// ----------------------------------- SYSTEM/PROCESS
-typedef int pid_t;
-#define getpid  _getpid
-
-#endif  // _MSC_VER
-
-// ----------------------------------- THREADS
-#if defined(HAVE_PTHREAD)
-# include <pthread.h>
-#else // no PTHREAD
-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
-#define pthread_self  GetCurrentThreadId
-#define pthread_equal(pthread_t_1, pthread_t_2)  ((pthread_t_1)==(pthread_t_2))
-#endif // HAVE_PTHREAD
-
-#ifndef HAVE_LOCALTIME_R
-extern GLOG_EXPORT struct tm* localtime_r(const time_t* timep,
-                                          struct tm* result);
-#endif // not HAVE_LOCALTIME_R
-
-#ifndef HAVE_GMTIME_R
-extern GLOG_EXPORT struct tm* gmtime_r(const time_t* timep, struct tm* result);
-#endif // not HAVE_GMTIME_R
-
-inline char* strerror_r(int errnum, char* buf, size_t buflen) {
-  strerror_s(buf, buflen, errnum);
-  return buf;
-}
-
-#ifndef __cplusplus
-/* I don't see how to get inlining for C code in MSVC.  Ah well. */
-#define inline
-#endif
-
-#endif  /* _WIN32 */
-
-#endif  /* CTEMPLATE_WINDOWS_PORT_H_ */
diff --git a/third_party/gperftools/.gitignore b/third_party/gperftools/.gitignore
deleted file mode 100644
index 5b14650..0000000
--- a/third_party/gperftools/.gitignore
+++ /dev/null
@@ -1,148 +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
-/pprof-symbolize
-/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_asserts_unittest
-/tcm_asserts_unittest.exe
-/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
diff --git a/third_party/gperftools/.travis.yml b/third_party/gperftools/.travis.yml
deleted file mode 100644
index 92e766b..0000000
--- a/third_party/gperftools/.travis.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-language: c++
-sudo: required
-dist: xenial
-script: ./autogen.sh && ./configure && make -j`getconf _NPROCESSORS_ONLN` && make check
diff --git a/third_party/gperftools/AUTHORS b/third_party/gperftools/AUTHORS
deleted file mode 100644
index 3995ed4..0000000
--- a/third_party/gperftools/AUTHORS
+++ /dev/null
@@ -1,2 +0,0 @@
-google-perftools@googlegroups.com
-
diff --git a/third_party/gperftools/BUILD b/third_party/gperftools/BUILD
deleted file mode 100644
index 680654a..0000000
--- a/third_party/gperftools/BUILD
+++ /dev/null
@@ -1,579 +0,0 @@
-licenses(["notice"])
-
-load("//tools/build_rules:select.bzl", "compiler_select", "cpu_select")
-load("//tools/build_rules:empty_main.bzl", "empty_main_if_asan")
-
-common_copts = [
-    # Stuff from their Makefile.
-    "-Wno-cast-align",
-    "-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",
-    "-Wno-unused-result",
-    "-fno-omit-frame-pointer",
-    "-DNDEBUG",
-    "-DENABLE_EMERGENCY_MALLOC",
-
-    # Stuff to make it work for us.
-    "-Ithird_party/gperftools/src/",
-    "-Ithird_party/empty_config_h",
-    "-Wno-unused-parameter",
-    "-Wno-missing-field-initializers",
-    "-Wno-unused-function",
-    "-Wno-unused-variable",
-    "-Wno-format-nonliteral",
-    "-Wno-switch-enum",
-    "-Wno-error=cast-align",
-    "-Wno-error=cast-qual",
-    "-Wno-cast-qual",
-    "-Wno-array-bounds",
-    "-Wno-cast-function-type",
-
-    # //build_tests:tcmalloc_build_test relies on this.
-    "-DENABLE_LARGE_ALLOC_REPORT=1",
-
-    # Stuff pulled out of config.h.
-    "-DGPERFTOOLS_CONFIG_H_=1",
-    "-DHAVE_BUILTIN_EXPECT=1",
-    "-DHAVE_DECL_MEMALIGN=1",
-    "-DHAVE_DECL_POSIX_MEMALIGN=1",
-    "-DHAVE_DECL_PVALLOC=1",
-    "-DHAVE_DECL_UNAME=1",
-    "-DHAVE_DECL_VALLOC=1",
-    "-DHAVE_DLFCN_H=1",
-    "-DHAVE_ELF32_VERSYM=1",
-    "-DHAVE_EXECINFO_H=1",
-    "-DHAVE_FCNTL_H=1",
-    "-DHAVE_FEATURES_H=1",
-    "-DHAVE_FORK=1",
-    "-DHAVE_GETEUID=1",
-    "-DHAVE_GLOB_H=1",
-    "-DHAVE_GRP_H=1",
-    "-DHAVE_INTTYPES_H=1",
-    "-DHAVE_LINUX_PTRACE_H=1",
-    "-DHAVE_LINUX_SIGEV_THREAD_ID=1",
-    "-DHAVE_MALLOC_H=1",
-    "-DHAVE_MEMORY_H=1",
-    "-DHAVE_MMAP=1",
-    "-DHAVE_NAMESPACES=1",
-    "-DHAVE_POLL_H=1",
-    "-DHAVE_PROGRAM_INVOCATION_NAME=1",
-    "-DHAVE_PTHREAD=1",
-    "-DHAVE_PWD_H=1",
-    "-DHAVE_SBRK=1",
-    "-DHAVE_SCHED_H=1",
-    "-DHAVE_STDINT_H=1",
-    "-DHAVE_STDLIB_H=1",
-    "-DHAVE_STRINGS_H=1",
-    "-DHAVE_STRING_H=1",
-    "-DHAVE_STRUCT_MALLINFO=1",
-    "-DHAVE_SYS_CDEFS_H=1",
-    "-DHAVE_SYS_PRCTL_H=1",
-    "-DHAVE_SYS_RESOURCE_H=1",
-    "-DHAVE_SYS_SOCKET_H=1",
-    "-DHAVE_SYS_STAT_H=1",
-    "-DHAVE_SYS_SYSCALL_H=1",
-    "-DHAVE_SYS_TYPES_H=1",
-    "-DHAVE_SYS_UCONTEXT_H=1",
-    "-DHAVE_SYS_WAIT_H=1",
-    "-DHAVE_TLS=1",
-    "-DHAVE_UCONTEXT_H=1",
-    "-DHAVE_UNISTD_H=1",
-    "-DHAVE_UNWIND_H=1",
-    "-DHAVE___ATTRIBUTE__=1",
-    "-DHAVE___ENVIRON=1",
-    "-DMALLOC_HOOK_MAYBE_VOLATILE=volatile",
-    "-DPERFTOOLS_DLL_DECL=",
-    "-DSTDC_HEADERS=1",
-    "-DSTL_NAMESPACE=std",
-    "-DPACKAGE_STRING=\\\"gperftools\\ 2.9.1\\\"",
-    "-DPACKAGE_BUGREPORT=\\\"https://frc971.org/contact\\\"",
-    "-DPACKAGE_VERSION=\\\"2.9.1\\\"",
-] + cpu_select({
-    "amd64": [
-        "-DHAVE_GETPAGESZE=1",
-        "-DHAVE_SYS_PARAM_H=1",
-        "-DPC_FROM_UCONTEXT=uc_mcontext.gregs[REG_RIP]",
-        "-DPRIdS=\\\"ld\\\"",
-        "-DPRIuS=\\\"lu\\\"",
-        "-DPRIxS=\\\"lx\\\"",
-    ],
-    "arm32": [
-        "-DPC_FROM_UCONTEXT=uc_mcontext.arm_pc",
-        "-DPRIdS=\\\"d\\\"",
-        "-DPRIuS=\\\"u\\\"",
-        "-DPRIxS=\\\"x\\\"",
-    ],
-    "arm64": [
-        "-DPC_FROM_UCONTEXT=uc_mcontext.pc",
-        "-DPRIdS=\\\"ld\\\"",
-        "-DPRIuS=\\\"lu\\\"",
-        "-DPRIxS=\\\"lx\\\"",
-    ],
-}) + compiler_select({
-    "clang": [
-        "-Wno-unused-const-variable",
-        "-Wno-unused-but-set-variable",
-        "-Wno-gnu-alignof-expression",
-        "-Wno-unused-private-field",
-
-        # It has annotations for this analysis, but the invariants are too tricky
-        # for clang to figure out by itself so it has lots of false positives. Just
-        # disable the analysis to simplify.
-        "-Wno-thread-safety-analysis",
-    ],
-    "gcc": [
-        "-Wno-use-after-free",
-        "-Wno-ignored-qualifiers",
-    ],
-})
-
-cc_library(
-    name = "tcmalloc",
-    srcs = glob(
-        include = [
-            "src/*.cc",
-            "src/*.c",
-            "src/base/*.cc",
-            "src/base/*.c",
-        ],
-        exclude = [
-            "**/*_unittest.cc",
-            "**/*_test.cc",
-            "src/debugallocation.cc",
-            "src/fake_stacktrace_scope.cc",
-        ],
-    ),
-    hdrs = glob([
-        "src/*.h",
-        "src/base/*.h",
-        "src/gperftools/*.h",
-    ]),
-    copts = common_copts,
-    includes = ["src"],
-    linkopts = [
-        "-lrt",
-        "-lpthread",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    visibility = ["//visibility:public"],
-    deps = [
-        "//third_party/empty_config_h",
-    ],
-    alwayslink = True,
-)
-
-cc_library(
-    name = "testutil",
-    srcs = [
-        "src/tests/testutil.cc",
-    ],
-    hdrs = [
-        "src/tests/testutil.h",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "low_level_alloc_unittest",
-    size = "medium",
-    srcs = [
-        "src/tests/low_level_alloc_unittest.cc",
-    ],
-    copts = common_copts,
-    defines = [
-        "NO_TCMALLOC_SAMPLES",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "atomicops_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/atomicops_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "stacktrace_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/stacktrace_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "tcmalloc_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/tcmalloc_unittest.cc",
-    ]),
-    copts = common_copts + [
-        "-fno-builtin",
-        #Add this back in when we upgrade clang.
-        #'-Wno-mismatched-new-delete',
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "tcmalloc_large_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/tcmalloc_large_unittest.cc",
-    ]),
-    copts = common_copts + [
-        "-fno-builtin",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "addressmap_unittest",
-    size = "medium",
-    srcs = [
-        "src/tests/addressmap_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "system_alloc_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/system-alloc_unittest.cc",
-    ]),
-    copts = common_copts + [
-        "-fno-builtin",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "packed_cache_test",
-    size = "small",
-    srcs = [
-        "src/tests/packed-cache_test.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "frag_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/frag_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "markidle_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/markidle_unittest.cc",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "current_allocated_bytes_test",
-    size = "small",
-    srcs = [
-        "src/tests/current_allocated_bytes_test.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "malloc_hook_test",
-    size = "small",
-    srcs = [
-        "src/tests/malloc_hook_test.cc",
-    ],
-    copts = common_copts + compiler_select({
-        "gcc": [
-            "-Wno-maybe-uninitialized",
-        ],
-        "clang": [],
-    }),
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "malloc_extension_test",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/malloc_extension_test.cc",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "malloc_extension_c_test",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/malloc_extension_c_test.c",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "memalign_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/memalign_unittest.cc",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-cc_test(
-    name = "page_heap_test",
-    size = "small",
-    srcs = [
-        "src/tests/page_heap_test.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "pagemap_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/pagemap_unittest.cc",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "realloc_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/realloc_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "stack_trace_table_test",
-    size = "small",
-    srcs = [
-        "src/tests/stack_trace_table_test.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "thread_dealloc_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/thread_dealloc_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-        ":testutil",
-    ],
-)
-
-"""
-We don't build this because it actually needs to be in a separate binary.
-cc_test(
-  name = 'debugallocation_test',
-  srcs = [
-    'src/tests/debugallocation_test.cc',
-  ],
-  deps = [
-    ':tcmalloc',
-  ],
-  copts = common_copts,
-  size = 'small',
-)
-"""
-
-cc_test(
-    name = "tcmalloc_large_heap_fragmentation_unittest",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/large_heap_fragmentation_unittest.cc",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "raw_printer_test",
-    size = "small",
-    srcs = [
-        "src/tests/raw_printer_test.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "getpc_test",
-    size = "small",
-    srcs = empty_main_if_asan([
-        "src/tests/getpc_test.cc",
-    ]),
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "profiledata_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/profiledata_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "profile_handler_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/profile-handler_unittest.cc",
-    ],
-    copts = common_copts,
-    flaky = True,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "heap_profiler_unittest",
-    size = "small",
-    srcs = [
-        "src/tests/heap-profiler_unittest.cc",
-    ],
-    copts = common_copts,
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
-
-cc_test(
-    name = "sampler_test",
-    size = "small",
-    srcs = [
-        "src/tests/sampler_test.cc",
-    ],
-    copts = common_copts + [
-        "-Wno-type-limits",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":tcmalloc",
-    ],
-)
diff --git a/third_party/gperftools/CMakeLists.txt b/third_party/gperftools/CMakeLists.txt
deleted file mode 100644
index 05e37ee..0000000
--- a/third_party/gperftools/CMakeLists.txt
+++ /dev/null
@@ -1,1526 +0,0 @@
-cmake_minimum_required(VERSION 3.12)
-
-# Please note that cmake support is very preliminary. Autotools-based
-# build is the only fully supported build for now.
-
-# Based on configure.ac
-
-project(gperftools VERSION 2.9.0 LANGUAGES C CXX
-        DESCRIPTION "Performance tools for C++"
-        HOMEPAGE_URL http://code.google.com/p/gperftools/)
-
-# Update this value for every release!
-set(TCMALLOC_SO_VERSION 9.9.5)
-set(PROFILER_SO_VERSION 5.4.5)
-set(TCMALLOC_AND_PROFILER_SO_VERSION 10.4.6)
-
-# 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.
-set(DEFAULT_BUILD_CPU_PROFILER ON)
-set(DEFAULT_BUILD_HEAP_PROFILER ON)
-set(DEFAULT_BUILD_HEAP_CHECKER ON)
-set(DEFAULT_BUILD_DEBUGALLOC ON)
-set(DEFAULT_BUILD_MINIMAL OFF)
-
-set(DEFAULT_TCMALLOC_ALIGNMENT 16)
-set(NEED_NANOSLEEP ON) # Used later, to decide if to run ACX_NANOSLEEP
-
-set(HOST string(TOLOWER "${CMAKE_SYSTEM_NAME}"))
-
-if(MINGW OR MSVC)
-  set(DEFAULT_BUILD_MINIMAL ON)
-  set(DEFAULT_BUILD_DEBUGALLOC OFF)
-  set(NEED_NANOSLEEP OFF)
-elseif(CYGWIN)
-  set(DEFAULT_BUILD_HEAP_CHECKER OFF)
-  set(DEFAULT_BUILD_CPU_PROFILER OFF)
-elseif(HOST MATCHES "freebsd")
-  set(DEFAULT_BUILD_HEAP_CHECKER OFF)
-elseif(APPLE)
-  set(DEFAULT_BUILD_HEAP_CHECKER OFF)
-endif()
-
-include(CheckCCompilerFlag)
-include(CheckCSourceCompiles)
-include(CheckCXXSourceCompiles)
-include(CheckFunctionExists)
-include(CheckIncludeFile)
-include(CheckLibraryExists)
-include(CheckSymbolExists)
-include(CheckTypeSize)
-include(CheckVariableExists)
-include(CMakeDependentOption)
-include(CTest)
-include(CPack)
-include(GNUInstallDirs)
-
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-include(DefineTargetVariables)
-include(FindObjcopyWithWeaken)
-include(PCFromUContext)
-
-define_target_variables()
-
-# Currently only backtrace works on s390.
-if(s390 OR OSX)
-  set(default_enable_libunwind OFF)
-  set(default_enable_backtrace ON)
-else()
-  set(default_enable_libunwind ON)
-  set(default_enable_backtrace OFF)
-endif()
-
-# Disable libunwind linking on ppc64 by default.
-if(PPC64)
-  set(default_enable_libunwind OFF)
-  set(default_tcmalloc_pagesize 64)
-else()
-  set(default_enable_libunwind ON)
-  set(default_tcmalloc_pagesize 8)
-endif()
-
-cmake_dependent_option(
-  GPERFTOOLS_BUILD_CPU_PROFILER "Build cpu-profiler" ${DEFAULT_BUILD_CPU_PROFILER}
-  "NOT gperftools_build_minimal" OFF)
-cmake_dependent_option(
-  GPERFTOOLS_BUILD_HEAP_PROFILER "Build heap-profiler" ${DEFAULT_BUILD_HEAP_PROFILER}
-  "NOT gperftools_build_minimal" OFF)
-cmake_dependent_option(
-  GPERFTOOLS_BUILD_HEAP_CHECKER "Build heap-checker" ${DEFAULT_BUILD_HEAP_CHECKER}
-  "NOT gperftools_build_minimal" OFF)
-cmake_dependent_option(
-  GPERFTOOLS_BUILD_DEBUGALLOC "Build debugalloc" ${DEFAULT_BUILD_DEBUGALLOC}
-  "NOT gperftools_build_minimal" OFF)
-option(
-        gperftools_build_minimal
-        "Build only tcmalloc-minimal (and maybe tcmalloc-minimal-debug)"
-        ${DEFAULT_BUILD_MINIMAL})
-if(gperftools_build_minimal)
-  set(GPERFTOOLS_BUILD_CPU_PROFILER OFF)
-  set(GPERFTOOLS_BUILD_HEAP_PROFILER OFF)
-  set(GPERFTOOLS_BUILD_HEAP_CHECKER OFF)
-endif()
-
-cmake_dependent_option(
-  gperftools_build_benchmark "Build benchmark" ON "NOT MINGW AND NOT MSVC" OFF)
-
-option(gperftools_enable_stacktrace_via_backtrace
-       "Enable use of backtrace() for stacktrace capturing (may deadlock)"
-       ${default_enable_backtrace})
-option(gperftools_enable_libunwind
-       "Enable libunwind linking"
-       ${default_enable_libunwind})
-
-set(enable_backtrace ${gperftools_enable_stacktrace_via_backtrace})
-set(enable_libunwind ${gperftools_enable_libunwind})
-
-set(gperftools_tcmalloc_pagesize ${default_tcmalloc_pagesize}
-  CACHE STRING "Set the tcmalloc internal page size")
-set_property(CACHE gperftools_tcmalloc_pagesize PROPERTY STRINGS "8" "32" "64")
-if(NOT gperftools_tcmalloc_pagesize STREQUAL "8" AND
-   NOT gperftools_tcmalloc_pagesize STREQUAL "32" AND
-   NOT gperftools_tcmalloc_pagesize STREQUAL "64")
-  message(WARNING
-    "Invalid gperftools_tcmalloc_pagesize (${gperftools_tcmalloc_pagesize}), "
-    "setting to default value (${default_tcmalloc_pagesize})")
-  set(gperftools_tcmalloc_pagesize ${default_tcmalloc_pagesize})
-endif()
-if (gperftools_tcmalloc_pagesize STREQUAL "32" OR
-  gperftools_tcmalloc_pagesize STREQUAL "64")
-  set(TCMALLOC_${gperftools_tcmalloc_pagesize}K_PAGES ON)
-endif()
-
-set(gperftools_tcmalloc_alignment ${DEFAULT_TCMALLOC_ALIGNMENT}
-  CACHE STRING "Set the tcmalloc allocation alignment")
-set_property(CACHE gperftools_tcmalloc_alignment PROPERTY STRINGS "8" "16")
-if(NOT gperftools_tcmalloc_alignment STREQUAL "8" AND
-   NOT gperftools_tcmalloc_alignment STREQUAL "16")
-  message(WARNING
-      "Invalid gperftools_tcmalloc_alignment (${gperftools_tcmalloc_alignment}), "
-      "setting to default value (${DEFAULT_TCMALLOC_ALIGNMENT})")
-  set(gperftools_tcmalloc_alignment ${DEFAULT_TCMALLOC_ALIGNMENT})
-endif()
-if(gperftools_tcmalloc_alignment STREQUAL "8")
-  set(TCMALLOC_ALIGN_8BYTES ON)
-endif()
-
-# AX_CXX_COMPILE_STDCXX(11, ext, mandatory)
-if(cxx_std_17 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
-  set(CMAKE_CXX_STANDARD 17) # std::align_val_t
-else()
-  set(CMAKE_CXX_STANDARD 11)
-endif()
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS ON)
-
-# Check if we have an objcopy installed that supports -W
-find_objcopy_with_weaken()
-
-# AX_C___ATTRIBUTE__
-check_c_source_compiles("#include <stdlib.h>
-                         static void foo(void) __attribute__ ((unused));
-                         void foo(void) { exit(1); }
-                         int main() { return 0; }"
-        HAVE___ATTRIBUTE__)
-
-set(CMAKE_EXTRA_INCLUDE_FILES "malloc.h")
-check_type_size("struct mallinfo" STRUCT_MALLINFO LANGUAGE CXX)
-set(CMAKE_EXTRA_INCLUDE_FILES "elf.h")
-check_type_size("Elf32_Versym" ELF32_VERSYM LANGUAGE CXX) # for vdso_support.h
-set(CMAKE_EXTRA_INCLUDE_FILES)
-check_function_exists("sbrk" HAVE_SBRK) # for tcmalloc to get memory
-check_function_exists("__sbrk" HAVE_SBRK) # for tcmalloc to get memory
-check_function_exists("geteuid" HAVE_GETEUID) # for turning off services when run as root
-check_function_exists("fork" HAVE_FORK) # for the pthread_atfork setup
-check_include_file("features.h" HAVE_FEATURES_H) # for vdso_support.h, Where __GLIBC__ is defined
-check_include_file("malloc.h" HAVE_MALLOC_H) # some systems define stuff there, others not
-check_include_file("glob.h" HAVE_GLOB_H) # for heap-profile-table (cleaning up profiles)
-check_include_file("execinfo.h" HAVE_EXECINFO_H) # for stacktrace? and heapchecker_unittest
-check_include_file("unwind.h" HAVE_UNWIND_H) # for stacktrace
-check_include_file("sched.h" HAVE_SCHED_H) # for being nice in our spinlock code
-check_include_file("sys/prctl.h" HAVE_SYS_PRCTL_H) # for thread_lister (needed by leak-checker)
-check_include_file("linux/ptrace.h" HAVE_LINUX_PTRACE_H) # also needed by leak-checker
-check_include_file("sys/syscall.h" HAVE_SYS_SYSCALL_H)
-check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) # optional; for forking out to symbolizer
-check_include_file("sys/wait.h" HAVE_SYS_WAIT_H) # optional; for forking out to symbolizer
-check_include_file("poll.h" HAVE_POLL_H) # optional; for forking out to symbolizer
-check_include_file("fcntl.h" HAVE_FCNTL_H) # for tcmalloc_unittest
-check_include_file("grp.h" HAVE_GRP_H) # for heapchecker_unittest
-check_include_file("pwd.h" HAVE_PWD_H) # for heapchecker_unittest
-check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H) # for memalign_unittest.cc
-check_include_file("sys/cdefs.h" HAVE_SYS_CDEFS_H) # Where glibc defines __THROW
-
-check_include_file("unistd.h" HAVE_UNISTD_H)
-check_include_file("inttypes.h" HAVE_INTTYPES_H)
-# 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.
-set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=600)
-check_symbol_exists("cfree" "stdlib.h;malloc.h" HAVE_DECL_CFREE)
-check_symbol_exists("posix_memalign" "stdlib.h;malloc.h" HAVE_DECL_POSIX_MEMALIGN)
-check_symbol_exists("memalign" "stdlib.h;malloc.h" HAVE_DECL_MEMALIGN)
-check_symbol_exists("valloc" "stdlib.h;malloc.h" HAVE_DECL_VALLOC)
-check_symbol_exists("pvalloc" "stdlib.h;malloc.h" HAVE_DECL_PVALLOC)
-set(CMAKE_REQUIRED_DEFINITIONS)
-
-if(HAVE_STRUCT_MALLINFO)
-    set(HAVE_STRUCT_MALLINFO 1)
-else()
-    set(HAVE_STRUCT_MALLINFO 0)
-endif()
-
-# We hardcode HAVE_MMAP to 1. There are no interesting systems anymore
-# without functional mmap. And our windows (except mingw) builds
-# aren't using autoconf. So we keep HAVE_MMAP define, but only to
-# distingush windows and rest.
-if(NOT WIN32)
-  set(HAVE_MMAP 1)
-endif()
-
-# 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.
-check_c_source_compiles("
-  #include <stdint.h>
-  int main()
-  {
-    int32_t v1 = 0;
-    intptr_t v2 = 0;
-    return (&v1 - &v2);
-  }"
-  INT32_EQUALS_INTPTR)
-
-# 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 (GPERFTOOLS_BUILD_CPU_PROFILER)
-  pc_from_ucontext(PC_FROM_UCONTEXT_DEF)
-endif ()
-
-# Some tests test the behavior of .so files, and only make sense for dynamic.
-option(GPERFTOOLS_BUILD_STATIC "Enable Static" ON)
-
-if(gperftools_enable_libunwind)
-  check_include_file("libunwind.h" HAVE_LIBUNWIND_H)
-  if(HAVE_LIBUNWIND_H)
-    find_library(libunwind_location NAMES unwind)
-    if(libunwind_location)
-      check_library_exists(
-        unwind backtrace ${libunwind_location} have_libunwind)
-    endif()
-    if(have_libunwind)
-      set(unwind_libs ${libunwind_location})
-      set(will_use_libunwind ON)
-    endif()
-  endif()
-endif()
-
-# On x86_64, we know that default is to omit frame pointer.
-if(x86_64)
-  set(omit_fp_by_default ON)
-endif()
-
-# 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.
-check_c_compiler_flag("-Wno-unused-result" have_w_no_unused_result)
-
-option(gperftools_dynamic_sized_delete_support
-       "Try to build run-time switch for sized delete operator"
-       OFF)
-if(gperftools_dynamic_sized_delete_support)
-  set(ENABLE_DYNAMIC_SIZED_DELETE 1)
-endif()
-
-option(gperftools_sized_delete "Build sized delete operator" OFF)
-if(gperftools_sized_delete)
-  set(ENABLE_SIZED_DELETE 1)
-endif()
-
-if(NOT MSVC)
-  set(CMAKE_REQUIRED_FLAGS -fsized-deallocation)
-  check_cxx_source_compiles("
-  #include <new>
-  int main() { (::operator delete)(0, 256); return 0; }"
-          have_sized_deallocation)
-  set(CMAKE_REQUIRED_FLAGS)
-endif()
-
-check_cxx_source_compiles("
-  #include <new>
-  int main() { (::operator delete)((::operator new)(256, std::align_val_t(16)), std::align_val_t(16)); return 0; }"
-  HAVE_STD_ALIGN_VAL_T)
-if(HAVE_STD_ALIGN_VAL_T)
-  set(HAVE_STD_ALIGN_VAL_T 1)
-else()
-  set(HAVE_STD_ALIGN_VAL_T 0)
-endif()
-
-check_c_source_compiles("
-  #include <unwind.h>
-  int main()
-  {
-#if __APPLE__
-#error OSX _Unwind_Backtrace recurses back to malloc
-#endif
-    &_Unwind_Backtrace;
-    return 0;
-  }"
-  HAVE_UNWIND_BACKTRACE)
-
-if(enable_backtrace)
-  set(default_emergency_malloc ON)
-else()
-  set(default_emergency_malloc OFF)
-endif()
-
-if(will_use_libunwind AND ARM)
-  set(default_emergency_malloc ON)
-endif()
-
-option(gperftools_emergency_malloc
-       "Build emergency malloc"
-       ${default_emergency_malloc})
-
-check_c_source_compiles(
-  "int main() { return __builtin_expect(main != 0, 1); }"
-  HAVE_BUILTIN_EXPECT)
-
-check_c_source_compiles("
-  #include <unistd.h>
-  int main()
-  {
-    char** env = __environ;
-    return 0;
-  }"
-  HAVE___ENVIRON)
-
-# 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
-if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND
-   CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.1.2")
-  message(WARNING "gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html")
-elseif(APPLE)
-  message(WARNING "OSX __thread support is known to call malloc which makes "
-                    "it unsafe to use from malloc replacement")
-elseif(MINGW)
-  message(WARNING "mingw doesn't really support tls")
-else()
-  check_c_source_compiles("static __thread int p = 0; int main() {}" HAVE_TLS)
-endif()
-
-if(NEED_NANOSLEEP)
-  check_c_source_compiles(
-    "#include <time.h>
-     int main()
-     { static struct timespec ts; nanosleep(&ts, NULL); return 0; }"
-    nanosleep_ok)
-  if(NOT nanosleep_ok)
-    set(CMAKE_REQUIRED_LIBRARIES rt)
-    check_c_source_compiles(
-      "#include <time.h>
-       int main()
-       { static struct timespec ts; nanosleep(&ts, NULL); return 0; }"
-      nanosleep_ok)
-    if(nanosleep_ok)
-      set(nanosleep_libs rt)
-    else()
-      message(FATAL_ERROR "cannot find the nanosleep function")
-    endif()
-    set(CMAKE_REQUIRED_LIBRARIES)
-  endif()
-endif()
-
-# 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(enable_backtrace)
-  check_symbol_exists("backtrace" "execinfo.h" HAVE_DECL_BACKTRACE)
-  check_function_exists("backtrace" backtrace_exists)
-  if(NOT backtrace_exists)
-    set(CMAKE_REQUIRED_LIBRARIES execinfo)
-    check_function_exists("backtrace" backtrace_exists)
-    set(CMAKE_REQUIRED_LIBRARIES)
-    if(backtrace_exists)
-      list(INSERT unwind_libs 0 execinfo)
-    endif()
-  endif()
-endif()
-
-find_package(Threads REQUIRED)
-set(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT})
-foreach(attr "PTHREAD_CREATE_JOINABLE" "PTHREAD_CREATE_UNDETACHED")
-  check_c_source_compiles("
-    #include <pthread.h>
-    int main() { int attr = ${attr}; return attr; }"
-    ${attr}_ATTR)
-  if(${attr}_ATTR)
-    set(PTHREAD_CREATE_JOINABLE ${attr})
-    break()
-  endif()
-endforeach()
-
-if(FreeBSD)
-  set(PTHREADS_CRASHES_IF_RUN_TOO_EARLY ON)
-endif()
-
-set(libstdcxx_la_linker_flag)
-if(EXISTS /usr/sfw/lib/libstdc++.la)
-  file(READ /usr/sfw/lib/libstdc++.la _ch LIMIT 1)
-  if(string(LENGTH _ch) EQUAL 0)
-    set(libstdcxx_la_linker_flag "-L${CMAKE_CURRENT_SOURCE_DIR}/src/solaris")
-  endif()
-endif()
-
-check_cxx_source_compiles(
-  "#include <string>
-     #include <vector>
-     int main() { pthread_t th; pthread_join(th, 0); return 0; }"
-  have_pthread_despite_asking_for)
-
-check_variable_exists("program_invocation_name" HAVE_PROGRAM_INVOCATION_NAME)
-
-if(MINGW)
-  check_symbol_exists("sleep" "unistd.h" HAVE_DECL_SLEEP)
-  check_symbol_exists("nanosleep" "time.h" HAVE_DECL_NANOSLEEP)
-endif()
-
-if(LINUX)
-  check_c_source_compiles("
-    #include <signal.h>
-    #include <time.h>
-    int main() { return SIGEV_THREAD_ID || CLOCK_THREAD_CPUTIME_ID; }"
-    HAVE_LINUX_SIGEV_THREAD_ID)
-endif()
-
-configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY)
-configure_file(cmake/tcmalloc.h.in
-               ${CMAKE_CURRENT_BINARY_DIR}/gperftools/tcmalloc.h
-               @ONLY)
-
-if(GPERFTOOLS_BUILD_CPU_PROFILER OR
-   GPERFTOOLS_BUILD_HEAP_PROFILER OR
-   GPERFTOOLS_BUILD_HEAP_CHECKER)
-  set(WITH_STACK_TRACE ON)
-endif()
-
-# The following matters only if we're not using libunwind and if we
-# care about backtrace capturing, and frame pointers are not available
-# to capture backtraces. The idea is to warn user about less stable or
-# known bad configurations (e.g. encourage to install libunwind).
-if (NOT unwind_libs AND NOT gperftools_build_minimal AND
-    omit_fp_by_default AND NOT gperftools_enable_frame_pointers)
-  if(HAVE_UNWIND_BACKTRACE)
-    message(WARNING "No frame pointers and no libunwind. "
-                    "Using experimental backtrace capturing via libgcc. "
-                    "Expect crashy cpu profiler.")
-  elseif(gperftools_enable_stacktrace_via_backtrace)
-    message(WARNING "No frame pointers and no libunwind. "
-      "Using experimental backtrace(). "
-      "Expect crashy cpu profiler.")
-  else()
-    message(FATAL_ERROR "No frame pointers and no libunwind. "
-      "The compilation will fail.")
-  endif()
-endif()
-
-# Based on Makefile.am
-
-set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-# This is so we can #include <gperftools/foo>
-include_directories($<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
-
-if(NOT WITH_STACK_TRACE)
-  add_compile_definitions(NO_TCMALLOC_SAMPLES)
-endif()
-
-# These are good warnings to turn on by default.
-if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare")
-
-  # 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)
-    add_compile_options(-mmmx -fno-omit-frame-pointer)
-  endif()
-endif()
-
-if(have_w_no_unused_result)
-  add_compile_options(-Wno-unused-result)
-endif()
-
-if(have_sized_deallocation)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsized-deallocation")
-endif()
-
-if(have_f_aligned_new)
-  add_compile_options(-faligned-new)
-endif()
-
-# LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
-add_link_options(${libstdcxx_la_linker_flag})
-
-option(
-  gperftools_enable_frame_pointers
-  "Compile with -fno-omit-frame-pointer (see INSTALL)"
-  OFF)
-
-if(gperftools_enable_frame_pointers)
-  add_compile_options(-fno-omit-frame-pointer)
-endif()
-
-if(omit_fp_by_default AND NOT gperftools_enable_frame_pointers)
-  add_compile_definitions(NO_FRAME_POINTER)
-endif()
-
-# 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.
-set(TCMALLOC_FLAGS)
-if(MINGW)
-  list(APPEND TCMALLOC_FLAGS "-Wl,-u__tcmalloc")
-endif()
-
-set(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
-        )
-install(FILES ${googleinclude_HEADERS}
-        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/google
-        )
-
-# This is a 'convenience library' -- it's not actually installed or anything
-set(LOGGING_INCLUDES
-        src/base/logging.h
-        src/base/commandlineflags.h
-        src/base/basictypes.h
-        src/base/dynamic_annotations.h)
-set(liblogging_la_SOURCES src/base/logging.cc
-        src/base/dynamic_annotations.c
-        ${LOGGING_INCLUDES})
-add_library(logging STATIC ${liblogging_la_SOURCES})
-
-set(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)
-set(libsysinfo_la_SOURCES src/base/sysinfo.cc
-        ${SYSINFO_INCLUDES})
-set(libsysinfo_la_LIBADD ${NANOSLEEP_LIBS})
-add_library(sysinfo STATIC ${libsysinfo_la_SOURCES})
-target_link_libraries(sysinfo ${libsysinfo_la_LIBADD})
-
-# 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 OR MSVC)
-  set(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)
-  set(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)
-  add_library(windows_object OBJECT ${libwindows_la_SOURCES})
-  add_library(windows INTERFACE)
-  target_sources(windows INTERFACE $<TARGET_OBJECTS:windows_object>)
-  # patch_functions.cc uses Psapi.lib.  MSVC has a #pragma for that, but not us.
-  target_link_libraries(windows INTERFACE psapi)
-
-  set(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)
-  set(libspinlock_la_SOURCES src/base/spinlock.cc
-          src/base/spinlock_internal.cc
-          src/base/atomicops-internals-x86.cc
-          ${SPINLOCK_INCLUDES})
-  add_library(spinlock STATIC ${libspinlock_la_SOURCES})
-  set(LIBSPINLOCK windows spinlock sysinfo logging)
-  # 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).
-  target_link_libraries(sysinfo shlwapi)
-
-  if(have_pthread_despite_asking_for)
-    add_library(maybe_threads STATIC src/maybe_threads.cc)
-    set(maybe_threads_lib maybe_threads)
-  endif()
-else()
-  set(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)
-  set(libspinlock_la_SOURCES src/base/spinlock.cc
-          src/base/spinlock_internal.cc
-          src/base/atomicops-internals-x86.cc
-          ${SPINLOCK_INCLUDES})
-  add_library(spinlock STATIC ${libspinlock_la_SOURCES})
-  target_link_libraries(spinlock ${nanosleep_libs})
-  set(LIBSPINLOCK spinlock sysinfo logging)
-  set(TCMALLOC_CC "src/tcmalloc.cc")
-  set(SYSTEM_ALLOC_CC "src/system-alloc.cc")
-
-  add_library(maybe_threads STATIC src/maybe_threads.cc)
-  set(maybe_threads_lib maybe_threads)
-endif()
-
-if(BUILD_TESTING)
-  set(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})
-  set(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})
-  if(MSVC OR MINGW)
-      list(APPEND low_level_alloc_unittest_SOURCES src/windows/port.cc)
-  endif()
-  add_executable(low_level_alloc_unittest ${low_level_alloc_unittest_SOURCES})
-  # 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.
-  target_compile_definitions(low_level_alloc_unittest PRIVATE NO_TCMALLOC_SAMPLES)
-  target_link_libraries(low_level_alloc_unittest spinlock sysinfo logging ${maybe_threads_lib})
-  add_test(low_level_alloc_unittest low_level_alloc_unittest)
-
-  set(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})
-  set(atomicops_unittest_SOURCES src/tests/atomicops_unittest.cc
-          ${ATOMICOPS_UNITTEST_INCLUDES})
-  if(MSVC OR MINGW)
-    list(APPEND atomicops_unittest_SOURCES src/windows/port.cc)
-  endif()
-  add_executable(atomicops_unittest ${atomicops_unittest_SOURCES})
-  target_link_libraries(atomicops_unittest spinlock sysinfo logging)
-  add_test(atomicops_unittest atomicops_unittest)
-endif()
-
-### ------- stack trace
-
-if(WITH_STACK_TRACE)
-
-  set(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)
-
-  set(SG_STACKTRACE_INCLUDES src/gperftools/stacktrace.h)
-  set(STACKTRACE_INCLUDES ${S_STACKTRACE_INCLUDES} ${SG_STACKTRACE_INCLUDES})
-  list(APPEND perftoolsinclude_HEADERS ${SG_STACKTRACE_INCLUDES})
-
-  ### Making the library
-  set(libstacktrace_la_SOURCES src/stacktrace.cc
-          src/base/elf_mem_image.cc
-          src/base/vdso_support.cc
-          ${STACKTRACE_INCLUDES})
-  add_library(stacktrace INTERFACE)
-  add_library(stacktrace_object OBJECT ${libstacktrace_la_SOURCES})
-  target_link_libraries(stacktrace INTERFACE ${unwind_libs} ${LIBSPINLOCK})
-  target_sources(stacktrace INTERFACE $<TARGET_OBJECTS:stacktrace_object>)
-
-  set(libfake_stacktrace_scope_la_SOURCES src/fake_stacktrace_scope.cc)
-  add_library(fake_stacktrace_scope ${libfake_stacktrace_scope_la_SOURCES})
-
-  if(BUILD_TESTING)
-    set(STACKTRACE_UNITTEST_INCLUDES src/config_for_unittests.h
-            src/base/commandlineflags.h
-            ${STACKTRACE_INCLUDES}
-            ${LOGGING_INCLUDES})
-    set(stacktrace_unittest_SOURCES src/tests/stacktrace_unittest.cc
-            ${STACKTRACE_UNITTEST_INCLUDES})
-    add_executable(stacktrace_unittest ${stacktrace_unittest_SOURCES})
-    target_link_libraries(stacktrace_unittest stacktrace logging fake_stacktrace_scope)
-    add_test(stacktrace_unittest stacktrace_unittest)
-  endif()
-
-endif()
-
-### ------- pprof
-
-# If we are not compiling with stacktrace support, pprof is worthless
-if(WITH_STACK_TRACE)
-  install(FILES src/pprof DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME pprof-symbolize)
-
-  if(BUILD_TESTING)
-    add_test(NAME pprof_unittest
-            COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/pprof" -test
-            VERBATIM)
-    list(APPEND TESTS_ENVIRONMENT "PPROF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/src/pprof")
-  endif()
-  if(INSTALL_PPROF)
-      install(FILES src/pprof DESTINATION ${CMAKE_INSTALL_BINDIR})
-  endif()
-endif()
-
-### ------- tcmalloc_minimal (thread-caching malloc)
-
-### The header files we use.  We divide into categories based on directory
-set(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)
-set(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)
-set(TCMALLOC_MINIMAL_INCLUDES ${S_TCMALLOC_MINIMAL_INCLUDES} ${SG_TCMALLOC_MINIMAL_INCLUDES} ${SG_STACKTRACE_INCLUDES})
-list(APPEND perftoolsinclude_HEADERS ${SG_TCMALLOC_MINIMAL_INCLUDES})
-
-### Making the library
-
-set(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})
-add_library(tcmalloc_minimal_internal_object OBJECT ${libtcmalloc_minimal_internal_la_SOURCES})
-# We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal.
-target_compile_definitions(tcmalloc_minimal_internal_object PRIVATE NO_TCMALLOC_SAMPLES NO_HEAP_CHECK NDEBUG)
-add_library(tcmalloc_minimal_internal INTERFACE)
-target_link_libraries(tcmalloc_minimal_internal INTERFACE ${LIBSPINLOCK} ${maybe_threads_lib})
-target_sources(tcmalloc_minimal_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_minimal_internal_object>)
-
-set(libtcmalloc_minimal_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_MINIMAL_INCLUDES})
-set(libtcmalloc_minimal_la_DEFINES NO_TCMALLOC_SAMPLES NDEBUG)
-add_library(tcmalloc_minimal SHARED ${libtcmalloc_minimal_la_SOURCES})
-target_compile_definitions(tcmalloc_minimal PRIVATE ${libtcmalloc_minimal_la_DEFINES})
-set(libtcmalloc_minimal_la_LIBADD tcmalloc_minimal_internal)
-target_link_libraries(tcmalloc_minimal PRIVATE tcmalloc_minimal_internal Threads::Threads)
-if(MINGW)
-  target_link_libraries(tcmalloc_minimal PRIVATE stacktrace)
-endif()
-set_target_properties(tcmalloc_minimal PROPERTIES
-        VERSION ${TCMALLOC_SO_VERSION}
-        SOVERSION ${TCMALLOC_SO_VERSION})
-weaken_object(tcmalloc_minimal)
-install(TARGETS tcmalloc_minimal)
-if(GPERFTOOLS_BUILD_STATIC)
-    add_library(tcmalloc_minimal_static STATIC ${libtcmalloc_minimal_internal_la_SOURCES})
-    target_compile_definitions(tcmalloc_minimal_static PRIVATE NO_TCMALLOC_SAMPLES NDEBUG)
-    target_link_libraries(tcmalloc_minimal_static PRIVATE tcmalloc_minimal_internal Threads::Threads)
-    if(MINGW)
-      target_link_libraries(tcmalloc_minimal_static PRIVATE stacktrace)
-    endif()
-    if(NOT MSVC)
-      set_target_properties(tcmalloc_minimal_static PROPERTIES
-              OUTPUT_NAME tcmalloc_minimal)
-    endif()
-    weaken_object(tcmalloc_minimal_static)
-    install(TARGETS tcmalloc_minimal_static)
-endif()
-
-if(BUILD_TESTING)
-  set(tcmalloc_minimal_unittest_SOURCES
-          src/tests/tcmalloc_unittest.cc
-          src/tests/testutil.h src/tests/testutil.cc
-          ${TCMALLOC_UNITTEST_INCLUDES})
-  set(tcmalloc_minimal_unittest_LDADD
-          ${TCMALLOC_FLAGS} Threads::Threads logging)
-  # 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'.
-  add_executable(tcmalloc_minimal_unittest ${tcmalloc_minimal_unittest_SOURCES})
-  target_link_libraries(tcmalloc_minimal_unittest tcmalloc_minimal ${tcmalloc_minimal_unittest_LDADD})
-  add_test(tcmalloc_minimal_unittest tcmalloc_minimal_unittest)
-
-  if(NOT MSVC)
-    add_executable(tcm_min_asserts_unittest
-            src/tests/tcmalloc_unittest.cc
-            src/tests/testutil.cc)
-    target_compile_definitions(tcm_min_asserts_unittest PUBLIC NO_TCMALLOC_SAMPLES NO_HEAP_CHECK)
-    target_link_libraries(tcm_min_asserts_unittest tcmalloc_minimal Threads::Threads)
-    add_test(tcm_min_asserts_unittest tcm_min_asserts_unittest)
-  endif()
-
-  add_executable(tcmalloc_minimal_large_unittest
-          src/tests/tcmalloc_large_unittest.cc
-          src/tests/testutil.cc
-          src/tests/testutil.h)
-  target_link_libraries(tcmalloc_minimal_large_unittest tcmalloc_minimal Threads::Threads)
-  add_test(tcmalloc_minimal_large_unittest tcmalloc_minimal_large_unittest)
-
-  add_executable(tcmalloc_minimal_large_heap_fragmentation_unittest
-          src/tests/large_heap_fragmentation_unittest.cc)
-  target_link_libraries(
-          tcmalloc_minimal_large_heap_fragmentation_unittest PUBLIC tcmalloc_minimal)
-  add_test(tcmalloc_minimal_large_heap_fragmentation_unittest tcmalloc_minimal_large_heap_fragmentation_unittest)
-
-  if(BUILD_SHARED_LIBS AND NOT MINGW)
-    add_custom_target(maybe_threads_unittest
-            COMMAND src/tests/maybe_threads_unittest.sh
-            VERBATIM)
-    add_test(maybe_threads_unittest maybe_threads_unittest)
-  endif()
-
-  if(MINGW OR MSVC)
-    set(port_src src/windows/port.cc)
-  endif()
-  add_executable(addressmap_unittest
-          src/tests/addressmap_unittest.cc
-          src/addressmap-inl.h
-          ${port_src})
-  target_link_libraries(addressmap_unittest logging)
-  add_test(addressmap_unittest addressmap_unittest)
-
-  if(NOT MINGW)
-    add_executable(system_alloc_unittest src/tests/system-alloc_unittest.cc)
-    target_link_libraries(system_alloc_unittest PUBLIC tcmalloc_minimal)
-    add_test(system_alloc_unittest system_alloc_unittest)
-  endif()
-
-  add_executable(packed_cache_test src/tests/packed-cache_test.cc)
-  target_link_libraries(packed_cache_test PUBLIC tcmalloc_minimal)
-  add_test(packed_cache_test packed_cache_test)
-
-  add_executable(frag_unittest src/tests/frag_unittest.cc)
-  target_link_libraries(frag_unittest PUBLIC tcmalloc_minimal)
-  add_test(frag_unittest frag_unittest)
-
-  add_executable(markidle_unittest
-          src/tests/markidle_unittest.cc
-          src/tests/testutil.cc)
-  target_link_libraries(markidle_unittest tcmalloc_minimal Threads::Threads)
-  add_test(markidle_unittest markidle_unittest)
-
-  add_executable(current_allocated_bytes_test
-          src/tests/current_allocated_bytes_test.cc)
-  target_link_libraries(current_allocated_bytes_test PUBLIC tcmalloc_minimal)
-  add_test(current_allocated_bytes_test current_allocated_bytes_test)
-
-  add_executable(malloc_hook_test
-          src/tests/malloc_hook_test.cc
-          src/tests/testutil.cc)
-  target_link_libraries(malloc_hook_test tcmalloc_minimal Threads::Threads)
-  add_test(malloc_hook_test malloc_hook_test)
-
-  set(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)
-  set(malloc_extension_test_LIBADD Threads::Threads ${TCMALLOC_FLAGS})
-  add_executable(malloc_extension_test ${malloc_extension_test_SOURCES})
-  target_link_libraries(malloc_extension_test tcmalloc_minimal ${malloc_extension_test_LIBADD})
-  add_test(malloc_extension_test malloc_extension_test)
-
-  if(NOT MSVC)
-    add_executable(malloc_extension_c_test src/tests/malloc_extension_c_test.c)
-    target_link_libraries(malloc_extension_c_test PUBLIC
-            tcmalloc_minimal stdc++ m)
-    if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
-      target_compile_options(malloc_extension_c_test PUBLIC "-ansi")
-    endif()
-    add_test(malloc_extension_c_test malloc_extension_c_test)
-  endif()
-
-  if(NOT MINGW AND NOT MSVC AND NOT APPLE)
-    set(memalign_unittest_SOURCES src/tests/memalign_unittest.cc
-            src/tcmalloc.h
-            src/config_for_unittests.h
-            src/tests/testutil.h src/tests/testutil.cc)
-    add_executable(memalign_unittest ${memalign_unittest_SOURCES})
-    target_link_libraries(memalign_unittest tcmalloc_minimal Threads::Threads)
-    add_test(memalign_unittest memalign_unittest)
-  endif()
-
-  add_executable(page_heap_test src/tests/page_heap_test.cc)
-  if(MSVC)
-    target_link_libraries(page_heap_test tcmalloc_minimal_static)
-  else()
-    target_link_libraries(page_heap_test tcmalloc_minimal)
-  endif()
-  add_test(page_heap_test page_heap_test)
-
-  add_executable(pagemap_unittest src/tests/pagemap_unittest.cc)
-  target_link_libraries(pagemap_unittest PUBLIC tcmalloc_minimal)
-  add_test(pagemap_unittest pagemap_unittest)
-
-  set(realloc_unittest_SOURCES src/tests/realloc_unittest.cc
-          src/config_for_unittests.h
-          src/base/logging.h)
-  set(realloc_unittest_LDFLAGS Threads::Threads ${TCMALLOC_FLAGS})
-  add_executable(realloc_unittest ${realloc_unittest_SOURCES})
-  target_link_libraries(realloc_unittest PUBLIC tcmalloc_minimal ${realloc_unittest_LDFLAGS})
-  add_test(realloc_unittest realloc_unittest)
-
-  add_executable(stack_trace_table_test src/tests/stack_trace_table_test.cc)
-  target_link_libraries(stack_trace_table_test PUBLIC tcmalloc_minimal)
-  add_test(stack_trace_table_test stack_trace_table_test)
-
-  add_executable(thread_dealloc_unittest
-          src/tests/thread_dealloc_unittest.cc
-          src/tests/testutil.cc)
-  target_link_libraries(thread_dealloc_unittest tcmalloc_minimal Threads::Threads)
-  add_test(thread_dealloc_unittest thread_dealloc_unittest)
-endif()
-
-### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation)
-
-if(GPERFTOOLS_BUILD_DEBUGALLOC)
-  set(libtcmalloc_minimal_debug_la_SOURCES src/debugallocation.cc
-          ${TCMALLOC_MINIMAL_INCLUDES})
-  add_library(tcmalloc_minimal_debug SHARED ${libtcmalloc_minimal_debug_la_SOURCES})
-  target_compile_definitions(tcmalloc_minimal_debug PRIVATE ${libtcmalloc_minimal_la_DEFINES}
-          TCMALLOC_FOR_DEBUGALLOCATION)
-  target_link_libraries(tcmalloc_minimal_debug PRIVATE ${libtcmalloc_minimal_la_LIBADD})
-  weaken_object(tcmalloc_minimal_debug)
-  install(TARGETS tcmalloc_minimal_debug)
-  set_target_properties(tcmalloc_minimal_debug PROPERTIES
-          VERSION ${TCMALLOC_SO_VERSION}
-          SOVERSION ${TCMALLOC_SO_VERSION})
-  if(GPERFTOOLS_BUILD_STATIC)
-    add_library(tcmalloc_minimal_debug_static STATIC ${libtcmalloc_minimal_debug_la_SOURCES})
-    target_compile_definitions(tcmalloc_minimal_debug_static PRIVATE ${libtcmalloc_minimal_la_DEFINES}
-            TCMALLOC_FOR_DEBUGALLOCATION)
-    if(NOT MSVC)
-      set_target_properties(tcmalloc_minimal_debug_static PROPERTIES
-              OUTPUT_NAME tcmalloc_minimal_debug)
-    endif()
-    target_link_libraries(tcmalloc_minimal_debug_static PRIVATE ${libtcmalloc_minimal_la_LIBADD})
-    weaken_object(tcmalloc_minimal_debug_static)
-    install(TARGETS tcmalloc_minimal_debug_static)
-  endif()
-
-  ### Unittests
-
-  if(BUILD_TESTING)
-    add_executable(tcmalloc_minimal_debug_unittest ${tcmalloc_minimal_unittest_SOURCES})
-    target_compile_definitions(tcmalloc_minimal_debug_unittest PRIVATE DEBUGALLOCATION)
-    target_link_libraries(tcmalloc_minimal_debug_unittest tcmalloc_minimal_debug ${tcmalloc_minimal_unittest_LDADD})
-    add_test(tcmalloc_minimal_debug_unittest tcmalloc_minimal_debug_unittest)
-
-    add_executable(malloc_extension_debug_test ${malloc_extension_test_SOURCES})
-    target_link_libraries(malloc_extension_debug_test tcmalloc_minimal_debug ${malloc_extension_test_LIBADD})
-    add_test(malloc_extension_debug_test malloc_extension_debug_test)
-
-    if(NOT MINGW AND NOT APPLE)
-      add_executable(memalign_debug_unittest ${memalign_unittest_SOURCES})
-      target_link_libraries(memalign_debug_unittest
-              tcmalloc_minimal_debug Threads::Threads)
-      add_test(memalign_debug_unittest memalign_debug_unittest)
-    endif()
-
-    add_executable(realloc_debug_unittest ${realloc_unittest_SOURCES})
-    target_link_libraries(realloc_debug_unittest PUBLIC tcmalloc_minimal_debug)
-    add_test(realloc_debug_unittest realloc_debug_unittest)
-
-    if(WITH_STACK_TRACE)
-      add_executable(debugallocation_test src/tests/debugallocation_test.cc)
-      target_link_libraries(debugallocation_test PUBLIC tcmalloc_minimal_debug Threads::Threads)
-
-      add_test(NAME debugallocation_test
-              COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/tests/debugallocation_test.sh)
-    endif()
-  endif()
-endif()
-
-if(NOT MINGW AND NOT MSVC)
-  if(gperftools_build_benchmark)
-    add_library(run_benchmark benchmark/run_benchmark.c)
-
-    add_executable(malloc_bench benchmark/malloc_bench.cc)
-    target_link_libraries(malloc_bench run_benchmark ${TCMALLOC_FLAGS})
-    if(GPERFTOOLS_BUILD_STATIC)
-      target_link_libraries(malloc_bench tcmalloc_minimal_static)
-    else()
-      target_link_libraries(malloc_bench tcmalloc_minimal)
-    endif()
-    add_executable(malloc_bench_shared benchmark/malloc_bench.cc)
-    target_link_libraries(malloc_bench_shared run_benchmark tcmalloc_minimal ${TCMALLOC_FLAGS} Threads::Threads)
-
-    if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER)
-      add_executable(malloc_bench_shared_full benchmark/malloc_bench.cc)
-      target_link_libraries(malloc_bench_shared_full run_benchmark tcmalloc ${TCMALLOC_FLAGS} Threads::Threads)
-    endif()
-
-    add_executable(binary_trees benchmark/binary_trees.cc)
-    target_link_libraries(binary_trees Threads::Threads ${TCMALLOC_FLAGS})
-    if(GPERFTOOLS_BUILD_STATIC)
-      target_link_libraries(binary_trees tcmalloc_minimal_static)
-    else()
-      target_link_libraries(binary_trees tcmalloc_minimal)
-    endif()
-    add_executable(binary_trees_shared benchmark/binary_trees.cc)
-    target_link_libraries(binary_trees_shared tcmalloc_minimal Threads::Threads ${TCMALLOC_FLAGS})
-  endif()
-endif()
-
-### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)
-
-if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER)
-  ### The header files we use.  We divide into categories based on directory
-  set(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)
-
-  set(SG_TCMALLOC_INCLUDES src/gperftools/heap-profiler.h
-          src/gperftools/heap-checker.h)
-  set(TCMALLOC_INCLUDES ${S_TCMALLOC_INCLUDES} ${SG_TCMALLOC_MINIMAL_INCLUDES}
-          ${SG_TCMALLOC_INCLUDES} ${SG_STACKTRACE_INCLUDES})
-  list(APPEND perftoolsinclude_HEADERS ${SG_TCMALLOC_INCLUDES})
-
-  if(gperftools_emergency_malloc)
-    set(EMERGENCY_MALLOC_CC
-            src/emergency_malloc.cc
-            src/emergency_malloc_for_stacktrace.cc)
-    set(EMERGENCY_MALLOC_DEFINE ENABLE_EMERGENCY_MALLOC)
-  else()
-    set(EMERGENCY_MALLOC_CC src/fake_stacktrace_scope.cc)
-  endif()
-
-  ### Making the library
-
-  set(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)
-  set(libtcmalloc_internal_la_DEFINE NDEBUG ${EMERGENCY_MALLOC_DEFINE})
-  set(libtcmalloc_internal_la_LIBADD stacktrace Threads::Threads)
-
-  set(libtcmalloc_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_INCLUDES})
-  set(libtcmalloc_la_DEFINE NDEBUG ${EMERGENCY_MALLOC_DEFINE})
-  set(libtcmalloc_la_LIBADD tcmalloc_internal ${maybe_threads_lib} Threads::Threads)
-  if(GPERFTOOLS_BUILD_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.)
-    set(HEAP_CHECKER_SOURCES src/base/thread_lister.c
-            src/base/linuxthreads.cc
-            src/heap-checker.cc
-            src/heap-checker-bcad.cc)
-    list(APPEND libtcmalloc_la_SOURCES ${HEAP_CHECKER_SOURCES})
-  else()
-    list(APPEND libtcmalloc_internal_la_DEFINE NO_HEAP_CHECK)
-    list(APPEND libtcmalloc_la_DEFINE NO_HEAP_CHECK)
-  endif()
-
-  add_library(tcmalloc_internal_object OBJECT ${libtcmalloc_internal_la_SOURCES})
-  target_compile_definitions(tcmalloc_internal_object PRIVATE ${libtcmalloc_internal_la_DEFINE})
-  add_library(tcmalloc_internal INTERFACE)
-  target_sources(tcmalloc_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_internal_object>)
-  target_link_libraries(tcmalloc_internal INTERFACE ${libtcmalloc_internal_la_LIBADD})
-
-  add_library(tcmalloc SHARED ${libtcmalloc_la_SOURCES})
-  target_compile_definitions(tcmalloc PRIVATE ${libtcmalloc_la_DEFINE})
-  target_link_libraries(tcmalloc ${libtcmalloc_la_LIBADD})
-  set_target_properties(tcmalloc PROPERTIES
-          VERSION ${TCMALLOC_SO_VERSION}
-          SOVERSION ${TCMALLOC_SO_VERSION})
-  weaken_object(tcmalloc)
-  install(TARGETS tcmalloc)
-  if(GPERFTOOLS_BUILD_STATIC)
-    add_library(tcmalloc_static STATIC ${libtcmalloc_la_SOURCES})
-    target_compile_definitions(tcmalloc_static PRIVATE ${libtcmalloc_la_DEFINE})
-    if(NOT MSVC)
-      set_target_properties(tcmalloc_static PROPERTIES OUTPUT_NAME tcmalloc)
-    endif()
-    target_link_libraries(tcmalloc_static PRIVATE ${libtcmalloc_la_LIBADD})
-    weaken_object(tcmalloc_static)
-    install(TARGETS tcmalloc_static)
-  endif()
-
-  ### Unittests
-  if(BUILD_TESTING)
-    set(TCMALLOC_UNITTEST_INCLUDES src/config_for_unittests.h
-            src/gperftools/malloc_extension.h)
-    set(tcmalloc_unittest_SOURCES src/tests/tcmalloc_unittest.cc
-            src/tcmalloc.h
-            src/tests/testutil.h src/tests/testutil.cc
-            ${TCMALLOC_UNITTEST_INCLUDES})
-    set(tcmalloc_unittest_LIBADD ${TCMALLOC_FLAGS} logging Threads::Threads)
-    add_executable(tcmalloc_unittest ${tcmalloc_unittest_SOURCES})
-    target_link_libraries(tcmalloc_unittest tcmalloc ${tcmalloc_unittest_LIBADD})
-    add_test(NAME tcmalloc_unittest
-            COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/tcmalloc_unittest.sh")
-
-    # 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.
-    set(tcmalloc_both_unittest_srcs src/tests/tcmalloc_unittest.cc
-            src/tests/testutil.h src/tests/testutil.cc
-            ${TCMALLOC_UNITTEST_INCLUDES})
-    if(GPERFTOOLS_BUILD_CPU_PROFILER)
-      set(tcmalloc_both_unittest_ladd tcmalloc tcmalloc_minimal profiler logging Threads::Threads)
-    else()
-      set(tcmalloc_both_unittest_ladd tcmalloc tcmalloc_minimal logging Threads::Threads)
-    endif()
-    if(NOT APPLE)
-      add_executable(tcmalloc_both_unittest ${tcmalloc_both_unittest_srcs})
-      target_link_libraries(tcmalloc_both_unittest ${TCMALLOC_FLAGS} ${tcmalloc_both_unittest_ladd})
-      add_test(tcmalloc_both_unittest tcmalloc_both_unittest)
-    endif()
-
-    add_executable(tcmalloc_large_unittest src/tests/tcmalloc_large_unittest.cc)
-    target_link_libraries(tcmalloc_large_unittest tcmalloc Threads::Threads)
-    add_test(tcmalloc_large_unittest tcmalloc_large_unittest)
-
-    add_executable(tcmalloc_large_heap_fragmentation_unittest src/tests/large_heap_fragmentation_unittest.cc)
-    target_link_libraries(tcmalloc_large_heap_fragmentation_unittest tcmalloc Threads::Threads)
-    add_test(tcmalloc_large_heap_fragmentation_unittest tcmalloc_large_heap_fragmentation_unittest)
-
-    add_executable(raw_printer_test src/tests/raw_printer_test.cc)
-    target_link_libraries(raw_printer_test tcmalloc Threads::Threads)
-    add_test(raw_printer_test raw_printer_test)
-
-    # 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.
-    list(APPEND TESTS_ENVIRONMENT TCMALLOC_SAMPLE_PARAMETER=524288)
-
-    set(sampler_test_SOURCES src/tests/sampler_test.cc
-            src/config_for_unittests.h)
-    set(sampler_test_LIBADD ${TCMALLOC_FLAGS} Threads::Threads m)
-    add_executable(sampler_test ${sampler_test_SOURCES})
-    target_link_libraries(sampler_test tcmalloc ${sampler_test_LIBADD})
-    add_test(sampler_test sampler_test)
-
-    # These unittests often need to run binaries.  They're in the current dir
-    list(APPEND TESTS_ENVIRONMENT BINDIR=. TMPDIR=/tmp/perftools)
-    set(SAMPLING_TEST_INCLUDES src/config_for_unittests.h
-            src/base/logging.h
-            src/gperftools/malloc_extension.h)
-    set(sampling_test_SOURCES src/tests/sampling_test.cc
-            ${SAMPLING_TEST_INCLUDES})
-    add_executable(sampling_test ${sampling_test_SOURCES})
-    target_link_libraries(sampling_test ${TCMALLOC_FLAGS} tcmalloc Threads::Threads)
-    add_test(NAME sampling_test.sh
-            COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/sampling_test.sh" sampling_test)
-    if(GPERFTOOLS_BUILD_HEAP_PROFILER)
-      set(HEAP_PROFILER_UNITTEST_INCLUDES src/config_for_unittests.h
-              src/gperftools/heap-profiler.h)
-      set(heap_profiler_unittest_SOURCES src/tests/heap-profiler_unittest.cc
-              ${HEAP_PROFILER_UNITTEST_INCLUDES})
-      add_executable(heap_profiler_unittest ${heap_profiler_unittest_SOURCES})
-      target_link_libraries(heap_profiler_unittest ${TCMALLOC_FLAGS} tcmalloc Threads::Threads)
-      add_test(NAME heap-profiler_unittest.sh
-              COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-profiler_unittest.sh" heap-profiler_unittest)
-
-      # Tests the compatibility include-headers in google/.  Requires a function
-      # defined in the heap-profiler, which is why the test lives here.
-      add_executable(simple_compat_test src/tests/simple_compat_test.cc
-              ${googleinclude_HEADERS})
-      target_link_libraries(simple_compat_test ${TCMALLOC_FLAGS} tcmalloc)
-      add_test(simple_compat_test simple_compat_test)
-    endif()
-    if(GPERFTOOLS_BUILD_HEAP_CHECKER)
-      set(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})
-      set(heap_checker_unittest_SOURCES src/tests/heap-checker_unittest.cc
-              ${HEAP_CHECKER_UNITTEST_INCLUDES})
-      add_executable(heap_checker_unittest ${heap_checker_unittest_SOURCES})
-      target_link_libraries(heap_checker_unittest ${TCMALLOC_FLAGS} tcmalloc logging Threads::Threads)
-      add_test(NAME heap-checker_unittest.sh
-              COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-checker_unittest.sh" heap_checker_unittest)
-      add_test(NAME heap-checker-death_unittest.sh
-              COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-checker-death_unittest.sh")
-endif()
-  endif()
-
-endif()
-
-### ------- tcmalloc with debugallocation
-if(GPERFTOOLS_BUILD_DEBUGALLOC)
-  if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER)
-    add_library(tcmalloc_debug SHARED src/debugallocation.cc ${HEAP_CHECKER_SOURCES} ${TCMALLOC_INCLUDES})
-    target_compile_definitions(tcmalloc_debug PRIVATE ${libtcmalloc_la_DEFINE}
-            TCMALLOC_FOR_DEBUGALLOCATION)
-    target_link_libraries(tcmalloc_debug PRIVATE ${libtcmalloc_la_LIBADD})
-    set_target_properties(tcmalloc_debug PROPERTIES
-            VERSION ${TCMALLOC_SO_VERSION}
-            SOVERSION ${TCMALLOC_SO_VERSION})
-    weaken_object(tcmalloc_debug)
-    install(TARGETS tcmalloc_debug)
-    if(GPERFTOOLS_BUILD_STATIC)
-      add_library(tcmalloc_debug_static STATIC src/debugallocation.cc ${HEAP_CHECKER_SOURCES} ${TCMALLOC_INCLUDES})
-      target_compile_definitions(tcmalloc_debug_static PRIVATE ${libtcmalloc_la_DEFINE}
-              TCMALLOC_FOR_DEBUGALLOCATION)
-      target_link_libraries(tcmalloc_debug_static PRIVATE ${libtcmalloc_la_LIBADD})
-      if(NOT MSVC)
-        set_target_properties(tcmalloc_debug_static PROPERTIES
-                OUTPUT_NAME tcmalloc_debug)
-      endif()
-      weaken_object(tcmalloc_debug_static)
-      install(TARGETS tcmalloc_debug_static)
-    endif()
-
-    ### Unittests
-    if(BUILD_TESTING)
-      add_executable(tcmalloc_debug_unittest ${tcmalloc_unittest_SOURCES})
-      target_compile_definitions(tcmalloc_debug_unittest PRIVATE DEBUGALLOCATION ${tcmalloc_unittest})
-      target_link_libraries(tcmalloc_debug_unittest tcmalloc_debug ${tcmalloc_unittest_LIBADD})
-      add_test(tcmalloc_debug_unittest tcmalloc_debug_unittest)
-
-      add_executable(sampler_debug_test ${sampler_test_SOURCES})
-      target_link_libraries(sampler_debug_test tcmalloc_debug ${tcmalloc_unittest_LIBADD})
-      add_test(sampler_debug_test sampler_debug_test)
-
-      add_executable(sampling_debug_test ${sampling_test_SOURCES})
-      target_link_libraries(sampling_debug_test ${TCMALLOC_FLAGS} tcmalloc_debug Threads::Threads)
-      add_test(sampling_debug_test.sh "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/sampling_test.sh" sampling_debug_test)
-
-      if(GPERFTOOLS_BUILD_HEAP_PROFILER)
-        add_executable(heap_profiler_debug_unittest ${heap_profiler_unittest_SOURCES})
-        target_link_libraries(heap_profiler_debug_unittest ${TCMALLOC_FLAGS} tcmalloc_debug Threads::Threads)
-        add_test(heap-profiler_debug_unittest.sh "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-profiler_unittest.sh" heap-profiler_debug_unittest)
-      endif()
-      if(GPERFTOOLS_BUILD_HEAP_CHECKER)
-        add_executable(heap_checker_debug_unittest ${heap_checker_unittest_SOURCES})
-        target_link_libraries(heap_checker_debug_unittest ${TCMALLOC_FLAGS} tcmalloc_debug logging Threads::Threads)
-        add_test(heap-checker_debug_unittest.sh "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-checker_unittest.sh" heap-checker_debug_unittest)
-      endif()
-    endif()
-  endif()
-endif()
-
-### ------- CPU profiler
-if(GPERFTOOLS_BUILD_CPU_PROFILER)
-  ### The header files we use.  We divide into categories based on directory
-  set(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})
-  set(SG_CPU_PROFILER_INCLUDES src/gperftools/profiler.h)
-  set(CPU_PROFILER_INCLUDES ${S_CPU_PROFILER_INCLUDES} ${SG_CPU_PROFILER_INCLUDES}
-          ${SG_STACKTRACE_INCLUDES})
-  list(APPEND perftoolsinclude_HEADERS ${SG_CPU_PROFILER_INCLUDES})
-
-  ### Making the library
-  set(libprofiler_la_SOURCES src/profiler.cc
-          src/profile-handler.cc
-          src/profiledata.cc
-          ${CPU_PROFILER_INCLUDES})
-  set(libprofiler_la_LIBADD stacktrace ${maybe_threads_lib} fake_stacktrace_scope)
-  add_library(profiler SHARED ${libprofiler_la_SOURCES})
-  target_link_libraries(profiler PRIVATE ${libprofiler_la_LIBADD})
-  set_target_properties(profiler PROPERTIES
-          VERSION ${PROFILER_SO_VERSION}
-          SOVERSION ${PROFILER_SO_VERSION})
-  install(TARGETS profiler)
-  if(GPERFTOOLS_BUILD_STATIC)
-    add_library(profiler_static STATIC ${libprofiler_la_SOURCES})
-    target_link_libraries(profiler_static PRIVATE ${libprofiler_la_LIBADD})
-    if(NOT MSVC)
-      set_target_properties(profiler_static PROPERTIES OUTPUT_NAME profiler)
-    endif()
-    install(TARGETS profiler_static)
-  endif()
-
-  # See discussion above (under LIBTCMALLOC_MINIMAL) for why we do this.
-  # Basically it's to work around systems where --rpath doesn't work right.
-  set(LIBPROFILER stacktrace profiler)
-
-  if(BUILD_TESTING)
-    add_executable(getpc_test src/tests/getpc_test.cc src/getpc.h)
-    add_test(getpc_test getpc_test)
-
-    add_executable(profiledata_unittest src/tests/profiledata_unittest.cc
-            src/profiledata.h
-            src/base/commandlineflags.h
-            src/base/logging.h
-            src/base/basictypes.h)
-    target_link_libraries(profiledata_unittest ${LIBPROFILER})
-    add_test(profiledata_unittest profiledata_unittest)
-
-    add_executable(profile_handler_unittest src/tests/profile-handler_unittest.cc
-            src/profile-handler.h)
-    target_link_libraries(profile_handler_unittest ${LIBPROFILER} Threads::Threads)
-    add_test(profile_handler_unittest profile_handler_unittest)
-
-    add_test(NAME profiler_unittest.sh
-            COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/profiler_unittest.sh")
-    set(PROFILER_UNITTEST_INCLUDES src/config_for_unittests.h
-            src/gperftools/profiler.h)
-    set(PROFILER_UNITTEST_SRCS src/tests/profiler_unittest.cc
-            src/tests/testutil.h src/tests/testutil.cc
-            ${PROFILER_UNITTEST_INCLUDES})
-    add_executable(profiler1_unittest ${PROFILER_UNITTEST_SRCS})
-    target_compile_definitions(profiler1_unittest PRIVATE NO_THREADS)
-    target_link_libraries(profiler1_unittest ${LIBPROFILER})
-    add_executable(profiler2_unittest ${PROFILER_UNITTEST_SRCS})
-    target_compile_definitions(profiler2_unittest PRIVATE NO_THREADS)
-    target_link_libraries(profiler2_unittest stacktrace profiler)
-    add_executable(profiler3_unittest ${PROFILER_UNITTEST_SRCS})
-    target_link_libraries(profiler3_unittest ${LIBPROFILER} Threads::Threads)
-    add_executable(profiler4_unittest ${PROFILER_UNITTEST_SRCS})
-    target_link_libraries(profiler4_unittest stacktrace profiler Threads::Threads)
-  endif()
-endif()
-
-install(FILES
-${CMAKE_CURRENT_BINARY_DIR}/gperftools/tcmalloc.h
-        ${perftoolsinclude_HEADERS}
-        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gperftools)
-
-### ------- 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(GPERFTOOLS_BUILD_HEAP_PROFILER OR GPERFTOOLS_BUILD_HEAP_CHECKER)
-    if(GPERFTOOLS_BUILD_CPU_PROFILER)
-      add_library(tcmalloc_and_profiler SHARED ${libtcmalloc_la_SOURCES} ${libprofiler_la_SOURCES})
-      target_compile_definitions(tcmalloc_and_profiler PRIVATE ${libtcmalloc_la_DEFINE})
-      set_target_properties(tcmalloc_and_profiler PROPERTIES
-              VERSION ${TCMALLOC_AND_PROFILER_SO_VERSION}
-              SOVERSION ${TCMALLOC_AND_PROFILER_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. :-(
-      target_link_libraries(tcmalloc_and_profiler PRIVATE ${libtcmalloc_la_LIBADD})
-      weaken_object(tcmalloc_and_profiler)
-      install(TARGETS tcmalloc_and_profiler)
-      if(GPERFTOOLS_BUILD_STATIC)
-        add_library(tcmalloc_and_profiler_static STATIC ${libtcmalloc_la_SOURCES} ${libprofiler_la_SOURCES})
-        target_compile_definitions(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_DEFINE})
-        target_link_libraries(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_LIBADD})
-        if(NOT MSVC)
-          set_target_properties(tcmalloc_and_profiler_static PROPERTIES
-                  OUTPUT_NAME tcmalloc_and_profiler)
-        endif()
-        weaken_object(tcmalloc_and_profiler_static)
-        install(TARGETS tcmalloc_and_profiler_static)
-      endif()
-
-      if(BUILD_TESTING)
-        add_executable(tcmalloc_and_profiler_unittest ${tcmalloc_both_unittest_srcs})
-        target_link_libraries(tcmalloc_and_profiler_unittest tcmalloc_and_profiler Threads::Threads)
-        add_test(tcmalloc_and_profiler_unittest tcmalloc_and_profiler_unittest)
-      endif()
-    endif()
-endif()
-
-if(BUILD_TESTING)
-  get_directory_property(tests TESTS)
-  message("TESTS_ENVIRONMENT:${TESTS_ENVIRONMENT}")
-  if(TESTS_ENVIRONMENT)
-    foreach(test IN LISTS tests)
-      set_tests_properties(${test} PROPERTIES ENVIRONMENT "${TESTS_ENVIRONMENT}")
-    endforeach()
-  endif()
-endif()
-
-if(MSVC)
-    add_subdirectory(src/windows)
-endif()
-
-## ^^^^ END OF RULES TO MAKE YOUR LIBRARIES, BINARIES, AND UNITTESTS
-#TODO rpm deb
-
-# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki
-# 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.
-set(PTHREAD_FLAGS)
-foreach(flag IN ITEMS INTERFACE_LINK_LIBRARIES INTERFACE_LINK_OPTIONS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_COMPILE_OPTIONS INTERFACE_COMPILE_DEFINITIONS INTERFACE_SOURCES)
-  get_target_property(T Threads::Threads ${flag})
-  if(T)
-    set(PTHREAD_FLAGS "${PTHREAD_FLAGS} ${T}")
-  endif()
-endforeach()
-set(NAME tcmalloc)
-configure_file(cmake/pkgconfig.pc libtcmalloc.pc @ONLY)
-set(NAME tcmalloc_debug)
-configure_file(cmake/pkgconfig.pc libtcmalloc_debug.pc @ONLY)
-set(NAME tcmalloc_minimal)
-configure_file(cmake/pkgconfig.pc libtcmalloc_minimal.pc @ONLY)
-set(NAME tcmalloc_minimal_debug)
-configure_file(cmake/pkgconfig.pc libtcmalloc_minimal_debug.pc @ONLY)
-set(NAME profiler)
-configure_file(cmake/pkgconfig.pc libprofiler.pc @ONLY)
-install(FILES
-        ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc.pc
-        ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc_minimal.pc
-        ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc_debug.pc
-        ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc_minimal_debug.pc
-        ${CMAKE_CURRENT_BINARY_DIR}/libprofiler.pc
-        DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
-
-#TODO @GENERATE_CHANGELOG_RULES@
-#TODO dist
diff --git a/third_party/gperftools/COPYING b/third_party/gperftools/COPYING
deleted file mode 100644
index e4956cf..0000000
--- a/third_party/gperftools/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/gperftools/ChangeLog b/third_party/gperftools/ChangeLog
deleted file mode 100644
index 92bcb9b..0000000
--- a/third_party/gperftools/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/gperftools/ChangeLog.old b/third_party/gperftools/ChangeLog.old
deleted file mode 100644
index 4b334be..0000000
--- a/third_party/gperftools/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/gperftools/INSTALL b/third_party/gperftools/INSTALL
deleted file mode 100644
index cfb6b97..0000000
--- a/third_party/gperftools/INSTALL
+++ /dev/null
@@ -1,564 +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 4, 8, 16, 32, 64, 128 or 256 which sets the
-internal page size to 4K, 8K, 16K, 32K, 64K, 128K and 256K respectively.
-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/gperftools/Makefile.am b/third_party/gperftools/Makefile.am
deleted file mode 100644
index bc61f62..0000000
--- a/third_party/gperftools/Makefile.am
+++ /dev/null
@@ -1,1508 +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 =
-
-# These are good warnings to turn on by default.
-if GCC
-AM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual \
-               -Wno-sign-compare
-
-# 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 OMIT_FP_BY_DEFAULT
-if !ENABLE_FRAME_POINTERS
-AM_CXXFLAGS += -DNO_FRAME_POINTER
-endif !ENABLE_FRAME_POINTERS
-endif OMIT_FP_BY_DEFAULT
-
-# respect --enable-frame-pointers regardless of architecture
-if ENABLE_FRAME_POINTERS
-AM_CXXFLAGS += -fno-omit-frame-pointer
-endif ENABLE_FRAME_POINTERS
-
-# 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
-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.vcxproj
-# 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.vcxproj
-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_generic_fp-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 = pprof-symbolize
-
-pprof-symbolize : $(top_srcdir)/src/pprof
-	cp -p $(top_srcdir)/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
-
-if INSTALL_PPROF
-bin_SCRIPTS += src/pprof
-dist_man_MANS = docs/pprof.1
-dist_doc_DATA += docs/pprof_remote_servers.html
-endif INSTALL_PPROF
-
-### Documentation
-
-# On MSVC, we need our own versions of addr2line and nm to work with pprof.
-WINDOWS_PROJECTS += vsprojects/nm-pdb/nm-pdb.vcxproj
-WINDOWS_PROJECTS += vsprojects/addr2line-pdb/addr2line-pdb.vcxproj
-# 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.vcxproj
-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.vcxproj
-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)
-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)
-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.vcxproj
-tcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_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)
-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.vcxproj
-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.vcxproj
-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)
-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.vcxproj
-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.vcxproj
-frag_unittest_SOURCES = src/tests/frag_unittest.cc src/config_for_unittests.h
-frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_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.vcxproj
-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)
-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.vcxproj
-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.vcxproj
-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.vcxproj
-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)
-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.vcxproj
-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.vcxproj
-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)
-pagemap_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-pagemap_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
-
-TESTS += realloc_unittest
-WINDOWS_PROJECTS += vsprojects/realloc_unittest/realloc_unittest.vcxproj
-realloc_unittest_SOURCES = src/tests/realloc_unittest.cc \
-                           src/config_for_unittests.h \
-                           src/base/logging.h
-realloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_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.vcxproj
-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.vcxproj
-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)
-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)
-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)
-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)
-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)
-malloc_bench_shared_full_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_bench_shared_full_LDADD = librun_benchmark.la libtcmalloc.la $(PTHREAD_LIBS)
-
-endif WITH_HEAP_PROFILER_OR_CHECKER
-
-binary_trees_SOURCES = benchmark/binary_trees.cc
-binary_trees_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_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)
-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
-
-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
-MAYBE_NO_HEAP_CHECK =
-else !WITH_HEAP_CHECKER
-HEAP_CHECKER_SOURCES =
-MAYBE_NO_HEAP_CHECK = -DNO_HEAP_CHECK
-endif !WITH_HEAP_CHECKER
-
-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) \
-                                   $(MAYBE_NO_HEAP_CHECK)
-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) \
-                         $(HEAP_CHECKER_SOURCES)
-libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS) \
-                          $(MAYBE_NO_HEAP_CHECK) $(EMERGENCY_MALLOC_DEFINE)
-libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@
-libtcmalloc_la_LIBADD = libtcmalloc_internal.la libmaybe_threads.la $(PTHREAD_LIBS)
-
-# same as above with without -DNDEBUG
-noinst_LTLIBRARIES += libtcmalloc_internal_with_asserts.la
-libtcmalloc_internal_with_asserts_la_SOURCES = $(libtcmalloc_internal_la_SOURCES)
-libtcmalloc_internal_with_asserts_la_CXXFLAGS = $(PTHREAD_CFLAGS) \
-                                   $(AM_CXXFLAGS) $(EMERGENCY_MALLOC_DEFINE) \
-                                   $(MAYBE_NO_HEAP_CHECK)
-libtcmalloc_internal_with_asserts_la_LDFLAGS = $(PTHREAD_CFLAGS)
-libtcmalloc_internal_with_asserts_la_LIBADD = libstacktrace.la $(PTHREAD_LIBS)
-
-noinst_LTLIBRARIES += libtcmalloc_with_asserts.la
-libtcmalloc_with_asserts_la_SOURCES = $(libtcmalloc_la_SOURCES)
-libtcmalloc_with_asserts_la_CXXFLAGS =  $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) \
-                          $(MAYBE_NO_HEAP_CHECK) $(EMERGENCY_MALLOC_DEFINE)
-libtcmalloc_with_asserts_la_LDFLAGS = $(PTHREAD_CFLAGS)
-libtcmalloc_with_asserts_la_LIBADD = libtcmalloc_internal_with_asserts.la libmaybe_threads.la $(PTHREAD_LIBS)
-
-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)
-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)
-
-TESTS += tcm_asserts_unittest
-tcm_asserts_unittest_INCLUDES = src/config_for_unittests.h \
-                             src/gperftools/malloc_extension.h
-tcm_asserts_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
-                            src/tcmalloc.h \
-                            src/tests/testutil.h src/tests/testutil.cc \
-                            $(TCMALLOC_UNITTEST_INCLUDES)
-tcm_asserts_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
-tcm_asserts_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-tcm_asserts_unittest_LDADD = libtcmalloc_with_asserts.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)
-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)
-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)
-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.vcxproj
-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)
-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)
-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|ProfilerGetStackTrace)'
-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.vcxproj
-getpc_test_SOURCES = src/tests/getpc_test.cc src/getpc.h
-
-TESTS += profiledata_unittest
-#WINDOWS_PROJECTS += vsprojects/profiledata_unittest/profiledata_unittest.vcxproj
-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_AND_PROFILER_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 .vcxproj 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/gperftools/NEWS b/third_party/gperftools/NEWS
deleted file mode 100644
index 44095ec..0000000
--- a/third_party/gperftools/NEWS
+++ /dev/null
@@ -1,1193 +0,0 @@
-== 2 March 2021 ==
-gperftools 2.9.1 is out!
-
-Minor fixes landed since previous release:
-
-* OSX builds new prefer backtrace() and have somewhat working heap
-  sampling.
-
-* Incorrect assertion failure was fixed that crashed tcmalloc if
-  assertions were on and sized delete was used. More details in github
-  issue #1254.
-
-== 21 February 2021 ==
-gperftools 2.9 is out!
-
-Few more changes landed compared to rc:
-
-* Venkatesh Srinivas has contributed thread-safety annotations
-  support.
-
-* couple more unit test bugs that caused tcmalloc_unittest to fail on
-  recent clang has been fixed.
-
-* usage of unsupportable linux_syscall_support.h has been removed from
-  few places. Building with --disable-heap-checker now completely
-  avoids it. Expect complete death of this header in next major
-  release.
-
-== 14 February 2021 ==
-gperftools 2.9rc is out!
-
-Here are notable changes:
-
-* Jarno Rajahalme has contributed fix for crashing bug in syscalls
-  support for aarch64.
-
-* User SSE4 has contributed basic support for Elbrus 2000 architecture
-  (!)
-
-* Venkatesh Srinivas has contributed cleanup to atomic ops.
-
-* Đoàn Trần Công Danh has fixed cpu profiler compilation on musl.
-
-* there is now better backtracing support for aarch64 and
-  riscv. x86-64 with frame pointers now also defaults to this new
-  "generic" frame pointer backtracer.
-
-* emergency malloc is now enabled by default. Fixes hang on musl when
-  libgcc backtracer is enabled.
-
-* bunch of legacy config tests has been removed
-
-== 20 December 2020 ==
-gperftools 2.8.1 is out!
-
-Here are notable changes:
-
-* previous release contained change to release memory without page
-  heap lock, but this change had at least one bug that caused to
-  crashes and corruption when running under aggressive decommit mode
-  (this is not default). While we check for other bugs, this feature
-  was reverted. See github issue #1204 and issue #1227.
-
-* stack traces depth captured by gperftools is now up to 254 levels
-  deep. Thanks to Kerrick Staley for this small but useful tweak.
-
-* Levon Ter-Grigoryan has contributed small fix for compiler warning.
-
-* Grant Henke has contributed updated detection of program counter
-  register for OS X on arm64.
-
-* Tim Gates has contributed small typo fix.
-
-* Steve Langasek has contributed basic build fixes for riscv64 (!).
-
-* Isaac Hier and okhowang have contributed premiliminary port of build
-  infrastructure to cmake. This works, but it is very premiliminary.
-  Autotools-based build is the only officially supported build for
-  now.
-
-== 6 July 2020 ==
-gperftools 2.8 is out!
-
-Here are notable changes:
-
-* ProfilerGetStackTrace is now officially supported API for
-  libprofiler. Contributed by Kirill Müller.
-
-* Build failures on mingw were fixed. This fixed issue #1108.
-
-* Build failure of page_heap_test on MSVC was fixed.
-
-* Ryan Macnak contributed fix for compiling linux syscall support on
-  i386 and recent GCCs. This fixed issue #1076.
-
-* test failures caused by new gcc 10 optimizations were fixed. Same
-  change also fixed tests on clang.
-
-== 8 Mar 2020 ==
-gperftools 2.8rc is out!
-
-Here are notable changes:
-
-* building code now requires c++11 or later. Bundled MSVC project was
-  converted to Visual Studio 2015.
-
-* User obones contributed fix for windows x64 TLS callbacks. This
-  fixed leak of thread caches on thread exists in 64-bit windows.
-
-* releasing memory back to kernel is now made with page heap lock
-  dropped.
-
-* HoluWu contributed fix for correct malloc patching on debug builds
-  on windows. This configuration previously crashed.
-
-* Romain Geissler contributed fix for tls access during early tls
-  initialization on dlopen.
-
-* large allocation reports are now silenced by default. Since not all
-  programs want their stderr polluted by those messages. Contributed
-  by Junhao Li.
-
-* HolyWu contributed improvements to MSVC project files. Notably,
-  there is now project for "overriding" version of tcmalloc.
-
-* MS-specific _recalloc is now correctly zeroing only malloced
-  part. This fix was contributed by HolyWu.
-
-* Brian Silverman contributed correctness fix to sampler_test.
-
-* Gabriel Marin ported few fixes from chromium's fork. As part of
-  those fixes, we reduced number of static initializers (forbidden in
-  chromium). Also we now syscalls via syscall function instead of
-  reimplementing direct way to make syscalls on each platform.
-
-* Brian Silverman fixed flakiness in page heap test.
-
-* There is now configure flag to skip installing perl pprof, since
-  external golang pprof is much superior. --disable-deprecated-pprof
-  is the flag.
-
-* Fabric Fontaine contributed fixes to drop use of nonstandard
-  __off64_t type.
-
-* Fabrice Fontaine contributed build fix to check for presence of
-  nonstandard __sbrk functions. It is only used by mmap hooks code and
-  (rightfully) not available on musl.
-
-* Fabrice Fontaine contributed build fix around mmap64 macro and
-  function conflict in same cases.
-
-* there is now configure time option to enable aggressive decommit by
-  default. Contributed by Laurent
-  Stacul. --enable-aggressive-decommit-by-default is the flag.
-
-* Tulio Magno Quites Machado Filho contributed build fixes for ppc
-  around ucontext access.
-
-* User pkubaj contributed couple build fixes for FreeBSD/ppc.
-
-* configure now always assumes we have mmap. This fixes configure
-  failures on some linux guests inside virtualbox. This fixed issue
-  #1008.
-
-* User shipujin contributed syscall support fixes for mips64 (big and
-  little endian).
-
-* Henrik Edin contributed configurable support for wide range of
-  malloc page sizes. 4K, 8K, 16K, 32K, 64K, 128K and 256K are now
-  supported via existing --with-tcmalloc-pagesize flag to configure.
-
-* Jon Kohler added overheads fields to per-size-class textual
-  stats. Stats that are available via
-  MallocExtension::instance()->GetStats().
-
-* tcmalloc can now avoid fallback from memfs to default sys
-  allocator. TCMALLOC_MEMFS_DISABLE_FALLBACK switches this on. This
-  was contributed by Jon Kohler.
-
-* Ilya Leoshkevich fixed mmap syscall support on s390.
-
-* Todd Lipcon contributed small build warning fix.
-
-* User prehistoricpenguin contributed misc source file mode fixes (we
-  still had few few c++ files marked executable).
-
-* User invalid_ms_user contributed fix for typo.
-
-* Jakub Wilk contributed typos fixes.
-
-== 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/gperftools/README b/third_party/gperftools/README
deleted file mode 100644
index 714a524..0000000
--- a/third_party/gperftools/README
+++ /dev/null
@@ -1,279 +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 Go 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.
-
-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 performance.  (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
-crashes.
-
-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/gperftools/README_windows.txt b/third_party/gperftools/README_windows.txt
deleted file mode 100644
index 7bba122..0000000
--- a/third_party/gperftools/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/gperftools/TODO b/third_party/gperftools/TODO
deleted file mode 100644
index 550f7e0..0000000
--- a/third_party/gperftools/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/gperftools/autogen.sh b/third_party/gperftools/autogen.sh
deleted file mode 100755
index 7c590a3..0000000
--- a/third_party/gperftools/autogen.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-autoreconf -i
diff --git a/third_party/gperftools/benchmark/binary_trees.cc b/third_party/gperftools/benchmark/binary_trees.cc
deleted file mode 100644
index 4c895b2..0000000
--- a/third_party/gperftools/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/gperftools/benchmark/malloc_bench.cc b/third_party/gperftools/benchmark/malloc_bench.cc
deleted file mode 100644
index 371b8c6..0000000
--- a/third_party/gperftools/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/gperftools/benchmark/run_benchmark.c b/third_party/gperftools/benchmark/run_benchmark.c
deleted file mode 100644
index 9bf04f4..0000000
--- a/third_party/gperftools/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/gperftools/benchmark/run_benchmark.h b/third_party/gperftools/benchmark/run_benchmark.h
deleted file mode 100644
index e030d1e..0000000
--- a/third_party/gperftools/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/gperftools/cmake/DefineTargetVariables.cmake b/third_party/gperftools/cmake/DefineTargetVariables.cmake
deleted file mode 100644
index ada0152..0000000
--- a/third_party/gperftools/cmake/DefineTargetVariables.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-if(NOT COMMAND check_cxx_source_compiles)
-  include(CheckCXXSourceCompiles)
-endif()
-
-macro(define_target_variables)
-  check_cxx_source_compiles("int main() { return __i386__; }" i386)
-  check_cxx_source_compiles("int main() { return __s390__; }" s390)
-  check_cxx_source_compiles("int main() { return __PPC64__; }" PPC64)
-  check_cxx_source_compiles("int main() { return __x86_64__; }" x86_64)
-  check_cxx_source_compiles("int main() { return __arm__; }" ARM)
-  check_cxx_source_compiles("int main() { return __FreeBSD__; }" FreeBSD)
-  check_cxx_source_compiles("int main() { return __MINGW__; }" MINGW)
-  check_cxx_source_compiles("int main() { return __linux; }" LINUX)
-  check_cxx_source_compiles("int main() { return __APPLE__; }" OSX)
-endmacro()
diff --git a/third_party/gperftools/cmake/FindObjcopyWithWeaken.cmake b/third_party/gperftools/cmake/FindObjcopyWithWeaken.cmake
deleted file mode 100644
index 95c81da..0000000
--- a/third_party/gperftools/cmake/FindObjcopyWithWeaken.cmake
+++ /dev/null
@@ -1,54 +0,0 @@
-function(find_objcopy_with_weaken)
-  find_program(OBJCOPY_EXECUTABLE "objcopy")
-  message(STATUS "Looking for objcopy that supports weaken - ${OBJCOPY_EXECUTABLE}")
-  if(NOT OBJCOPY_EXECUTABLE)
-    return()
-  endif()
-  set(objcopy_test_src "${CMAKE_CURRENT_BINARY_DIR}/objcopy_test.c")
-  set(objcopy_test_exe "${CMAKE_CURRENT_BINARY_DIR}/objcopy_test")
-  file(WRITE ${objcopy_test_src} "void foo() {} int main() { return 0; }")
-  try_compile(objcopy_test_compiled
-          ${CMAKE_CURRENT_BINARY_DIR} ${objcopy_test_src}
-          COPY_FILE ${objcopy_test_exe})
-  if(objcopy_test_compiled AND EXISTS ${objcopy_test_exe})
-    execute_process(
-            COMMAND ${OBJCOPY_EXECUTABLE} -W foo ${objcopy_test_exe}
-            RESULT_VARIABLE objcopy_result)
-    file(REMOVE ${objcopy_test_exe})
-  endif()
-  if(objcopy_result EQUAL 0)
-    set(objcopy_weaken ON)
-  endif()
-  file(REMOVE ${objcopy_test_src})
-  if(objcopy_weaken)
-    set(objcopy_has_weaken "Success")
-    set(HAVE_OBJCOPY_WEAKEN TRUE PARENT_SCOPE)
-    set(OBJCOPY_EXECUTABLE "${OBJCOPY_EXECUTABLE}" PARENT_SCOPE)
-  else()
-    set(objcopy_has_weaken "Failed")
-  endif()
-  message(STATUS "objcopy has weaken support - ${objcopy_has_weaken}")
-endfunction(find_objcopy_with_weaken)
-
-function(weaken_object target)
-  if(NOT HAVE_OBJCOPY_WEAKEN)
-      return()
-  endif()
-  # 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.
-  add_custom_command(TARGET ${target} POST_BUILD
-          COMMAND "${OBJCOPY_EXECUTABLE}"
-          -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 "$<TARGET_FILE:${target}>")
-endfunction()
\ No newline at end of file
diff --git a/third_party/gperftools/cmake/PCFromUContext.cmake b/third_party/gperftools/cmake/PCFromUContext.cmake
deleted file mode 100644
index d231124..0000000
--- a/third_party/gperftools/cmake/PCFromUContext.cmake
+++ /dev/null
@@ -1,64 +0,0 @@
-include(CheckCSourceCompiles)
-include(CheckIncludeFile)
-
-macro(pc_from_ucontext variable)
-    set(HAVE_${variable} OFF)
-    check_include_file("ucontext.h" HAVE_UCONTEXT_H)
-    if(EXISTS /etc/redhat-release)
-        set(redhat7_release_pattern "Red Hat Linux release 7")
-        file(STRINGS /etc/redhat-release redhat_release_match
-             LIMIT_COUNT 1
-             REGEX ${redhat7_release_pattern})
-        if(redhat_release_match MATCHES ${redhat7_release_pattern})
-            set(HAVE_SYS_UCONTEXT_H OFF)
-        else()
-            check_include_file("sys/ucontext.h" HAVE_SYS_UCONTEXT_H)
-        endif()
-    else()
-        check_include_file("sys/ucontext.h" HAVE_SYS_UCONTEXT_H)
-    endif()
-    check_include_file("cygwin/signal.h" HAVE_CYGWIN_SIGNAL_H)
-
-    set(pc_fields
-        "uc_mcontext.gregs[REG_PC]"  # Solaris x86 (32 + 64 bit)
-        "uc_mcontext.gregs[REG_EIP]"  # Linux (i386)
-        "uc_mcontext.gregs[REG_RIP]"  # Linux (x86_64)
-        "uc_mcontext.sc_ip"  # Linux (ia64)
-        "uc_mcontext.pc"  # Linux (mips)
-        "uc_mcontext.uc_regs->gregs[PT_NIP]"  # Linux (ppc)
-        "uc_mcontext.psw.addr"  # Linux (s390)
-        "uc_mcontext.gregs[R15]"  # Linux (arm old [untested])
-        "uc_mcontext.arm_pc"  # Linux (arm arch 5)
-        "uc_mcontext.cr0_hi"  # Linux (e2k)
-        "uc_mcontext.gp_regs[PT_NIP]"  # Suse SLES 11 (ppc64)
-        "uc_mcontext.mc_eip"  # FreeBSD (i386)
-        "uc_mcontext.mc_rip"  # FreeBSD (x86_64 [untested])
-        "uc_mcontext.__gregs[_REG_EIP]"  # NetBSD (i386)
-        "uc_mcontext.__gregs[_REG_RIP]"  # NetBSD (x86_64)
-        "uc_mcontext->ss.eip"  # OS X (i386, <=10.4)
-        "uc_mcontext->__ss.__eip"  # OS X (i386, >=10.5)
-        "uc_mcontext->ss.rip"  # OS X (x86_64)
-        "uc_mcontext->__ss.__rip"  # OS X (>=10.5 [untested])
-        "uc_mcontext->ss.srr0"  # OS X (ppc, ppc64 [untested])
-        "uc_mcontext->__ss.__srr0")  # OS X (>=10.5 [untested])
-
-    set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE=1)
-    if(HAVE_CYGWIN_SIGNAL_H)
-        set(_inc "cygwin/signal.h")
-    elseif(HAVE_SYS_UCONTEXT_H)
-        set(_inc "sys/ucontext.h")
-    elseif(HAVE_UCONTEXT_H)
-        set(_inc "ucontext.h")
-    endif()
-    foreach(pc_field IN LISTS pc_fields)
-        string(MAKE_C_IDENTIFIER ${pc_field} pc_field_id)
-        check_c_source_compiles(
-            "#include <${_inc}>\nint main() { ucontext_t u; return u.${pc_field} == 0; }"
-            HAVE_${pc_field_id})
-        if(HAVE_${pc_field_id})
-            set(HAVE_${variable} ON)
-            set(${variable} ${pc_field})
-            break()
-        endif()
-    endforeach()
-endmacro()
diff --git a/third_party/gperftools/cmake/config.h.in b/third_party/gperftools/cmake/config.h.in
deleted file mode 100644
index 030955a..0000000
--- a/third_party/gperftools/cmake/config.h.in
+++ /dev/null
@@ -1,313 +0,0 @@
-/* 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_
-
-/* Enable aggressive decommit by default */
-#cmakedefine ENABLE_AGGRESSIVE_DECOMMIT_BY_DEFAULT
-
-/* Build new/delete operators for overaligned types */
-#cmakedefine ENABLE_ALIGNED_NEW_DELETE
-
-/* Build runtime detection for sized delete */
-#cmakedefine ENABLE_DYNAMIC_SIZED_DELETE
-
-/* Report large allocation */
-#cmakedefine ENABLE_LARGE_ALLOC_REPORT
-
-/* Build sized deletion operators */
-#cmakedefine ENABLE_SIZED_DELETE
-
-/* Define to 1 if you have the <asm/ptrace.h> header file. */
-#cmakedefine HAVE_ASM_PTRACE_H
-
-/* Define to 1 if you have the <cygwin/signal.h> header file. */
-#cmakedefine HAVE_CYGWIN_SIGNAL_H
-
-/* Define to 1 if you have the declaration of `backtrace', and to 0 if you
-   don't. */
-#cmakedefine01 HAVE_DECL_BACKTRACE
-
-/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
-   */
-#cmakedefine01 HAVE_DECL_CFREE
-
-/* Define to 1 if you have the declaration of `memalign', and to 0 if you
-   don't. */
-#cmakedefine01 HAVE_DECL_MEMALIGN
-
-/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you
-   don't. */
-#cmakedefine01 HAVE_DECL_NANOSLEEP
-
-/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if
-   you don't. */
-#cmakedefine01 HAVE_DECL_POSIX_MEMALIGN
-
-/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you
-   don't. */
-#cmakedefine01 HAVE_DECL_PVALLOC
-
-/* Define to 1 if you have the declaration of `sleep', and to 0 if you don't.
-   */
-#cmakedefine01 HAVE_DECL_SLEEP
-
-/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't.
-   */
-#cmakedefine01 HAVE_DECL_VALLOC
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H
-
-/* Define to 1 if the system has the type `Elf32_Versym'. */
-#cmakedefine HAVE_ELF32_VERSYM
-
-/* Define to 1 if you have the <execinfo.h> header file. */
-#cmakedefine HAVE_EXECINFO_H
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#cmakedefine HAVE_FCNTL_H
-
-/* Define to 1 if you have the <features.h> header file. */
-#cmakedefine HAVE_FEATURES_H
-
-/* Define to 1 if you have the `fork' function. */
-#cmakedefine HAVE_FORK
-
-/* Define to 1 if you have the `geteuid' function. */
-#cmakedefine HAVE_GETEUID
-
-/* Define to 1 if you have the <glob.h> header file. */
-#cmakedefine HAVE_GLOB_H
-
-/* Define to 1 if you have the <grp.h> header file. */
-#cmakedefine HAVE_GRP_H
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <libunwind.h> header file. */
-#cmakedefine HAVE_LIBUNWIND_H
-
-/* Define to 1 if you have the <linux/ptrace.h> header file. */
-#cmakedefine HAVE_LINUX_PTRACE_H
-
-/* Define if this is Linux that has SIGEV_THREAD_ID */
-#cmakedefine01 HAVE_LINUX_SIGEV_THREAD_ID
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#cmakedefine HAVE_MALLOC_H
-
-/* Define to 1 if you have the <malloc/malloc.h> header file. */
-#cmakedefine HAVE_MALLOC_MALLOC_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H
-
-/* Define to 1 if you have a working `mmap' system call. */
-#cmakedefine HAVE_MMAP
-
-/* Define to 1 if you have the <poll.h> header file. */
-#cmakedefine HAVE_POLL_H
-
-/* define if libc has program_invocation_name */
-#cmakedefine HAVE_PROGRAM_INVOCATION_NAME
-
-/* Define if you have POSIX threads libraries and header files. */
-#cmakedefine HAVE_PTHREAD
-
-/* defined to 1 if pthread symbols are exposed even without include pthread.h
-   */
-#cmakedefine HAVE_PTHREAD_DESPITE_ASKING_FOR
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#cmakedefine HAVE_PWD_H
-
-/* Define to 1 if you have the `sbrk' function. */
-#cmakedefine HAVE_SBRK
-
-/* Define to 1 if you have the <sched.h> header file. */
-#cmakedefine HAVE_SCHED_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H
-
-/* Define to 1 if the system has the type `struct mallinfo'. */
-#cmakedefine HAVE_STRUCT_MALLINFO
-
-/* Define to 1 if you have the <sys/cdefs.h> header file. */
-#cmakedefine HAVE_SYS_CDEFS_H
-
-/* Define to 1 if you have the <sys/malloc.h> header file. */
-#cmakedefine HAVE_SYS_MALLOC_H
-
-/* Define to 1 if you have the <sys/prctl.h> header file. */
-#cmakedefine HAVE_SYS_PRCTL_H
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#cmakedefine HAVE_SYS_RESOURCE_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#cmakedefine HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#cmakedefine HAVE_SYS_SYSCALL_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <sys/ucontext.h> header file. */
-#cmakedefine HAVE_SYS_UCONTEXT_H
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#cmakedefine HAVE_SYS_WAIT_H
-
-/* Define to 1 if compiler supports __thread */
-#cmakedefine HAVE_TLS
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-#cmakedefine HAVE_UCONTEXT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#cmakedefine HAVE_UNISTD_H
-
-/* Whether <unwind.h> contains _Unwind_Backtrace */
-#cmakedefine HAVE_UNWIND_BACKTRACE
-
-/* Define to 1 if you have the <unwind.h> header file. */
-#cmakedefine HAVE_UNWIND_H
-
-/* define if your compiler has __attribute__ */
-#cmakedefine HAVE___ATTRIBUTE__
-
-/* define if your compiler supports alignment of functions */
-#cmakedefine HAVE___ATTRIBUTE__ALIGNED_FN
-
-/* Define to 1 if compiler supports __environ */
-#cmakedefine HAVE___ENVIRON
-
-/* Define to 1 if you have the `__sbrk' function. */
-#cmakedefine HAVE___SBRK
-
-/* prefix where we look for installed files */
-#cmakedefine INSTALL_PREFIX
-
-/* Define to 1 if int32_t is equivalent to intptr_t */
-#cmakedefine INT32_EQUALS_INTPTR
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#cmakedefine LT_OBJDIR
-
-/* Name of package */
-#define PACKAGE "@PROJECT_NAME@"
-
-/* 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 "@PROJECT_NAME@"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "@PROJECT_NAME@ @PROJECT_VERSION@"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "@PROJECT_NAME@"
-
-/* Define to the home page for this package. */
-#cmakedefine PACKAGE_URL
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "@PROJECT_VERSION@"
-
-/* How to access the PC from a struct ucontext */
-#define PC_FROM_UCONTEXT @PC_FROM_UCONTEXT_DEF@
-
-/* 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 WIN32
-#cmakedefine WIN32
-#endif
-#if defined(WIN32)
-#ifndef PERFTOOLS_DLL_DECL
-# define PERFTOOLS_IS_A_DLL  1
-# define PERFTOOLS_DLL_DECL  __declspec(dllexport)
-# define PERFTOOLS_DLL_DECL_FOR_UNITTESTS  __declspec(dllimport)
-#endif
-#else
-#ifndef PERFTOOLS_DLL_DECL
-# define PERFTOOLS_DLL_DECL
-# define PERFTOOLS_DLL_DECL_FOR_UNITTESTS
-#endif
-#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. */
-#define PTHREAD_CREATE_JOINABLE @PTHREAD_CREATE_JOINABLE@
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define 8 bytes of allocation alignment for tcmalloc */
-#cmakedefine TCMALLOC_ALIGN_8BYTES
-
-/* Define internal page size for tcmalloc as number of left bitshift */
-#cmakedefine TCMALLOC_PAGE_SIZE_SHIFT
-
-/* Version number of package */
-#define VERSION @PROJECT_VERSION@
-
-/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-# define __STDC_FORMAT_MACROS 1
-#endif
-
-// ---------------------------------------------------------------------
-// Extra stuff not found in config.h.in
-#if defined(WIN32)
-
-// 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
-#endif  /* GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ */
diff --git a/third_party/gperftools/cmake/pkgconfig.pc b/third_party/gperftools/cmake/pkgconfig.pc
deleted file mode 100644
index d816c11..0000000
--- a/third_party/gperftools/cmake/pkgconfig.pc
+++ /dev/null
@@ -1,14 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
-includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
-
-Name: @CMAKE_PROJECT_NAME@
-Version: @CMAKE_PROJECT_VERSION@
-Description: @CMAKE_PROJECT_DESCRIPTION@
-URL: @CMAKE_PROJECT_HOMEPAGE_URL@
-Requires:
-Libs: -L${libdir} -l@NAME@
-Libs.private:@PTHREAD_FLAGS@
-Cflags: -I${includedir}
-
diff --git a/third_party/gperftools/cmake/tcmalloc.h.in b/third_party/gperftools/cmake/tcmalloc.h.in
deleted file mode 100644
index 1d265a0..0000000
--- a/third_party/gperftools/cmake/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  @PROJECT_VERSION_MAJOR@
-#define TC_VERSION_MINOR  @PROJECT_VERSION_MINOR@
-#define TC_VERSION_PATCH  ".@PROJECT_VERSION_PATCH@"
-#define TC_VERSION_STRING "gperftools @PROJECT_VERSION@"
-
-/* 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
-
-#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 @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/gperftools/configure.ac b/third_party/gperftools/configure.ac
deleted file mode 100644
index c419d5f..0000000
--- a/third_party/gperftools/configure.ac
+++ /dev/null
@@ -1,657 +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.9.1],[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:9:5
-PROFILER_SO_VERSION=5:4:5
-TCMALLOC_AND_PROFILER_SO_VERSION=10:4:6
-
-AC_SUBST(TCMALLOC_SO_VERSION)
-AC_SUBST(PROFILER_SO_VERSION)
-AC_SUBST(TCMALLOC_AND_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 and OSX.
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [
-#if !defined(__s390__) && !defined(__APPLE__)
-#error not s390 and not osx
-#endif
-return 1
-])],
-                  [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 4K, 8K, 16K, 32K, 64K, 128K or 256K])],
-            [],
-            [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
-  4)
-       AC_DEFINE(TCMALLOC_PAGE_SIZE_SHIFT, 12);;
-  8)
-       #Default tcmalloc page size.
-       ;;
-  16)
-       AC_DEFINE(TCMALLOC_PAGE_SIZE_SHIFT, 14);;
-  32)
-       AC_DEFINE(TCMALLOC_PAGE_SIZE_SHIFT, 15);;
-  64)
-       AC_DEFINE(TCMALLOC_PAGE_SIZE_SHIFT, 16);;
-  128)
-       AC_DEFINE(TCMALLOC_PAGE_SIZE_SHIFT, 17);;
-  256)
-       AC_DEFINE(TCMALLOC_PAGE_SIZE_SHIFT, 18,
-                 [Define internal page size for tcmalloc as number of left bitshift]);;
-  *)
-       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
-
-AX_CXX_COMPILE_STDCXX(11, ext, mandatory)
-
-# 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
-
-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([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(__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, __GLIBC__ macros
-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(sys/cdefs.h)   # Where glibc defines __THROW
-# 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 hardcode HAVE_MMAP to 1. There are no interesting systems anymore
-# without functional mmap. And our windows (except mingw) builds
-# aren't using autoconf. So we keep HAVE_MMAP define, but only to
-# distingush windows and rest.
-case "$host" in
-   *-mingw*) default_emergency_malloc=no;;
-   *) default_emergency_malloc=yes
-      AC_DEFINE(HAVE_MMAP, 1, [Define to 1 if you have a working `mmap' system call.])
-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])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
-                  [is_x86_64=yes], [is_x86_64=no])
-omit_fp_by_default=no
-AS_IF([test "$is_x86_64" = yes], [omit_fp_by_default=yes])
-AM_CONDITIONAL(OMIT_FP_BY_DEFAULT,
-               test "$omit_fp_by_default" = yes)
-AC_MSG_RESULT([$omit_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([deprecated-pprof],
-              [AS_HELP_STRING([--disable-deprecated-pprof],
-                [do not install old deprecated and unmaintained bundled pprof
-(see github.com/google/pprof for supported version)])],
-              [enable_pprof="$enableval"],
-              [enable_pprof=yes])
-
-AM_CONDITIONAL(INSTALL_PPROF,
-               [test "x$enable_pprof" = xyes])
-
-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>
-#if defined(__APPLE__)
-#error OSX _Unwind_Backtrace recurses back to malloc
-#endif
-]],
-                    [[&_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$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])
-
-# 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 __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)
-
-# 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)
-
-# 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])])
-
-# Disable large allocation report by default.
-AC_ARG_ENABLE([large-alloc-report],
-              [AS_HELP_STRING([--enable-large-alloc-report],
-                              [report very large allocations to stderr])],
-              [enable_large_alloc_report="$enableval"],
-              [enable_large_alloc_report=no])
-AS_IF([test "x$enable_large_alloc_report" = xyes],
-      [AC_DEFINE([ENABLE_LARGE_ALLOC_REPORT], 1, [report large allocation])])
-
-# Enable aggressive decommit by default
-AC_ARG_ENABLE([aggressive-decommit-by-default],
-              [AS_HELP_STRING([--enable-aggressive-decommit-by-default],
-                              [enable aggressive decommit by default])],
-              [enable_aggressive_decommit_by_default="$enableval"],
-              [enable_aggressive_decommit_by_default=no])
-AS_IF([test "x$enable_aggressive_decommit_by_default" = xyes],
-      [AC_DEFINE([ENABLE_AGGRESSIVE_DECOMMIT_BY_DEFAULT],
-                 1,
-                 [enable aggressive decommit by default])])
-
-# Write generated configuration file
-AC_CONFIG_FILES([Makefile
-                 src/gperftools/tcmalloc.h src/windows/gperftools/tcmalloc.h])
-AC_OUTPUT
-
-AS_IF([test "$omit_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/gperftools/docs/cpuprofile-fileformat.html b/third_party/gperftools/docs/cpuprofile-fileformat.html
deleted file mode 100644
index 3f90e6b..0000000
--- a/third_party/gperftools/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/gperftools/docs/cpuprofile.html b/third_party/gperftools/docs/cpuprofile.html
deleted file mode 100644
index c81feb6..0000000
--- a/third_party/gperftools/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/gperftools/docs/designstyle.css b/third_party/gperftools/docs/designstyle.css
deleted file mode 100644
index 29299af..0000000
--- a/third_party/gperftools/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/gperftools/docs/heap-example1.png b/third_party/gperftools/docs/heap-example1.png
deleted file mode 100644
index 9a14b6f..0000000
--- a/third_party/gperftools/docs/heap-example1.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/heap_checker.html b/third_party/gperftools/docs/heap_checker.html
deleted file mode 100644
index ca05b50..0000000
--- a/third_party/gperftools/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/gperftools/docs/heapprofile.html b/third_party/gperftools/docs/heapprofile.html
deleted file mode 100644
index 6f50869..0000000
--- a/third_party/gperftools/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/gperftools/docs/index.html b/third_party/gperftools/docs/index.html
deleted file mode 100644
index 7b93ed3..0000000
--- a/third_party/gperftools/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/gperftools/docs/overview.dot b/third_party/gperftools/docs/overview.dot
deleted file mode 100644
index 9966f56..0000000
--- a/third_party/gperftools/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/gperftools/docs/overview.gif b/third_party/gperftools/docs/overview.gif
deleted file mode 100644
index 43828da..0000000
--- a/third_party/gperftools/docs/overview.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/pageheap.dot b/third_party/gperftools/docs/pageheap.dot
deleted file mode 100644
index 5e9aec8..0000000
--- a/third_party/gperftools/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/gperftools/docs/pageheap.gif b/third_party/gperftools/docs/pageheap.gif
deleted file mode 100644
index 5cf00bd..0000000
--- a/third_party/gperftools/docs/pageheap.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/pprof-test-big.gif b/third_party/gperftools/docs/pprof-test-big.gif
deleted file mode 100644
index 67a1240..0000000
--- a/third_party/gperftools/docs/pprof-test-big.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/pprof-test.gif b/third_party/gperftools/docs/pprof-test.gif
deleted file mode 100644
index 9eeab8a..0000000
--- a/third_party/gperftools/docs/pprof-test.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/pprof-vsnprintf-big.gif b/third_party/gperftools/docs/pprof-vsnprintf-big.gif
deleted file mode 100644
index 2ab292a..0000000
--- a/third_party/gperftools/docs/pprof-vsnprintf-big.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/pprof-vsnprintf.gif b/third_party/gperftools/docs/pprof-vsnprintf.gif
deleted file mode 100644
index 42a8547..0000000
--- a/third_party/gperftools/docs/pprof-vsnprintf.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/pprof.1 b/third_party/gperftools/docs/pprof.1
deleted file mode 100644
index f0f6caf..0000000
--- a/third_party/gperftools/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/gperftools/docs/pprof.see_also b/third_party/gperftools/docs/pprof.see_also
deleted file mode 100644
index f2caf52..0000000
--- a/third_party/gperftools/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/gperftools/docs/pprof_remote_servers.html b/third_party/gperftools/docs/pprof_remote_servers.html
deleted file mode 100644
index e30e612..0000000
--- a/third_party/gperftools/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/gperftools/docs/spanmap.dot b/third_party/gperftools/docs/spanmap.dot
deleted file mode 100644
index 3cb42ab..0000000
--- a/third_party/gperftools/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/gperftools/docs/spanmap.gif b/third_party/gperftools/docs/spanmap.gif
deleted file mode 100644
index a0627f6..0000000
--- a/third_party/gperftools/docs/spanmap.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/t-test1.times.txt b/third_party/gperftools/docs/t-test1.times.txt
deleted file mode 100644
index 0163693..0000000
--- a/third_party/gperftools/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/gperftools/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png
deleted file mode 100644
index 8c0ae6b..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.1024.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png
deleted file mode 100644
index 24b2a27..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.128.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png
deleted file mode 100644
index 183a77b..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.131072.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png
deleted file mode 100644
index db59d61..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.16384.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png
deleted file mode 100644
index 169546f..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.2048.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png
deleted file mode 100644
index 6213021..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.256.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png
deleted file mode 100644
index 18715e3..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.32768.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png
deleted file mode 100644
index 642e245..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.4096.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png
deleted file mode 100644
index aea1d67..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.512.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png
deleted file mode 100644
index 3a080de..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.64.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png
deleted file mode 100644
index 48ebdb6..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.65536.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png b/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png
deleted file mode 100644
index 3a99cbc..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspercpusec.vs.threads.8192.bytes.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.1.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.1.threads.png
deleted file mode 100644
index 37d406d..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.1.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.12.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.12.threads.png
deleted file mode 100644
index d45458a..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.12.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.16.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.16.threads.png
deleted file mode 100644
index e8a3c9f..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.16.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.2.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.2.threads.png
deleted file mode 100644
index 52d7aee..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.2.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.20.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.20.threads.png
deleted file mode 100644
index da0328a..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.20.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.3.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.3.threads.png
deleted file mode 100644
index 1093e81..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.3.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.4.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.4.threads.png
deleted file mode 100644
index d7c79ef..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.4.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.5.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.5.threads.png
deleted file mode 100644
index 779eec6..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.5.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.8.threads.png b/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.8.threads.png
deleted file mode 100644
index 76c125a..0000000
--- a/third_party/gperftools/docs/tcmalloc-opspersec.vs.size.8.threads.png
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/docs/tcmalloc.html b/third_party/gperftools/docs/tcmalloc.html
deleted file mode 100644
index 33b8cc5..0000000
--- a/third_party/gperftools/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/gperftools/docs/threadheap.dot b/third_party/gperftools/docs/threadheap.dot
deleted file mode 100644
index b2dba72..0000000
--- a/third_party/gperftools/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/gperftools/docs/threadheap.gif b/third_party/gperftools/docs/threadheap.gif
deleted file mode 100644
index c43d0a3..0000000
--- a/third_party/gperftools/docs/threadheap.gif
+++ /dev/null
Binary files differ
diff --git a/third_party/gperftools/gperftools.sln b/third_party/gperftools/gperftools.sln
deleted file mode 100644
index 1f1483c..0000000
--- a/third_party/gperftools/gperftools.sln
+++ /dev/null
@@ -1,307 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 12.00

-# Visual Studio 14

-VisualStudioVersion = 14.0.25420.1

-MinimumVisualStudioVersion = 10.0.40219.1

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtcmalloc_minimal", "vsprojects\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj", "{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcmalloc_minimal_unittest", "vsprojects\tcmalloc_minimal_unittest\tcmalloc_minimal_unittest.vcxproj", "{7CC73D97-C057-43A6-82EF-E6B567488D02}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcmalloc_minimal_large_unittest", "vsprojects\tcmalloc_minimal_large\tcmalloc_minimal_large_unittest.vcxproj", "{2D8B9599-C74C-4298-B723-6CF6077563E3}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addressmap_unittest", "vsprojects\addressmap_unittest\addressmap_unittest.vcxproj", "{32EECEB6-7D18-477E-BC7A-30CE98457A88}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "frag_unittest", "vsprojects\frag_unittest\frag_unittest.vcxproj", "{24754725-DE0D-4214-8979-324247AAD78E}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "low_level_alloc_unittest", "vsprojects\low_level_alloc_unittest\low_level_alloc_unittest.vcxproj", "{A765198D-5305-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "malloc_hook_test", "vsprojects\malloc_hook_test\malloc_hook_test.vcxproj", "{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "malloc_extension_test", "vsprojects\malloc_extension_test\malloc_extension_test.vcxproj", "{3765198D-5305-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "markidle_unittest", "vsprojects\markidle_unittest\markidle_unittest.vcxproj", "{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "current_allocated_bytes_test", "vsprojects\current_allocated_bytes_test\current_allocated_bytes_test.vcxproj", "{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "packed-cache_test", "vsprojects\packed-cache_test\packed-cache_test.vcxproj", "{605D3CED-B530-424E-B7D2-2A31F14FD570}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pagemap_unittest", "vsprojects\pagemap_unittest\pagemap_unittest.vcxproj", "{9765198D-5305-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "page_heap_test", "vsprojects\page_heap_test\page_heap_test.vcxproj", "{9765198D-5305-4AB0-9A21-A0CD8201EB2B}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "realloc_unittest", "vsprojects\realloc_unittest\realloc_unittest.vcxproj", "{4765198D-5305-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sampler_test", "vsprojects\sampler_test\sampler_test.vcxproj", "{B765198D-5305-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack_trace_table_test", "vsprojects\stack_trace_table_test\stack_trace_table_test.vcxproj", "{A4754725-DE0D-4214-8979-324247AAD78E}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_dealloc_unittest", "vsprojects\thread_dealloc_unittest\thread_dealloc_unittest.vcxproj", "{6CFFBD0F-09E3-4282-A711-0564451FDF74}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "preamble_patcher_test", "vsprojects\preamble_patcher_test\preamble_patcher_test.vcxproj", "{5765198D-5305-4AB0-9A21-A0CD8201EB2A}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addr2line-pdb", "vsprojects\addr2line-pdb\addr2line-pdb.vcxproj", "{81CA712E-90B8-4AE5-9E89-5B436578D6DA}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nm-pdb", "vsprojects\nm-pdb\nm-pdb.vcxproj", "{3A559C75-FD26-4300-B86B-165FD43EE1CE}"

-EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "system-alloc_unittest", "vsprojects\system-alloc_unittest\system-alloc_unittest.vcxproj", "{387F753A-0312-4A7B-A1D6-B2795E832E96}"

-EndProject

-Global

-	GlobalSection(SolutionConfigurationPlatforms) = preSolution

-		Debug|x64 = Debug|x64

-		Debug|x86 = Debug|x86

-		Release-Override|x64 = Release-Override|x64

-		Release-Override|x86 = Release-Override|x86

-		Release-Patch|x64 = Release-Patch|x64

-		Release-Patch|x86 = Release-Patch|x86

-	EndGlobalSection

-	GlobalSection(ProjectConfigurationPlatforms) = postSolution

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Debug|x64.ActiveCfg = Debug|x64

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Debug|x64.Build.0 = Debug|x64

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Debug|x86.ActiveCfg = Debug|Win32

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Debug|x86.Build.0 = Debug|Win32

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Override|x64.Build.0 = Release-Override|x64

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Debug|x64.ActiveCfg = Debug|x64

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Debug|x64.Build.0 = Debug|x64

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Debug|x86.ActiveCfg = Debug|Win32

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Debug|x86.Build.0 = Debug|Win32

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Override|x64.Build.0 = Release-Override|x64

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Debug|x64.ActiveCfg = Debug|x64

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Debug|x64.Build.0 = Debug|x64

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Debug|x86.ActiveCfg = Debug|Win32

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Debug|x86.Build.0 = Debug|Win32

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Override|x64.Build.0 = Release-Override|x64

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Debug|x64.ActiveCfg = Debug|x64

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Debug|x64.Build.0 = Debug|x64

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Debug|x86.ActiveCfg = Debug|Win32

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Debug|x86.Build.0 = Debug|Win32

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Override|x64.Build.0 = Release-Override|x64

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{24754725-DE0D-4214-8979-324247AAD78E}.Debug|x64.ActiveCfg = Debug|x64

-		{24754725-DE0D-4214-8979-324247AAD78E}.Debug|x64.Build.0 = Debug|x64

-		{24754725-DE0D-4214-8979-324247AAD78E}.Debug|x86.ActiveCfg = Debug|Win32

-		{24754725-DE0D-4214-8979-324247AAD78E}.Debug|x86.Build.0 = Debug|Win32

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x64.Build.0 = Release-Override|x64

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{24754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.Build.0 = Debug|x64

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.Build.0 = Debug|Win32

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.Build.0 = Release-Override|x64

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Debug|x64.Build.0 = Debug|x64

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Debug|x86.Build.0 = Debug|Win32

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.Build.0 = Release-Override|x64

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.Build.0 = Debug|x64

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.Build.0 = Debug|Win32

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.Build.0 = Release-Override|x64

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x64.ActiveCfg = Debug|x64

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x64.Build.0 = Debug|x64

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x86.ActiveCfg = Debug|Win32

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x86.Build.0 = Debug|Win32

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x64.Build.0 = Release-Override|x64

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x64.ActiveCfg = Debug|x64

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x64.Build.0 = Debug|x64

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x86.ActiveCfg = Debug|Win32

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug|x86.Build.0 = Debug|Win32

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x64.Build.0 = Release-Override|x64

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Debug|x64.ActiveCfg = Debug|x64

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Debug|x64.Build.0 = Debug|x64

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Debug|x86.ActiveCfg = Debug|Win32

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Debug|x86.Build.0 = Debug|Win32

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Override|x64.Build.0 = Release-Override|x64

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.Build.0 = Debug|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.Build.0 = Debug|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.Build.0 = Release-Override|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Debug|x64.ActiveCfg = Debug|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Debug|x64.Build.0 = Debug|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Debug|x86.ActiveCfg = Debug|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Debug|x86.Build.0 = Debug|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Override|x64.Build.0 = Release-Override|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.Build.0 = Debug|x64

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.Build.0 = Debug|Win32

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.Build.0 = Release-Override|x64

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.Build.0 = Debug|x64

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.Build.0 = Debug|Win32

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.Build.0 = Release-Override|x64

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Debug|x64.ActiveCfg = Debug|x64

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Debug|x64.Build.0 = Debug|x64

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Debug|x86.ActiveCfg = Debug|Win32

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Debug|x86.Build.0 = Debug|Win32

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x64.Build.0 = Release-Override|x64

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{A4754725-DE0D-4214-8979-324247AAD78E}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Debug|x64.ActiveCfg = Debug|x64

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Debug|x64.Build.0 = Debug|x64

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Debug|x86.ActiveCfg = Debug|Win32

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Debug|x86.Build.0 = Debug|Win32

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Override|x64.Build.0 = Release-Override|x64

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{5765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x64.ActiveCfg = Debug|x64

-		{5765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug|x86.ActiveCfg = Debug|Win32

-		{5765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{5765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{5765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{5765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Debug|x64.ActiveCfg = Debug|x64

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Debug|x64.Build.0 = Debug|x64

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Debug|x86.ActiveCfg = Debug|Win32

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Debug|x86.Build.0 = Debug|Win32

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Override|x64.Build.0 = Release-Override|x64

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug|x64.ActiveCfg = Debug|x64

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug|x64.Build.0 = Debug|x64

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug|x86.ActiveCfg = Debug|Win32

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug|x86.Build.0 = Debug|Win32

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Override|x64.Build.0 = Release-Override|x64

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Debug|x64.ActiveCfg = Debug|x64

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Debug|x64.Build.0 = Debug|x64

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Debug|x86.ActiveCfg = Debug|Win32

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Debug|x86.Build.0 = Debug|Win32

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Override|x64.ActiveCfg = Release-Override|x64

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Override|x64.Build.0 = Release-Override|x64

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Override|x86.ActiveCfg = Release-Override|Win32

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Override|x86.Build.0 = Release-Override|Win32

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Patch|x64.ActiveCfg = Release-Patch|x64

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Patch|x64.Build.0 = Release-Patch|x64

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Patch|x86.ActiveCfg = Release-Patch|Win32

-		{387F753A-0312-4A7B-A1D6-B2795E832E96}.Release-Patch|x86.Build.0 = Release-Patch|Win32

-	EndGlobalSection

-	GlobalSection(SolutionProperties) = preSolution

-		HideSolutionNode = FALSE

-	EndGlobalSection

-EndGlobal

diff --git a/third_party/gperftools/m4/ac_have_attribute.m4 b/third_party/gperftools/m4/ac_have_attribute.m4
deleted file mode 100644
index 19f4021..0000000
--- a/third_party/gperftools/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/gperftools/m4/acx_nanosleep.m4 b/third_party/gperftools/m4/acx_nanosleep.m4
deleted file mode 100644
index 1d44392..0000000
--- a/third_party/gperftools/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/gperftools/m4/acx_pthread.m4 b/third_party/gperftools/m4/acx_pthread.m4
deleted file mode 100644
index 89d42c7..0000000
--- a/third_party/gperftools/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/gperftools/m4/ax_cxx_compile_stdcxx.m4 b/third_party/gperftools/m4/ax_cxx_compile_stdcxx.m4
deleted file mode 100644
index 9e9eaed..0000000
--- a/third_party/gperftools/m4/ax_cxx_compile_stdcxx.m4
+++ /dev/null
@@ -1,948 +0,0 @@
-# ===========================================================================
-#  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
-#
-# DESCRIPTION
-#
-#   Check for baseline language coverage in the compiler for the specified
-#   version of the C++ standard.  If necessary, add switches to CXX and
-#   CXXCPP to enable support.  VERSION may be '11' (for the C++11 standard)
-#   or '14' (for the C++14 standard).
-#
-#   The second argument, if specified, indicates whether you insist on an
-#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
-#   -std=c++11).  If neither is specified, you get whatever works, with
-#   preference for an extended mode.
-#
-#   The third argument, if specified 'mandatory' or if left unspecified,
-#   indicates that baseline support for the specified C++ standard is
-#   required and that the macro should error out if no mode with that
-#   support is found.  If specified 'optional', then configuration proceeds
-#   regardless, after defining HAVE_CXX${VERSION} if and only if a
-#   supporting mode is found.
-#
-# LICENSE
-#
-#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
-#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
-#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
-#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
-#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
-#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
-#   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
-#
-#   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 10
-
-dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
-dnl  (serial version number 13).
-
-AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
-  m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
-        [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
-        [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
-        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
-  m4_if([$2], [], [],
-        [$2], [ext], [],
-        [$2], [noext], [],
-        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
-  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
-        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
-        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
-        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
-  AC_LANG_PUSH([C++])dnl
-  ac_success=no
-
-  m4_if([$2], [noext], [], [dnl
-  if test x$ac_success = xno; then
-    for alternative in ${ax_cxx_compile_alternatives}; do
-      switch="-std=gnu++${alternative}"
-      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
-      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
-                     $cachevar,
-        [ac_save_CXX="$CXX"
-         CXX="$CXX $switch"
-         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
-          [eval $cachevar=yes],
-          [eval $cachevar=no])
-         CXX="$ac_save_CXX"])
-      if eval test x\$$cachevar = xyes; then
-        CXX="$CXX $switch"
-        if test -n "$CXXCPP" ; then
-          CXXCPP="$CXXCPP $switch"
-        fi
-        ac_success=yes
-        break
-      fi
-    done
-  fi])
-
-  m4_if([$2], [ext], [], [dnl
-  if test x$ac_success = xno; then
-    dnl HP's aCC needs +std=c++11 according to:
-    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
-    dnl Cray's crayCC needs "-h std=c++11"
-    for alternative in ${ax_cxx_compile_alternatives}; do
-      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
-        cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
-        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
-                       $cachevar,
-          [ac_save_CXX="$CXX"
-           CXX="$CXX $switch"
-           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
-            [eval $cachevar=yes],
-            [eval $cachevar=no])
-           CXX="$ac_save_CXX"])
-        if eval test x\$$cachevar = xyes; then
-          CXX="$CXX $switch"
-          if test -n "$CXXCPP" ; then
-            CXXCPP="$CXXCPP $switch"
-          fi
-          ac_success=yes
-          break
-        fi
-      done
-      if test x$ac_success = xyes; then
-        break
-      fi
-    done
-  fi])
-  AC_LANG_POP([C++])
-  if test x$ax_cxx_compile_cxx$1_required = xtrue; then
-    if test x$ac_success = xno; then
-      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
-    fi
-  fi
-  if test x$ac_success = xno; then
-    HAVE_CXX$1=0
-    AC_MSG_NOTICE([No compiler with C++$1 support was found])
-  else
-    HAVE_CXX$1=1
-    AC_DEFINE(HAVE_CXX$1,1,
-              [define if the compiler supports basic C++$1 syntax])
-  fi
-  AC_SUBST(HAVE_CXX$1)
-])
-
-
-dnl  Test body for checking C++11 support
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
-  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-)
-
-
-dnl  Test body for checking C++14 support
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
-  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
-)
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
-  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
-  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
-)
-
-dnl  Tests for new features in C++11
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
-
-// If the compiler admits that it is not ready for C++11, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
-
-#error "This is not a C++ compiler"
-
-#elif __cplusplus < 201103L
-
-#error "This is not a C++11 compiler"
-
-#else
-
-namespace cxx11
-{
-
-  namespace test_static_assert
-  {
-
-    template <typename T>
-    struct check
-    {
-      static_assert(sizeof(int) <= sizeof(T), "not big enough");
-    };
-
-  }
-
-  namespace test_final_override
-  {
-
-    struct Base
-    {
-      virtual void f() {}
-    };
-
-    struct Derived : public Base
-    {
-      virtual void f() override {}
-    };
-
-  }
-
-  namespace test_double_right_angle_brackets
-  {
-
-    template < typename T >
-    struct check {};
-
-    typedef check<void> single_type;
-    typedef check<check<void>> double_type;
-    typedef check<check<check<void>>> triple_type;
-    typedef check<check<check<check<void>>>> quadruple_type;
-
-  }
-
-  namespace test_decltype
-  {
-
-    int
-    f()
-    {
-      int a = 1;
-      decltype(a) b = 2;
-      return a + b;
-    }
-
-  }
-
-  namespace test_type_deduction
-  {
-
-    template < typename T1, typename T2 >
-    struct is_same
-    {
-      static const bool value = false;
-    };
-
-    template < typename T >
-    struct is_same<T, T>
-    {
-      static const bool value = true;
-    };
-
-    template < typename T1, typename T2 >
-    auto
-    add(T1 a1, T2 a2) -> decltype(a1 + a2)
-    {
-      return a1 + a2;
-    }
-
-    int
-    test(const int c, volatile int v)
-    {
-      static_assert(is_same<int, decltype(0)>::value == true, "");
-      static_assert(is_same<int, decltype(c)>::value == false, "");
-      static_assert(is_same<int, decltype(v)>::value == false, "");
-      auto ac = c;
-      auto av = v;
-      auto sumi = ac + av + 'x';
-      auto sumf = ac + av + 1.0;
-      static_assert(is_same<int, decltype(ac)>::value == true, "");
-      static_assert(is_same<int, decltype(av)>::value == true, "");
-      static_assert(is_same<int, decltype(sumi)>::value == true, "");
-      static_assert(is_same<int, decltype(sumf)>::value == false, "");
-      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
-      return (sumf > 0.0) ? sumi : add(c, v);
-    }
-
-  }
-
-  namespace test_noexcept
-  {
-
-    int f() { return 0; }
-    int g() noexcept { return 0; }
-
-    static_assert(noexcept(f()) == false, "");
-    static_assert(noexcept(g()) == true, "");
-
-  }
-
-  namespace test_constexpr
-  {
-
-    template < typename CharT >
-    unsigned long constexpr
-    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
-    {
-      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
-    }
-
-    template < typename CharT >
-    unsigned long constexpr
-    strlen_c(const CharT *const s) noexcept
-    {
-      return strlen_c_r(s, 0UL);
-    }
-
-    static_assert(strlen_c("") == 0UL, "");
-    static_assert(strlen_c("1") == 1UL, "");
-    static_assert(strlen_c("example") == 7UL, "");
-    static_assert(strlen_c("another\0example") == 7UL, "");
-
-  }
-
-  namespace test_rvalue_references
-  {
-
-    template < int N >
-    struct answer
-    {
-      static constexpr int value = N;
-    };
-
-    answer<1> f(int&)       { return answer<1>(); }
-    answer<2> f(const int&) { return answer<2>(); }
-    answer<3> f(int&&)      { return answer<3>(); }
-
-    void
-    test()
-    {
-      int i = 0;
-      const int c = 0;
-      static_assert(decltype(f(i))::value == 1, "");
-      static_assert(decltype(f(c))::value == 2, "");
-      static_assert(decltype(f(0))::value == 3, "");
-    }
-
-  }
-
-  namespace test_uniform_initialization
-  {
-
-    struct test
-    {
-      static const int zero {};
-      static const int one {1};
-    };
-
-    static_assert(test::zero == 0, "");
-    static_assert(test::one == 1, "");
-
-  }
-
-  namespace test_lambdas
-  {
-
-    void
-    test1()
-    {
-      auto lambda1 = [](){};
-      auto lambda2 = lambda1;
-      lambda1();
-      lambda2();
-    }
-
-    int
-    test2()
-    {
-      auto a = [](int i, int j){ return i + j; }(1, 2);
-      auto b = []() -> int { return '0'; }();
-      auto c = [=](){ return a + b; }();
-      auto d = [&](){ return c; }();
-      auto e = [a, &b](int x) mutable {
-        const auto identity = [](int y){ return y; };
-        for (auto i = 0; i < a; ++i)
-          a += b--;
-        return x + identity(a + b);
-      }(0);
-      return a + b + c + d + e;
-    }
-
-    int
-    test3()
-    {
-      const auto nullary = [](){ return 0; };
-      const auto unary = [](int x){ return x; };
-      using nullary_t = decltype(nullary);
-      using unary_t = decltype(unary);
-      const auto higher1st = [](nullary_t f){ return f(); };
-      const auto higher2nd = [unary](nullary_t f1){
-        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
-      };
-      return higher1st(nullary) + higher2nd(nullary)(unary);
-    }
-
-  }
-
-  namespace test_variadic_templates
-  {
-
-    template <int...>
-    struct sum;
-
-    template <int N0, int... N1toN>
-    struct sum<N0, N1toN...>
-    {
-      static constexpr auto value = N0 + sum<N1toN...>::value;
-    };
-
-    template <>
-    struct sum<>
-    {
-      static constexpr auto value = 0;
-    };
-
-    static_assert(sum<>::value == 0, "");
-    static_assert(sum<1>::value == 1, "");
-    static_assert(sum<23>::value == 23, "");
-    static_assert(sum<1, 2>::value == 3, "");
-    static_assert(sum<5, 5, 11>::value == 21, "");
-    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
-
-  }
-
-  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
-  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
-  // because of this.
-  namespace test_template_alias_sfinae
-  {
-
-    struct foo {};
-
-    template<typename T>
-    using member = typename T::member_type;
-
-    template<typename T>
-    void func(...) {}
-
-    template<typename T>
-    void func(member<T>*) {}
-
-    void test();
-
-    void test() { func<foo>(0); }
-
-  }
-
-}  // namespace cxx11
-
-#endif  // __cplusplus >= 201103L
-
-]])
-
-
-dnl  Tests for new features in C++14
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
-
-// If the compiler admits that it is not ready for C++14, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
-
-#error "This is not a C++ compiler"
-
-#elif __cplusplus < 201402L
-
-#error "This is not a C++14 compiler"
-
-#else
-
-namespace cxx14
-{
-
-  namespace test_polymorphic_lambdas
-  {
-
-    int
-    test()
-    {
-      const auto lambda = [](auto&&... args){
-        const auto istiny = [](auto x){
-          return (sizeof(x) == 1UL) ? 1 : 0;
-        };
-        const int aretiny[] = { istiny(args)... };
-        return aretiny[0];
-      };
-      return lambda(1, 1L, 1.0f, '1');
-    }
-
-  }
-
-  namespace test_binary_literals
-  {
-
-    constexpr auto ivii = 0b0000000000101010;
-    static_assert(ivii == 42, "wrong value");
-
-  }
-
-  namespace test_generalized_constexpr
-  {
-
-    template < typename CharT >
-    constexpr unsigned long
-    strlen_c(const CharT *const s) noexcept
-    {
-      auto length = 0UL;
-      for (auto p = s; *p; ++p)
-        ++length;
-      return length;
-    }
-
-    static_assert(strlen_c("") == 0UL, "");
-    static_assert(strlen_c("x") == 1UL, "");
-    static_assert(strlen_c("test") == 4UL, "");
-    static_assert(strlen_c("another\0test") == 7UL, "");
-
-  }
-
-  namespace test_lambda_init_capture
-  {
-
-    int
-    test()
-    {
-      auto x = 0;
-      const auto lambda1 = [a = x](int b){ return a + b; };
-      const auto lambda2 = [a = lambda1(x)](){ return a; };
-      return lambda2();
-    }
-
-  }
-
-  namespace test_digit_separators
-  {
-
-    constexpr auto ten_million = 100'000'000;
-    static_assert(ten_million == 100000000, "");
-
-  }
-
-  namespace test_return_type_deduction
-  {
-
-    auto f(int& x) { return x; }
-    decltype(auto) g(int& x) { return x; }
-
-    template < typename T1, typename T2 >
-    struct is_same
-    {
-      static constexpr auto value = false;
-    };
-
-    template < typename T >
-    struct is_same<T, T>
-    {
-      static constexpr auto value = true;
-    };
-
-    int
-    test()
-    {
-      auto x = 0;
-      static_assert(is_same<int, decltype(f(x))>::value, "");
-      static_assert(is_same<int&, decltype(g(x))>::value, "");
-      return x;
-    }
-
-  }
-
-}  // namespace cxx14
-
-#endif  // __cplusplus >= 201402L
-
-]])
-
-
-dnl  Tests for new features in C++17
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
-
-// If the compiler admits that it is not ready for C++17, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
-
-#error "This is not a C++ compiler"
-
-#elif __cplusplus < 201703L
-
-#error "This is not a C++17 compiler"
-
-#else
-
-#include <initializer_list>
-#include <utility>
-#include <type_traits>
-
-namespace cxx17
-{
-
-  namespace test_constexpr_lambdas
-  {
-
-    constexpr int foo = [](){return 42;}();
-
-  }
-
-  namespace test::nested_namespace::definitions
-  {
-
-  }
-
-  namespace test_fold_expression
-  {
-
-    template<typename... Args>
-    int multiply(Args... args)
-    {
-      return (args * ... * 1);
-    }
-
-    template<typename... Args>
-    bool all(Args... args)
-    {
-      return (args && ...);
-    }
-
-  }
-
-  namespace test_extended_static_assert
-  {
-
-    static_assert (true);
-
-  }
-
-  namespace test_auto_brace_init_list
-  {
-
-    auto foo = {5};
-    auto bar {5};
-
-    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
-    static_assert(std::is_same<int, decltype(bar)>::value);
-  }
-
-  namespace test_typename_in_template_template_parameter
-  {
-
-    template<template<typename> typename X> struct D;
-
-  }
-
-  namespace test_fallthrough_nodiscard_maybe_unused_attributes
-  {
-
-    int f1()
-    {
-      return 42;
-    }
-
-    [[nodiscard]] int f2()
-    {
-      [[maybe_unused]] auto unused = f1();
-
-      switch (f1())
-      {
-      case 17:
-        f1();
-        [[fallthrough]];
-      case 42:
-        f1();
-      }
-      return f1();
-    }
-
-  }
-
-  namespace test_extended_aggregate_initialization
-  {
-
-    struct base1
-    {
-      int b1, b2 = 42;
-    };
-
-    struct base2
-    {
-      base2() {
-        b3 = 42;
-      }
-      int b3;
-    };
-
-    struct derived : base1, base2
-    {
-        int d;
-    };
-
-    derived d1 {{1, 2}, {}, 4};  // full initialization
-    derived d2 {{}, {}, 4};      // value-initialized bases
-
-  }
-
-  namespace test_general_range_based_for_loop
-  {
-
-    struct iter
-    {
-      int i;
-
-      int& operator* ()
-      {
-        return i;
-      }
-
-      const int& operator* () const
-      {
-        return i;
-      }
-
-      iter& operator++()
-      {
-        ++i;
-        return *this;
-      }
-    };
-
-    struct sentinel
-    {
-      int i;
-    };
-
-    bool operator== (const iter& i, const sentinel& s)
-    {
-      return i.i == s.i;
-    }
-
-    bool operator!= (const iter& i, const sentinel& s)
-    {
-      return !(i == s);
-    }
-
-    struct range
-    {
-      iter begin() const
-      {
-        return {0};
-      }
-
-      sentinel end() const
-      {
-        return {5};
-      }
-    };
-
-    void f()
-    {
-      range r {};
-
-      for (auto i : r)
-      {
-        [[maybe_unused]] auto v = i;
-      }
-    }
-
-  }
-
-  namespace test_lambda_capture_asterisk_this_by_value
-  {
-
-    struct t
-    {
-      int i;
-      int foo()
-      {
-        return [*this]()
-        {
-          return i;
-        }();
-      }
-    };
-
-  }
-
-  namespace test_enum_class_construction
-  {
-
-    enum class byte : unsigned char
-    {};
-
-    byte foo {42};
-
-  }
-
-  namespace test_constexpr_if
-  {
-
-    template <bool cond>
-    int f ()
-    {
-      if constexpr(cond)
-      {
-        return 13;
-      }
-      else
-      {
-        return 42;
-      }
-    }
-
-  }
-
-  namespace test_selection_statement_with_initializer
-  {
-
-    int f()
-    {
-      return 13;
-    }
-
-    int f2()
-    {
-      if (auto i = f(); i > 0)
-      {
-        return 3;
-      }
-
-      switch (auto i = f(); i + 4)
-      {
-      case 17:
-        return 2;
-
-      default:
-        return 1;
-      }
-    }
-
-  }
-
-  namespace test_template_argument_deduction_for_class_templates
-  {
-
-    template <typename T1, typename T2>
-    struct pair
-    {
-      pair (T1 p1, T2 p2)
-        : m1 {p1},
-          m2 {p2}
-      {}
-
-      T1 m1;
-      T2 m2;
-    };
-
-    void f()
-    {
-      [[maybe_unused]] auto p = pair{13, 42u};
-    }
-
-  }
-
-  namespace test_non_type_auto_template_parameters
-  {
-
-    template <auto n>
-    struct B
-    {};
-
-    B<5> b1;
-    B<'a'> b2;
-
-  }
-
-  namespace test_structured_bindings
-  {
-
-    int arr[2] = { 1, 2 };
-    std::pair<int, int> pr = { 1, 2 };
-
-    auto f1() -> int(&)[2]
-    {
-      return arr;
-    }
-
-    auto f2() -> std::pair<int, int>&
-    {
-      return pr;
-    }
-
-    struct S
-    {
-      int x1 : 2;
-      volatile double y1;
-    };
-
-    S f3()
-    {
-      return {};
-    }
-
-    auto [ x1, y1 ] = f1();
-    auto& [ xr1, yr1 ] = f1();
-    auto [ x2, y2 ] = f2();
-    auto& [ xr2, yr2 ] = f2();
-    const auto [ x3, y3 ] = f3();
-
-  }
-
-  namespace test_exception_spec_type_system
-  {
-
-    struct Good {};
-    struct Bad {};
-
-    void g1() noexcept;
-    void g2();
-
-    template<typename T>
-    Bad
-    f(T*, T*);
-
-    template<typename T1, typename T2>
-    Good
-    f(T1*, T2*);
-
-    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
-
-  }
-
-  namespace test_inline_variables
-  {
-
-    template<class T> void f(T)
-    {}
-
-    template<class T> inline T g(T)
-    {
-      return T{};
-    }
-
-    template<> inline void f<>(int)
-    {}
-
-    template<> int g<>(int)
-    {
-      return 5;
-    }
-
-  }
-
-}  // namespace cxx17
-
-#endif  // __cplusplus < 201703L
-
-]])
diff --git a/third_party/gperftools/m4/ax_generate_changelog.m4 b/third_party/gperftools/m4/ax_generate_changelog.m4
deleted file mode 100644
index d9d5cd1..0000000
--- a/third_party/gperftools/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/gperftools/m4/install_prefix.m4 b/third_party/gperftools/m4/install_prefix.m4
deleted file mode 100644
index ef33f42..0000000
--- a/third_party/gperftools/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/gperftools/m4/pc_from_ucontext.m4 b/third_party/gperftools/m4/pc_from_ucontext.m4
deleted file mode 100644
index 159b01d..0000000
--- a/third_party/gperftools/m4/pc_from_ucontext.m4
+++ /dev/null
@@ -1,112 +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_CHECK_HEADERS(asm/ptrace.h)           # get ptrace macros, e.g. PT_NIP
-   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.__gregs[[REG_PC]]"  # Linux (riscv64)
-   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.cr0_hi"           # Linux (e2k)
-   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_srr0"          # FreeBSD (powerpc, powerpc64)
-   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_fields="$pc_fields uc_mcontext->__ss.__pc"       # OS X (arm64)
-   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_asm_ptrace_h" = xyes -a "x$ac_cv_header_sys_ucontext_h" = xyes; then
-         AC_TRY_COMPILE([#define _GNU_SOURCE 1
-                         #include <asm/ptrace.h>
-                         #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_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/gperftools/m4/program_invocation_name.m4 b/third_party/gperftools/m4/program_invocation_name.m4
deleted file mode 100644
index 6161f66..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb.sh b/third_party/gperftools/packages/deb.sh
deleted file mode 100755
index 31b423c..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/README b/third_party/gperftools/packages/deb/README
deleted file mode 100644
index 57becfd..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/changelog b/third_party/gperftools/packages/deb/changelog
deleted file mode 100644
index d67df61..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/compat b/third_party/gperftools/packages/deb/compat
deleted file mode 100644
index b8626c4..0000000
--- a/third_party/gperftools/packages/deb/compat
+++ /dev/null
@@ -1 +0,0 @@
-4
diff --git a/third_party/gperftools/packages/deb/control b/third_party/gperftools/packages/deb/control
deleted file mode 100644
index 37c34a5..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/copyright b/third_party/gperftools/packages/deb/copyright
deleted file mode 100644
index db7c78e..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/docs b/third_party/gperftools/packages/deb/docs
deleted file mode 100644
index fc4806f..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/libgperftools-dev.dirs b/third_party/gperftools/packages/deb/libgperftools-dev.dirs
deleted file mode 100644
index 8f88347..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/libgperftools-dev.install b/third_party/gperftools/packages/deb/libgperftools-dev.install
deleted file mode 100644
index e863529..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/libgperftools0.dirs b/third_party/gperftools/packages/deb/libgperftools0.dirs
deleted file mode 100644
index 14f5b95..0000000
--- a/third_party/gperftools/packages/deb/libgperftools0.dirs
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib
-usr/bin
diff --git a/third_party/gperftools/packages/deb/libgperftools0.install b/third_party/gperftools/packages/deb/libgperftools0.install
deleted file mode 100644
index 047eed5..0000000
--- a/third_party/gperftools/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/gperftools/packages/deb/libgperftools0.manpages b/third_party/gperftools/packages/deb/libgperftools0.manpages
deleted file mode 100644
index 8ecbfc4..0000000
--- a/third_party/gperftools/packages/deb/libgperftools0.manpages
+++ /dev/null
@@ -1 +0,0 @@
-docs/pprof.1
diff --git a/third_party/gperftools/packages/deb/rules b/third_party/gperftools/packages/deb/rules
deleted file mode 100755
index f520bef..0000000
--- a/third_party/gperftools/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/gperftools/packages/rpm.sh b/third_party/gperftools/packages/rpm.sh
deleted file mode 100755
index 448a032..0000000
--- a/third_party/gperftools/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/gperftools/packages/rpm/rpm.spec b/third_party/gperftools/packages/rpm/rpm.spec
deleted file mode 100644
index 0690e4f..0000000
--- a/third_party/gperftools/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/gperftools/src/addressmap-inl.h b/third_party/gperftools/src/addressmap-inl.h
deleted file mode 100644
index 524aff6..0000000
--- a/third_party/gperftools/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/gperftools/src/base/arm_instruction_set_select.h b/third_party/gperftools/src/base/arm_instruction_set_select.h
deleted file mode 100644
index 77ff670..0000000
--- a/third_party/gperftools/src/base/arm_instruction_set_select.h
+++ /dev/null
@@ -1,85 +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: 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/gperftools/src/base/atomicops-internals-arm-generic.h b/third_party/gperftools/src/base/atomicops-internals-arm-generic.h
deleted file mode 100644
index cfa6143..0000000
--- a/third_party/gperftools/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 <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 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);
-  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/gperftools/src/base/atomicops-internals-arm-v6plus.h b/third_party/gperftools/src/base/atomicops-internals-arm-v6plus.h
deleted file mode 100644
index af2920a..0000000
--- a/third_party/gperftools/src/base/atomicops-internals-arm-v6plus.h
+++ /dev/null
@@ -1,310 +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 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);
-  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/gperftools/src/base/atomicops-internals-gcc.h b/third_party/gperftools/src/base/atomicops-internals-gcc.h
deleted file mode 100644
index 4f81ce3..0000000
--- a/third_party/gperftools/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/gperftools/src/base/atomicops-internals-linuxppc.h b/third_party/gperftools/src/base/atomicops-internals-linuxppc.h
deleted file mode 100644
index 5c4d03c..0000000
--- a/third_party/gperftools/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/gperftools/src/base/atomicops-internals-macosx.h b/third_party/gperftools/src/base/atomicops-internals-macosx.h
deleted file mode 100644
index 9a0c00a..0000000
--- a/third_party/gperftools/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/gperftools/src/base/atomicops-internals-mips.h b/third_party/gperftools/src/base/atomicops-internals-mips.h
deleted file mode 100644
index 58e0f14..0000000
--- a/third_party/gperftools/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/gperftools/src/base/atomicops-internals-windows.h b/third_party/gperftools/src/base/atomicops-internals-windows.h
deleted file mode 100644
index f7c2907..0000000
--- a/third_party/gperftools/src/base/atomicops-internals-windows.h
+++ /dev/null
@@ -1,428 +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 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);
-  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/gperftools/src/base/atomicops-internals-x86.cc b/third_party/gperftools/src/base/atomicops-internals-x86.cc
deleted file mode 100644
index 20073c2..0000000
--- a/third_party/gperftools/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/gperftools/src/base/atomicops-internals-x86.h b/third_party/gperftools/src/base/atomicops-internals-x86.h
deleted file mode 100644
index 94c7aac..0000000
--- a/third_party/gperftools/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/gperftools/src/base/atomicops.h b/third_party/gperftools/src/base/atomicops.h
deleted file mode 100644
index f1daf3b..0000000
--- a/third_party/gperftools/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/gperftools/src/base/basictypes.h b/third_party/gperftools/src/base/basictypes.h
deleted file mode 100644
index 4f2246e..0000000
--- a/third_party/gperftools/src/base/basictypes.h
+++ /dev/null
@@ -1,440 +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 =  ( ((( uint64) 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
-
-#if defined(__GNUC__)
-#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)))
-# elif (defined(__riscv) && __riscv_xlen == 64)
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-# elif (defined(__e2k__))
-#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
-# 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/gperftools/src/base/commandlineflags.h b/third_party/gperftools/src/base/commandlineflags.h
deleted file mode 100644
index 038a94a..0000000
--- a/third_party/gperftools/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/gperftools/src/base/dynamic_annotations.c b/third_party/gperftools/src/base/dynamic_annotations.c
deleted file mode 100644
index 9b966a7..0000000
--- a/third_party/gperftools/src/base/dynamic_annotations.c
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- Mode: c; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* 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
-
-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;
-  if (local_running_on_valgrind == -1)
-    running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();
-  return local_running_on_valgrind;
-}
diff --git a/third_party/gperftools/src/base/dynamic_annotations.h b/third_party/gperftools/src/base/dynamic_annotations.h
deleted file mode 100644
index af944527..0000000
--- a/third_party/gperftools/src/base/dynamic_annotations.h
+++ /dev/null
@@ -1,86 +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: 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_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* BASE_DYNAMIC_ANNOTATIONS_H_ */
diff --git a/third_party/gperftools/src/base/elf_mem_image.cc b/third_party/gperftools/src/base/elf_mem_image.cc
deleted file mode 100644
index d2ca1a5..0000000
--- a/third_party/gperftools/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/gperftools/src/base/elf_mem_image.h b/third_party/gperftools/src/base/elf_mem_image.h
deleted file mode 100644
index 5fb00ff..0000000
--- a/third_party/gperftools/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/gperftools/src/base/elfcore.h b/third_party/gperftools/src/base/elfcore.h
deleted file mode 100644
index 11c09b4..0000000
--- a/third_party/gperftools/src/base/elfcore.h
+++ /dev/null
@@ -1,135 +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 "config.h"
-
-#include <stdarg.h>
-#include <stdint.h>
-#include <sys/types.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
-
-#endif  // __linux and various arches
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _ELFCORE_H */
diff --git a/third_party/gperftools/src/base/googleinit.h b/third_party/gperftools/src/base/googleinit.h
deleted file mode 100644
index a290427..0000000
--- a/third_party/gperftools/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/gperftools/src/base/linux_syscall_support.h b/third_party/gperftools/src/base/linux_syscall_support.h
deleted file mode 100644
index d6899b8..0000000
--- a/third_party/gperftools/src/base/linux_syscall_support.h
+++ /dev/null
@@ -1,3017 +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, s390x, and riscv64 on Linux.
- * Porting to other related platforms should not be difficult.
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
-     defined(__mips__) || defined(__mips64) || defined(__mips64el__) || defined(__PPC__) || \
-     defined(__aarch64__) || defined(__s390__) || defined(__riscv)) \
-  && (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 definitions                                              */
-#elif defined(__aarch64__)
-#ifndef __NR_fstatat
-#define __NR_fstatat             79
-#endif
-/* End of aarch64 definitions                                              */
-#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                                             */
-#elif defined(__riscv)
-# ifndef __NR_gettid
-# define __NR_gettid             178
-# endif
-# ifndef __NR_futex
-# define __NR_futex              422
-# endif
-# ifndef __NR_getdents64
-# define __NR_getdents64         61
-# endif
-# ifndef __NR_openat
-# define __NR_openat             56
-# endif
-# ifndef __NR_fstatat
-# define __NR_fstatat            79
-# endif
-#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__) || defined(__riscv))
-  /* 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                                               \
-                           : "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))         \
-                             : "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))         \
-                             : "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)
-                           : "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");                            \
-        __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                  \
-                                : "x8", "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)
-                             : "x8", "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);
-    }
-  #elif defined(__riscv)
-    #undef LSS_REG
-    #define LSS_REG(r,a) register long __a##r __asm__("a"#r) =       \
-                                 (long)(a)
-
-    #undef  LSS_BODY
-    #define LSS_BODY(type, name, args...)                                     \
-          register long __a7 __asm__("a7") = __NR_##name;                     \
-          long __res;                                                         \
-          __asm__ __volatile__ (                                              \
-                                "scall\n\t"                                   \
-                                : "+r" (__a0)                                 \
-                                : "r" (__a7), ##args                          \
-                                : "memory");                                  \
-          __res = __a0;                                                       \
-          LSS_RETURN(type, __res)
-    #undef _syscall0
-    #define _syscall0(type,name)                                              \
-      type LSS_NAME(name)() {                                                 \
-          register long __a7 __asm__("a7") = __NR_##name;                     \
-          register long __a0 __asm__("a0");                                   \
-          long __res;                                                         \
-          __asm__ __volatile__ (                                              \
-                                "scall\n\t"                                   \
-                                : "=r" (__a0)                                 \
-                                : "r" (__a7)                                  \
-                                : "memory");                                  \
-          __res = __a0;                                                       \
-          LSS_RETURN(type, __res);                                            \
-      }
-    #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);                                                 \
-      }
-    #undef _syscall2
-    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
-      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \
-        LSS_REG(0, arg1);                                                     \
-        LSS_REG(1, arg2);                                                     \
-        LSS_BODY(type, name, "r"(__a1));                                      \
-      }
-    #undef _syscall3
-    #define _syscall3(type, name, 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, name, "r"(__a1), "r"(__a2));                           \
-      }
-    #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"(__a1), "r"(__a2), "r"(__a3));                \
-      }
-    #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"(__a1), "r"(__a2), "r"(__a3), "r"(__a4));     \
-      }
-    #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(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, name, "r"(__a1), "r"(__a2), "r"(__a3), "r"(__a4),      \
-                             "r"(__a5));                                      \
-      }
-  #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/gperftools/src/base/linuxthreads.cc b/third_party/gperftools/src/base/linuxthreads.cc
deleted file mode 100644
index 1504730..0000000
--- a/third_party/gperftools/src/base/linuxthreads.cc
+++ /dev/null
@@ -1,709 +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) {
-        sig_num_threads = sig_num_threads - 1;
-        /* 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.
-     */
-    sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0);
-    if (sig_proc < 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/gperftools/src/base/linuxthreads.h b/third_party/gperftools/src/base/linuxthreads.h
deleted file mode 100644
index a087628..0000000
--- a/third_party/gperftools/src/base/linuxthreads.h
+++ /dev/null
@@ -1,55 +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 _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/gperftools/src/base/logging.cc b/third_party/gperftools/src/base/logging.cc
deleted file mode 100644
index 52d9bd3..0000000
--- a/third_party/gperftools/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/gperftools/src/base/logging.h b/third_party/gperftools/src/base/logging.h
deleted file mode 100644
index 94b9138..0000000
--- a/third_party/gperftools/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/gperftools/src/base/low_level_alloc.cc b/third_party/gperftools/src/base/low_level_alloc.cc
deleted file mode 100644
index db91155..0000000
--- a/third_party/gperftools/src/base/low_level_alloc.cc
+++ /dev/null
@@ -1,580 +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
-  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() { 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_;
-    DISALLOW_COPY_AND_ASSIGN(ArenaLock);
-  };
-} // 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;
-  }
-  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/gperftools/src/base/low_level_alloc.h b/third_party/gperftools/src/base/low_level_alloc.h
deleted file mode 100644
index 406bfff..0000000
--- a/third_party/gperftools/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/gperftools/src/base/simple_mutex.h b/third_party/gperftools/src/base/simple_mutex.h
deleted file mode 100644
index 5913b9e..0000000
--- a/third_party/gperftools/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/gperftools/src/base/spinlock.cc b/third_party/gperftools/src/base/spinlock.cc
deleted file mode 100644
index d2a9e1c..0000000
--- a/third_party/gperftools/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/gperftools/src/base/spinlock.h b/third_party/gperftools/src/base/spinlock.h
deleted file mode 100644
index 118f541..0000000
--- a/third_party/gperftools/src/base/spinlock.h
+++ /dev/null
@@ -1,132 +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.
-  inline void Lock() EXCLUSIVE_LOCK_FUNCTION() {
-    if (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                             kSpinLockHeld) != kSpinLockFree) {
-      SlowLock();
-    }
-  }
-
-  // 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);
-    return res;
-  }
-
-  // Release this SpinLock, which must be held by the calling thread.
-  inline void Unlock() UNLOCK_FUNCTION() {
-    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();
-  }
-  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/gperftools/src/base/spinlock_internal.cc b/third_party/gperftools/src/base/spinlock_internal.cc
deleted file mode 100644
index d962971..0000000
--- a/third_party/gperftools/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/gperftools/src/base/spinlock_internal.h b/third_party/gperftools/src/base/spinlock_internal.h
deleted file mode 100644
index aa47e67..0000000
--- a/third_party/gperftools/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/gperftools/src/base/spinlock_linux-inl.h b/third_party/gperftools/src/base/spinlock_linux-inl.h
deleted file mode 100644
index ad48aae..0000000
--- a/third_party/gperftools/src/base/spinlock_linux-inl.h
+++ /dev/null
@@ -1,103 +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 <limits.h>
-#include <sched.h>
-#include <sys/syscall.h>
-#include <time.h>
-#include <unistd.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.
-
-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) &&
-                  syscall(__NR_futex, &x, FUTEX_WAKE, 1, NULL, NULL, 0) >= 0);
-    if (have_futex && syscall(__NR_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
-      syscall(__NR_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) {
-    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/gperftools/src/base/spinlock_posix-inl.h b/third_party/gperftools/src/base/spinlock_posix-inl.h
deleted file mode 100644
index f4d217b..0000000
--- a/third_party/gperftools/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/gperftools/src/base/spinlock_win32-inl.h b/third_party/gperftools/src/base/spinlock_win32-inl.h
deleted file mode 100644
index 05caa54..0000000
--- a/third_party/gperftools/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/gperftools/src/base/stl_allocator.h b/third_party/gperftools/src/base/stl_allocator.h
deleted file mode 100644
index 94debe8..0000000
--- a/third_party/gperftools/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/gperftools/src/base/sysinfo.cc b/third_party/gperftools/src/base/sysinfo.cc
deleted file mode 100644
index 9c2a615..0000000
--- a/third_party/gperftools/src/base/sysinfo.cc
+++ /dev/null
@@ -1,878 +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 = (const 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;
-}
-
-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/gperftools/src/base/sysinfo.h b/third_party/gperftools/src/base/sysinfo.h
deleted file mode 100644
index 77d956e..0000000
--- a/third_party/gperftools/src/base/sysinfo.h
+++ /dev/null
@@ -1,230 +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();
-
-//  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/gperftools/src/base/thread_annotations.h b/third_party/gperftools/src/base/thread_annotations.h
deleted file mode 100644
index b68e756..0000000
--- a/third_party/gperftools/src/base/thread_annotations.h
+++ /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.
-
-// ---
-// 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/gperftools/src/base/thread_lister.c b/third_party/gperftools/src/base/thread_lister.c
deleted file mode 100644
index dcf9194..0000000
--- a/third_party/gperftools/src/base/thread_lister.c
+++ /dev/null
@@ -1,87 +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 "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
-#ifdef HAVE_UNISTD_H
-# include <unistd.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/gperftools/src/base/thread_lister.h b/third_party/gperftools/src/base/thread_lister.h
deleted file mode 100644
index 6e70b89..0000000
--- a/third_party/gperftools/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/gperftools/src/base/vdso_support.cc b/third_party/gperftools/src/base/vdso_support.cc
deleted file mode 100644
index e4805e9..0000000
--- a/third_party/gperftools/src/base/vdso_support.cc
+++ /dev/null
@@ -1,143 +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 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/atomicops.h"  // for MemoryBarrier
-#include "base/logging.h"
-#include "base/dynamic_annotations.h"
-#include "base/basictypes.h"  // for COMPILE_ASSERT
-
-using base::subtle::MemoryBarrier;
-
-#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/gperftools/src/base/vdso_support.h b/third_party/gperftools/src/base/vdso_support.h
deleted file mode 100644
index 073386c..0000000
--- a/third_party/gperftools/src/base/vdso_support.h
+++ /dev/null
@@ -1,137 +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 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/gperftools/src/central_freelist.cc b/third_party/gperftools/src/central_freelist.cc
deleted file mode 100644
index d064c2f..0000000
--- a/third_party/gperftools/src/central_freelist.cc
+++ /dev/null
@@ -1,384 +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);
-  }
-
-  // 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) {
-    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);
-  }
-
-  *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/gperftools/src/central_freelist.h b/third_party/gperftools/src/central_freelist.h
deleted file mode 100644
index 0f66e0c..0000000
--- a/third_party/gperftools/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/gperftools/src/common.cc b/third_party/gperftools/src/common.cc
deleted file mode 100644
index 5e9e11e..0000000
--- a/third_party/gperftools/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/gperftools/src/common.h b/third_party/gperftools/src/common.h
deleted file mode 100644
index caa3e4a..0000000
--- a/third_party/gperftools/src/common.h
+++ /dev/null
@@ -1,309 +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_PAGE_SIZE_SHIFT)
-static const size_t kPageShift  = TCMALLOC_PAGE_SIZE_SHIFT;
-#else
-static const size_t kPageShift  = 13;
-#endif
-
-static const size_t kClassSizesMax = 128;
-
-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/gperftools/src/config_for_unittests.h b/third_party/gperftools/src/config_for_unittests.h
deleted file mode 100644
index 12bf614..0000000
--- a/third_party/gperftools/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/gperftools/src/debugallocation.cc b/third_party/gperftools/src/debugallocation.cc
deleted file mode 100644
index b0f7509..0000000
--- a/third_party/gperftools/src/debugallocation.cc
+++ /dev/null
@@ -1,1588 +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.");
-DEFINE_bool(malloc_page_fence_readable,
-            EnvToBool("TCMALLOC_PAGE_FENCE_READABLE", false),
-            "Permits reads to the page fence.");
-#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: %zu", size);
-      return NULL;
-    }
-    MallocBlock* b = NULL;
-    const bool use_malloc_page_fence = FLAGS_malloc_page_fence;
-    const bool malloc_page_fence_readable = FLAGS_malloc_page_fence_readable;
-#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|(malloc_page_fence_readable ? PROT_READ : 0))) {
-        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%zu\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;
-  }
-  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 %zu 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 %zu 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/gperftools/src/emergency_malloc.cc b/third_party/gperftools/src/emergency_malloc.cc
deleted file mode 100644
index 6c0946a..0000000
--- a/third_party/gperftools/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 %zu 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/gperftools/src/emergency_malloc.h b/third_party/gperftools/src/emergency_malloc.h
deleted file mode 100644
index 8a82cfc..0000000
--- a/third_party/gperftools/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/gperftools/src/emergency_malloc_for_stacktrace.cc b/third_party/gperftools/src/emergency_malloc_for_stacktrace.cc
deleted file mode 100644
index f1dc35e..0000000
--- a/third_party/gperftools/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/gperftools/src/fake_stacktrace_scope.cc b/third_party/gperftools/src/fake_stacktrace_scope.cc
deleted file mode 100644
index ee35a04..0000000
--- a/third_party/gperftools/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/gperftools/src/getenv_safe.h b/third_party/gperftools/src/getenv_safe.h
deleted file mode 100644
index 59094b1..0000000
--- a/third_party/gperftools/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/gperftools/src/getpc.h b/third_party/gperftools/src/getpc.h
deleted file mode 100644
index 9605363..0000000
--- a/third_party/gperftools/src/getpc.h
+++ /dev/null
@@ -1,195 +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
-#ifdef HAVE_ASM_PTRACE_H
-#include <asm/ptrace.h>
-#endif
-#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/gperftools/src/google/heap-checker.h b/third_party/gperftools/src/google/heap-checker.h
deleted file mode 100644
index 6b9ffe5..0000000
--- a/third_party/gperftools/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/gperftools/src/google/heap-profiler.h b/third_party/gperftools/src/google/heap-profiler.h
deleted file mode 100644
index 0c46f63..0000000
--- a/third_party/gperftools/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/gperftools/src/google/malloc_extension.h b/third_party/gperftools/src/google/malloc_extension.h
deleted file mode 100644
index ad34dec..0000000
--- a/third_party/gperftools/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/gperftools/src/google/malloc_extension_c.h b/third_party/gperftools/src/google/malloc_extension_c.h
deleted file mode 100644
index 9141805..0000000
--- a/third_party/gperftools/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/gperftools/src/google/malloc_hook.h b/third_party/gperftools/src/google/malloc_hook.h
deleted file mode 100644
index 416283b..0000000
--- a/third_party/gperftools/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/gperftools/src/google/malloc_hook_c.h b/third_party/gperftools/src/google/malloc_hook_c.h
deleted file mode 100644
index 1fa1a4a..0000000
--- a/third_party/gperftools/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/gperftools/src/google/profiler.h b/third_party/gperftools/src/google/profiler.h
deleted file mode 100644
index 2f99679..0000000
--- a/third_party/gperftools/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/gperftools/src/google/stacktrace.h b/third_party/gperftools/src/google/stacktrace.h
deleted file mode 100644
index 829b303..0000000
--- a/third_party/gperftools/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/gperftools/src/google/tcmalloc.h b/third_party/gperftools/src/google/tcmalloc.h
deleted file mode 100644
index ee8bb15..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/heap-checker.h b/third_party/gperftools/src/gperftools/heap-checker.h
deleted file mode 100644
index edd6cc7..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/heap-profiler.h b/third_party/gperftools/src/gperftools/heap-profiler.h
deleted file mode 100644
index f8076e9..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/malloc_extension.h b/third_party/gperftools/src/gperftools/malloc_extension.h
deleted file mode 100644
index d203394..0000000
--- a/third_party/gperftools/src/gperftools/malloc_extension.h
+++ /dev/null
@@ -1,446 +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.
-  //
-  // Since gperftools 2.8 heap samples are not de-duplicated by the
-  // library anymore.
-  //
-  // 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();
-
-  // 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/gperftools/src/gperftools/malloc_extension_c.h b/third_party/gperftools/src/gperftools/malloc_extension_c.h
deleted file mode 100644
index a43534f..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/malloc_hook.h b/third_party/gperftools/src/gperftools/malloc_hook.h
deleted file mode 100644
index ab655f6..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/malloc_hook_c.h b/third_party/gperftools/src/gperftools/malloc_hook_c.h
deleted file mode 100644
index 5cee782..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/nallocx.h b/third_party/gperftools/src/gperftools/nallocx.h
deleted file mode 100644
index 01f874c..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/profiler.h b/third_party/gperftools/src/gperftools/profiler.h
deleted file mode 100644
index 89e34a2..0000000
--- a/third_party/gperftools/src/gperftools/profiler.h
+++ /dev/null
@@ -1,173 +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);
-
-/* Returns the current stack trace, to be called from a SIGPROF handler. */
-PERFTOOLS_DLL_DECL int ProfilerGetStackTrace(
-    void** result, int max_depth, int skip_count, const void *uc);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  /* BASE_PROFILER_H_ */
diff --git a/third_party/gperftools/src/gperftools/stacktrace.h b/third_party/gperftools/src/gperftools/stacktrace.h
deleted file mode 100644
index a0890f4..0000000
--- a/third_party/gperftools/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/gperftools/src/gperftools/tcmalloc.h b/third_party/gperftools/src/gperftools/tcmalloc.h
deleted file mode 100644
index 51e40e3..0000000
--- a/third_party/gperftools/src/gperftools/tcmalloc.h
+++ /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  2
-#define TC_VERSION_MINOR  9
-#define TC_VERSION_PATCH  ".1"
-#define TC_VERSION_STRING "gperftools 2.9.1"
-
-/* For struct mallinfo, if it's defined. */
-#if 1
-# 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 1
-  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/gperftools/src/gperftools/tcmalloc.h.in b/third_party/gperftools/src/gperftools/tcmalloc.h.in
deleted file mode 100644
index 0c8a3dd..0000000
--- a/third_party/gperftools/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/gperftools/src/heap-checker-bcad.cc b/third_party/gperftools/src/heap-checker-bcad.cc
deleted file mode 100644
index 8b0dbe1..0000000
--- a/third_party/gperftools/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/gperftools/src/heap-checker.cc b/third_party/gperftools/src/heap-checker.cc
deleted file mode 100644
index 199fc93..0000000
--- a/third_party/gperftools/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 %zu; %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 %zu", 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 %zu bytes at %p"
-                    ": have stack inside: %p",
-                    (stack_disable ? "stack" : "range"),
-                    info.object_size, ptr, AsPtr(*iter));
-        return;
-      }
-    }
-    RAW_VLOG(11, "%s-disabling %zu 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 %zu 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 %zu 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 %zu 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 %zu 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 %zu bytes at %p "
-                      "inside %p of size %zu",
-                      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 %zu 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 %zu 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: %zu bytes "
-               "in %zu 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/gperftools/src/heap-profile-stats.h b/third_party/gperftools/src/heap-profile-stats.h
deleted file mode 100644
index 1e0359a..0000000
--- a/third_party/gperftools/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/gperftools/src/heap-profile-table.cc b/third_party/gperftools/src/heap-profile-table.cc
deleted file mode 100644
index 93d592c..0000000
--- a/third_party/gperftools/src/heap-profile-table.cc
+++ /dev/null
@@ -1,629 +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;
-  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 %zu bytes "
-          "in %zu 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 %zu byte object %p", v->bytes, ptr);
-}
-
-void HeapProfileTable::Snapshot::ReportIndividualObjects() {
-  char unused;
-  map_.Iterate(ReportObject, &unused);
-}
diff --git a/third_party/gperftools/src/heap-profile-table.h b/third_party/gperftools/src/heap-profile-table.h
deleted file mode 100644
index afe1319..0000000
--- a/third_party/gperftools/src/heap-profile-table.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
-//         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();
-
-  // 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_;
-
-  DISALLOW_COPY_AND_ASSIGN(HeapProfileTable);
-};
-
-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/gperftools/src/heap-profiler.cc b/third_party/gperftools/src/heap-profiler.cc
deleted file mode 100644
index 47df779..0000000
--- a/third_party/gperftools/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 std::string;
-using std::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 PRIxPTR 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=%zu, 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 PRIxPTR 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=%zu, "
-            "new_size=%zu, 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 PRIxPTR 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=%zu)",
-                  (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=%zd) = 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/gperftools/src/internal_logging.cc b/third_party/gperftools/src/internal_logging.cc
deleted file mode 100644
index ca1c86e..0000000
--- a/third_party/gperftools/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/gperftools/src/internal_logging.h b/third_party/gperftools/src/internal_logging.h
deleted file mode 100644
index 1b0468e..0000000
--- a/third_party/gperftools/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/gperftools/src/libc_override.h b/third_party/gperftools/src/libc_override.h
deleted file mode 100644
index c981c3d..0000000
--- a/third_party/gperftools/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/gperftools/src/libc_override_gcc_and_weak.h b/third_party/gperftools/src/libc_override_gcc_and_weak.h
deleted file mode 100644
index bb99b69..0000000
--- a/third_party/gperftools/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_sized);
-void operator delete[](void *p, size_t size) CPP_NOTHROW
-  ALIAS(tc_deletearray_sized);
-
-#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_sized_aligned);
-void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
-  ALIAS(tc_deletearray_sized_aligned);
-
-#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/gperftools/src/libc_override_glibc.h b/third_party/gperftools/src/libc_override_glibc.h
deleted file mode 100644
index 3269213..0000000
--- a/third_party/gperftools/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/gperftools/src/libc_override_osx.h b/third_party/gperftools/src/libc_override_osx.h
deleted file mode 100644
index 9d5d611..0000000
--- a/third_party/gperftools/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/gperftools/src/libc_override_redefine.h b/third_party/gperftools/src/libc_override_redefine.h
deleted file mode 100644
index 4d61b25..0000000
--- a/third_party/gperftools/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/gperftools/src/linked_list.h b/third_party/gperftools/src/linked_list.h
deleted file mode 100644
index f25b6f8..0000000
--- a/third_party/gperftools/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/gperftools/src/malloc_extension.cc b/third_party/gperftools/src/malloc_extension.cc
deleted file mode 100644
index 68cb98a..0000000
--- a/third_party/gperftools/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 std::string;
-using std::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/gperftools/src/malloc_hook-inl.h b/third_party/gperftools/src/malloc_hook-inl.h
deleted file mode 100644
index b07704e..0000000
--- a/third_party/gperftools/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/gperftools/src/malloc_hook.cc b/third_party/gperftools/src/malloc_hook.cc
deleted file mode 100644
index 9d5741e..0000000
--- a/third_party/gperftools/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/gperftools/src/malloc_hook_mmap_freebsd.h b/third_party/gperftools/src/malloc_hook_mmap_freebsd.h
deleted file mode 100644
index 8575dcc..0000000
--- a/third_party/gperftools/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/gperftools/src/malloc_hook_mmap_linux.h b/third_party/gperftools/src/malloc_hook_mmap_linux.h
deleted file mode 100644
index cbf3782..0000000
--- a/third_party/gperftools/src/malloc_hook_mmap_linux.h
+++ /dev/null
@@ -1,250 +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 <errno.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include <unistd.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__) || (defined(__riscv) && __riscv_xlen == 64) \
-    || defined(__e2k__)
-
-static inline void* do_mmap64(void *start, size_t length,
-                              int prot, int flags,
-                              int fd, off64_t offset) __THROW {
-#if defined(__s390__)
-  long args[6] = { (long)start, (long)length, (long)prot, (long)flags,
-                   (long)fd, (long)offset };
-  return (void*)syscall(SYS_mmap, args);
-#else
-  return (void*)syscall(SYS_mmap, start, length, prot, flags, fd, offset);
-#endif
-}
-
-#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 mmap64 and mmap doesn't get #define'd away by <sys/mman.h>
-# undef mmap64
-# 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 = 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);
-  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;
-}
-
-#ifdef HAVE___SBRK
-// 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/gperftools/src/maybe_emergency_malloc.h b/third_party/gperftools/src/maybe_emergency_malloc.h
deleted file mode 100644
index 250ecf0..0000000
--- a/third_party/gperftools/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/gperftools/src/maybe_threads.cc b/third_party/gperftools/src/maybe_threads.cc
deleted file mode 100644
index f973fbf..0000000
--- a/third_party/gperftools/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/gperftools/src/maybe_threads.h b/third_party/gperftools/src/maybe_threads.h
deleted file mode 100644
index 00f6969..0000000
--- a/third_party/gperftools/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/gperftools/src/memfs_malloc.cc b/third_party/gperftools/src/memfs_malloc.cc
deleted file mode 100644
index ef0ba5c..0000000
--- a/third_party/gperftools/src/memfs_malloc.cc
+++ /dev/null
@@ -1,279 +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");
-DEFINE_bool(memfs_malloc_disable_fallback,
-            EnvToBool("TCMALLOC_MEMFS_DISABLE_FALLBACK", false),
-            "If we run out of hugepage memory don't fallback to default "
-            "allocator.");
-
-// 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 (!FLAGS_memfs_malloc_disable_fallback && 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 (!FLAGS_memfs_malloc_disable_fallback &&
-      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 (!FLAGS_memfs_malloc_disable_fallback && aligned_size < size) {
-    return fallback_->Alloc(size, actual_size, alignment);
-  }
-
-  void* result = AllocInternal(aligned_size, actual_size, new_alignment);
-  if (result != NULL) {
-    return result;
-  } else if (FLAGS_memfs_malloc_disable_fallback) {
-    return NULL;
-  }
-  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/gperftools/src/memory_region_map.cc b/third_party/gperftools/src/memory_region_map.cc
deleted file mode 100644
index 5fb17d3..0000000
--- a/third_party/gperftools/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 %zu 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 %zu 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%" PRIxPTR " 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 %zu 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 %zu", 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 " %zu "
-              "to %zu 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 %zd", (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/gperftools/src/memory_region_map.h b/third_party/gperftools/src/memory_region_map.h
deleted file mode 100644
index c21fac3..0000000
--- a/third_party/gperftools/src/memory_region_map.h
+++ /dev/null
@@ -1,416 +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() { Unlock(); }
-   private:
-    DISALLOW_COPY_AND_ASSIGN(LockHolder);
-  };
-
-  // 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();
-
-  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/gperftools/src/packed-cache-inl.h b/third_party/gperftools/src/packed-cache-inl.h
deleted file mode 100644
index 7c216e5..0000000
--- a/third_party/gperftools/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/gperftools/src/page_heap.cc b/third_party/gperftools/src/page_heap.cc
deleted file mode 100644
index 44ad654..0000000
--- a/third_party/gperftools/src/page_heap.cc
+++ /dev/null
@@ -1,718 +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);
-
-  const int extra = span->length - n;
-  Span* leftover = NewSpan(span->start + n, extra);
-  ASSERT(leftover->location == Span::IN_USE);
-  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;
-
-  const int extra = span->length - n;
-  ASSERT(extra >= 0);
-  if (extra > 0) {
-    Span* leftover = NewSpan(span->start + n, extra);
-    leftover->location = old_location;
-    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;
-  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);
-  }
-  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);
-  }
-
-  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);
-  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/gperftools/src/page_heap.h b/third_party/gperftools/src/page_heap.h
deleted file mode 100644
index bf50394..0000000
--- a/third_party/gperftools/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/gperftools/src/page_heap_allocator.h b/third_party/gperftools/src/page_heap_allocator.h
deleted file mode 100644
index 3fecabd..0000000
--- a/third_party/gperftools/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/gperftools/src/pagemap.h b/third_party/gperftools/src/pagemap.h
deleted file mode 100644
index dfa336c..0000000
--- a/third_party/gperftools/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/gperftools/src/pprof b/third_party/gperftools/src/pprof
deleted file mode 100755
index 3a816c6..0000000
--- a/third_party/gperftools/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/gperftools/src/profile-handler.cc b/third_party/gperftools/src/profile-handler.cc
deleted file mode 100644
index 0db17bb..0000000
--- a/third_party/gperftools/src/profile-handler.cc
+++ /dev/null
@@ -1,599 +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 sigevent
-#include <signal.h>
-// for SYS_gettid
-#include <sys/syscall.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"
-
-// Some Linux systems don't have sigev_notify_thread_id defined in
-// signal.h (despite having SIGEV_THREAD_ID defined) and also lack
-// working linux/signal.h. So lets workaround. Note, we know that at
-// least on Linux sigev_notify_thread_id is macro.
-//
-// See https://sourceware.org/bugzilla/show_bug.cgi?id=27417 and
-// https://bugzilla.kernel.org/show_bug.cgi?id=200081
-//
-#if __linux__ && HAVE_LINUX_SIGEV_THREAD_ID && !defined(sigev_notify_thread_id)
-#define sigev_notify_thread_id _sigev_un._tid
-#endif
-
-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_notify_thread_id = syscall(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 = 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/gperftools/src/profile-handler.h b/third_party/gperftools/src/profile-handler.h
deleted file mode 100644
index b6bb0a1..0000000
--- a/third_party/gperftools/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/gperftools/src/profiledata.cc b/third_party/gperftools/src/profiledata.cc
deleted file mode 100644
index 7bfb727..0000000
--- a/third_party/gperftools/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/%zu\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/gperftools/src/profiledata.h b/third_party/gperftools/src/profiledata.h
deleted file mode 100644
index a4f0446..0000000
--- a/third_party/gperftools/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 = 254;  // 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/gperftools/src/profiler.cc b/third_party/gperftools/src/profiler.cc
deleted file mode 100644
index 227deb2..0000000
--- a/third_party/gperftools/src/profiler.cc
+++ /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
-//         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"
-
-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)
-{
-  static unsigned profile_count;
-  static char base_profile_name[PATH_MAX];
-  static bool started = false;
-
-  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[PATH_MAX + 16];
-
-    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);
-}
-
-extern "C" PERFTOOLS_DLL_DECL int ProfilerGetStackTrace(
-    void** result, int max_depth, int skip_count, const void *uc) {
-  return GetStackTraceWithContext(result, max_depth, skip_count, uc);
-}
-
-#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));
-}
-extern "C" int ProfilerGetStackTrace(
-    void** result, int max_depth, int skip_count, const void *uc) {
-  return 0;
-}
-
-#endif  // OS_CYGWIN
-
-// DEPRECATED routines
-extern "C" PERFTOOLS_DLL_DECL void ProfilerEnable() { }
-extern "C" PERFTOOLS_DLL_DECL void ProfilerDisable() { }
diff --git a/third_party/gperftools/src/raw_printer.cc b/third_party/gperftools/src/raw_printer.cc
deleted file mode 100644
index 785d473..0000000
--- a/third_party/gperftools/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/gperftools/src/raw_printer.h b/third_party/gperftools/src/raw_printer.h
deleted file mode 100644
index 5f57bbf..0000000
--- a/third_party/gperftools/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/gperftools/src/sampler.cc b/third_party/gperftools/src/sampler.cc
deleted file mode 100644
index 20bf1ad..0000000
--- a/third_party/gperftools/src/sampler.cc
+++ /dev/null
@@ -1,134 +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, 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 FLAGS_tcmalloc_sample_parameter <= 0;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/gperftools/src/sampler.h b/third_party/gperftools/src/sampler.h
deleted file mode 100644
index 0a281c5..0000000
--- a/third_party/gperftools/src/sampler.h
+++ /dev/null
@@ -1,232 +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:
-  constexpr Sampler() {}
-
-  // 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.
- private:
-  friend class SamplerTest;
-  bool RecordAllocationSlow(size_t k);
-
-  ssize_t bytes_until_sample_{};
-  uint64_t rnd_{};  // Cheap random number generator
-  bool initialized_{};
-};
-
-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 = *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/gperftools/src/solaris/libstdc++.la b/third_party/gperftools/src/solaris/libstdc++.la
deleted file mode 100644
index 3edf425..0000000
--- a/third_party/gperftools/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/gperftools/src/span.cc b/third_party/gperftools/src/span.cc
deleted file mode 100644
index eac43f4..0000000
--- a/third_party/gperftools/src/span.cc
+++ /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 <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 {
-
-Span* NewSpan(PageID p, Length len) {
-  Span* result = Static::span_allocator()->New();
-  memset(result, 0, sizeof(*result));
-  result->start = p;
-  result->length = len;
-  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/gperftools/src/span.h b/third_party/gperftools/src/span.h
deleted file mode 100644
index 7068893..0000000
--- a/third_party/gperftools/src/span.h
+++ /dev/null
@@ -1,161 +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();
-
-  // What freelist the span is on: IN_USE if on none, or normal or returned
-  enum { IN_USE, ON_NORMAL_FREELIST, ON_RETURNED_FREELIST };
-};
-
-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/gperftools/src/stack_trace_table.cc b/third_party/gperftools/src/stack_trace_table.cc
deleted file mode 100644
index 5888dc0..0000000
--- a/third_party/gperftools/src/stack_trace_table.cc
+++ /dev/null
@@ -1,123 +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 {
-
-StackTraceTable::StackTraceTable()
-    : error_(false),
-      depth_total_(0),
-      bucket_total_(0),
-      head_(nullptr) {
-}
-
-StackTraceTable::~StackTraceTable() {
-  ASSERT(head_ == nullptr);
-}
-
-void StackTraceTable::AddTrace(const StackTrace& t) {
-  if (error_) {
-    return;
-  }
-
-  depth_total_ += t.depth;
-  bucket_total_++;
-  Entry* entry = allocator_.allocate(1);
-  if (entry == nullptr) {
-    Log(kLog, __FILE__, __LINE__,
-        "tcmalloc: could not allocate bucket", sizeof(*entry));
-    error_ = true;
-  } else {
-    entry->trace = t;
-    entry->next = head_;
-    head_ = entry;
-  }
-}
-
-void** StackTraceTable::ReadStackTracesAndClear() {
-  void** out = nullptr;
-
-  const int out_len = bucket_total_ * 3 + depth_total_ + 1;
-  if (!error_) {
-    // Allocate output array
-    out = new (std::nothrow_t{}) void*[out_len];
-    if (out == nullptr) {
-      Log(kLog, __FILE__, __LINE__,
-          "tcmalloc: allocation failed for stack traces",
-          out_len * sizeof(*out));
-    }
-  }
-
-  if (out) {
-    // Fill output array
-    int idx = 0;
-    Entry* entry = head_;
-    while (entry != NULL) {
-      out[idx++] = reinterpret_cast<void*>(uintptr_t{1});   // count
-      out[idx++] = reinterpret_cast<void*>(entry->trace.size);  // cumulative size
-      out[idx++] = reinterpret_cast<void*>(entry->trace.depth);
-      for (int d = 0; d < entry->trace.depth; ++d) {
-        out[idx++] = entry->trace.stack[d];
-      }
-      entry = entry->next;
-    }
-    out[idx++] = NULL;
-    ASSERT(idx == out_len);
-  }
-
-  // Clear state
-  error_ = false;
-  depth_total_ = 0;
-  bucket_total_ = 0;
-
-  SpinLockHolder h(Static::pageheap_lock());
-  Entry* entry = head_;
-  while (entry != nullptr) {
-    Entry* next = entry->next;
-    allocator_.deallocate(entry, 1);
-    entry = next;
-  }
-  head_ = nullptr;
-
-  return out;
-}
-
-}  // namespace tcmalloc
diff --git a/third_party/gperftools/src/stack_trace_table.h b/third_party/gperftools/src/stack_trace_table.h
deleted file mode 100644
index 46b86ba..0000000
--- a/third_party/gperftools/src/stack_trace_table.h
+++ /dev/null
@@ -1,85 +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"
-#include "page_heap_allocator.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
-  // For testing
-  int depth_total() const { return depth_total_; }
-  int bucket_total() const { return bucket_total_; }
-
- private:
-  struct Entry {
-    Entry* next;
-    StackTrace trace;
-  };
-
-  bool error_;
-  int depth_total_;
-  int bucket_total_;
-  Entry* head_;
-  STLPageHeapAllocator<Entry, void> allocator_;
-};
-
-}  // namespace tcmalloc
-
-#endif  // TCMALLOC_STACK_TRACE_TABLE_H_
diff --git a/third_party/gperftools/src/stacktrace.cc b/third_party/gperftools/src/stacktrace.cc
deleted file mode 100644
index 2a2c648..0000000
--- a/third_party/gperftools/src/stacktrace.cc
+++ /dev/null
@@ -1,396 +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
-
-// Sadly, different OSes have very different mcontexts even for
-// identical hardware arch. So keep it linux-only for now.
-#if defined(__GNUC__) && __linux__ && (defined(__x86_64__) || defined(__aarch64__) || defined(__riscv))
-#define STACKTRACE_INL_HEADER "stacktrace_generic_fp-inl.h"
-#define GST_SUFFIX generic_fp
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_generic_fp
-
-#undef TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE
-#define TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE 1
-
-#define STACKTRACE_INL_HEADER "stacktrace_generic_fp-inl.h"
-#define GST_SUFFIX generic_fp_unsafe
-#include "stacktrace_impl_setup-inl.h"
-#undef GST_SUFFIX
-#undef STACKTRACE_INL_HEADER
-#define HAVE_GST_generic_fp_unsafe
-#endif
-
-#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_generic_fp
-  &impl__generic_fp,
-#endif
-#ifdef HAVE_GST_generic_fp
-  &impl__generic_fp_unsafe,
-#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(__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_generic_fp) && !defined(NO_FRAME_POINTER) \
-   && !defined(__riscv) \
-   && (!defined(HAVE_GST_libunwind) || defined(TCMALLOC_DONT_PREFER_LIBUNWIND))
-static GetStackImplementation *get_stack_impl = &impl__generic_fp;
-#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));
-}
-
-// As of this writing, aarch64 has completely borked libunwind, so
-// lets test this case and fall back to frame pointers (which is
-// nearly but not quite perfect).
-ATTRIBUTE_NOINLINE
-static void maybe_convert_libunwind_to_generic_fp() {
-#if defined(HAVE_GST_libunwind) && defined(HAVE_GST_generic_fp)
-  if (get_stack_impl != &impl__libunwind) {
-    return;
-  }
-
-  // Okay we're on libunwind and we have generic_fp, check if
-  // libunwind returns bogus results.
-  void* stack[4];
-  int rv = get_stack_impl->GetStackTracePtr(stack, 4, 0);
-  if (rv > 2) {
-    // Seems fine
-    return;
-  }
-  // bogus. So replacing with generic_fp
-  get_stack_impl = &impl__generic_fp;
-#endif
-}
-
-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) {
-    maybe_convert_libunwind_to_generic_fp();
-    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);
-}
-
-ATTRIBUTE_NOINLINE
-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/gperftools/src/stacktrace_arm-inl.h b/third_party/gperftools/src/stacktrace_arm-inl.h
deleted file mode 100644
index 1586b8f..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_generic-inl.h b/third_party/gperftools/src/stacktrace_generic-inl.h
deleted file mode 100644
index 7d7c22d..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_generic_fp-inl.h b/third_party/gperftools/src/stacktrace_generic_fp-inl.h
deleted file mode 100644
index d458109..0000000
--- a/third_party/gperftools/src/stacktrace_generic_fp-inl.h
+++ /dev/null
@@ -1,222 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2021, 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 contains "generic" stack frame pointer backtracing
-// code. Attempt is made to minimize amount of arch- or os-specific
-// code and keep everything as generic as possible. Currently
-// supported are x86-64, aarch64 and riscv.
-#ifndef BASE_STACKTRACE_GENERIC_FP_INL_H_
-#define BASE_STACKTRACE_GENERIC_FP_INL_H_
-
-#if defined(HAVE_SYS_UCONTEXT_H)
-#include <sys/ucontext.h>
-#elif defined(HAVE_UCONTEXT_H)
-#include <ucontext.h>
-#endif
-
-// This is only used on OS-es with mmap support.
-#include <sys/mman.h>
-
-// Set this to true to disable "probing" of addresses that are read to
-// make backtracing less-safe, but faster.
-#ifndef TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE
-#define TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE 0
-#endif
-
-namespace {
-namespace stacktrace_generic_fp {
-
-struct frame {
-  uintptr_t parent;
-  void* pc;
-};
-
-frame* adjust_fp(frame* f) {
-#ifdef __riscv
-  return f - 1;
-#else
-  return f;
-#endif
-}
-
-static bool CheckPageIsReadable(void* ptr, void* checked_ptr) {
-  static uintptr_t pagesize;
-  if (pagesize == 0) {
-    pagesize = getpagesize();
-  }
-
-  uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
-  uintptr_t parent_frame = reinterpret_cast<uintptr_t>(checked_ptr);
-
-  parent_frame &= ~(pagesize - 1);
-  addr &= ~(pagesize - 1);
-
-  if (parent_frame != 0 && addr == parent_frame) {
-    return true;
-  }
-
-  return (msync(reinterpret_cast<void*>(addr), pagesize, MS_ASYNC) == 0);
-}
-
-ATTRIBUTE_NOINLINE // forces architectures with link register to save it
-int capture(void **result, int max_depth, int skip_count,
-            void* initial_frame, void* const * initial_pc) {
-  int i = 0;
-
-  if (initial_pc != nullptr) {
-    // This is 'with ucontext' case. We take first pc from ucontext
-    // and then skip_count is ignored as we assume that caller only
-    // needed stack trace up to signal handler frame.
-    skip_count = 0;
-    if (max_depth == 0) {
-      return 0;
-    }
-    result[0] = *initial_pc;
-    i++;
-  }
-
-  constexpr uintptr_t kTooSmallAddr = 16 << 10;
-  constexpr uintptr_t kFrameSizeThreshold = 128 << 10;
-
-  // This is simplistic yet. Here we're targeting x86-64, aarch64 and
-  // riscv. All have 16 bytes stack alignment (even 32 bit
-  // riscv). This can be made more elaborate as we consider more
-  // architectures. Note, it allows us to only readability of check
-  // f->parent address.
-  constexpr uintptr_t kAlignment = 16;
-
-  uintptr_t initial_frame_addr = reinterpret_cast<uintptr_t>(initial_frame);
-  if ((initial_frame_addr & (kAlignment - 1)) != 0) {
-    return i;
-  }
-  if (initial_frame_addr < kTooSmallAddr) {
-    return i;
-  }
-
-  frame* prev_f = nullptr;
-  frame *f = adjust_fp(reinterpret_cast<frame*>(initial_frame));
-
-  while (i < max_depth) {
-    if (!TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE
-        && !CheckPageIsReadable(&f->parent, prev_f)) {
-      break;
-    }
-
-    void* pc = f->pc;
-    if (pc == nullptr) {
-      break;
-    }
-
-    if (i >= skip_count) {
-      result[i - skip_count] = pc;
-    }
-
-    i++;
-
-    uintptr_t parent_frame_addr = f->parent;
-    uintptr_t child_frame_addr = reinterpret_cast<uintptr_t>(f);
-
-    if (parent_frame_addr < kTooSmallAddr) {
-      break;
-    }
-    // stack grows towards smaller addresses, so if we didn't see
-    // frame address increased (going from child to parent), it is bad
-    // frame. We also test if frame is too big since that is another
-    // sign of bad stack frame.
-    if (parent_frame_addr - child_frame_addr > kFrameSizeThreshold) {
-      break;
-    }
-
-    if ((parent_frame_addr & (kAlignment - 1)) != 0) {
-      // not aligned, so we keep it safe and assume frame is bogus
-      break;
-    }
-
-    prev_f = f;
-
-    f = adjust_fp(reinterpret_cast<frame*>(parent_frame_addr));
-  }
-  return i;
-}
-
-}  // namespace stacktrace_generic_fp
-}  // namespace
-
-#endif  // BASE_STACKTRACE_GENERIC_FP_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 {
-#if IS_STACK_FRAMES
-  memset(sizes, 0, sizeof(*sizes) * max_depth);
-#endif
-
-  // one for this function
-  skip_count += 1;
-
-  void* const * initial_pc = nullptr;
-  void* initial_frame = __builtin_frame_address(0);
-
-#if IS_WITH_CONTEXT
-  if (ucp) {
-    auto uc = static_cast<const ucontext_t*>(ucp);
-#ifdef __riscv
-    initial_pc = reinterpret_cast<void* const *>(&uc->uc_mcontext.__gregs[REG_PC]);
-    initial_frame = reinterpret_cast<void*>(uc->uc_mcontext.__gregs[REG_S0]);
-#elif __aarch64__
-    initial_pc = reinterpret_cast<void* const *>(&uc->uc_mcontext.pc);
-    initial_frame = reinterpret_cast<void*>(uc->uc_mcontext.regs[29]);
-#else
-    initial_pc = reinterpret_cast<void* const *>(&uc->uc_mcontext.gregs[REG_RIP]);
-    initial_frame = reinterpret_cast<void*>(uc->uc_mcontext.gregs[REG_RBP]);
-#endif
-  }
-#endif  // IS_WITH_CONTEXT
-
-  int n = stacktrace_generic_fp::capture(result, max_depth, skip_count,
-                                         initial_frame, initial_pc);
-
-  // make sure we don't tail-call capture
-  (void)*(const_cast<void * volatile *>(result));
-  return n;
-}
diff --git a/third_party/gperftools/src/stacktrace_impl_setup-inl.h b/third_party/gperftools/src/stacktrace_impl_setup-inl.h
deleted file mode 100644
index 698c5b3..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_instrument-inl.h b/third_party/gperftools/src/stacktrace_instrument-inl.h
deleted file mode 100644
index c631765..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_libgcc-inl.h b/third_party/gperftools/src/stacktrace_libgcc-inl.h
deleted file mode 100644
index ce9cf51..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_libunwind-inl.h b/third_party/gperftools/src/stacktrace_libunwind-inl.h
deleted file mode 100644
index 6f361ec..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_powerpc-darwin-inl.h b/third_party/gperftools/src/stacktrace_powerpc-darwin-inl.h
deleted file mode 100644
index 3f6c367..0000000
--- a/third_party/gperftools/src/stacktrace_powerpc-darwin-inl.h
+++ /dev/null
@@ -1,163 +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.
-
-// ---
-// 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
-#ifdef __FreeBSD__
-  __asm__ volatile ("mr %0,1" : "=r" (sp));
-#else
-  __asm__ volatile ("mr %0,r1" : "=r" (sp));
-#endif
-
-  // 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/gperftools/src/stacktrace_powerpc-inl.h b/third_party/gperftools/src/stacktrace_powerpc-inl.h
deleted file mode 100644
index 124bc4e..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_powerpc-linux-inl.h b/third_party/gperftools/src/stacktrace_powerpc-linux-inl.h
deleted file mode 100644
index a301a46..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_win32-inl.h b/third_party/gperftools/src/stacktrace_win32-inl.h
deleted file mode 100644
index 663e9a5..0000000
--- a/third_party/gperftools/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/gperftools/src/stacktrace_x86-inl.h b/third_party/gperftools/src/stacktrace_x86-inl.h
deleted file mode 100644
index 46eb5d8..0000000
--- a/third_party/gperftools/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/gperftools/src/static_vars.cc b/third_party/gperftools/src/static_vars.cc
deleted file mode 100644
index fef6ed1..0000000
--- a/third_party/gperftools/src/static_vars.cc
+++ /dev/null
@@ -1,152 +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_;
-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();
-  // 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;
-
-#if defined(ENABLE_AGGRESSIVE_DECOMMIT_BY_DEFAULT)
-  const bool kDefaultAggressiveDecommit = true;
-#else
-  const bool kDefaultAggressiveDecommit = false;
-#endif
-
-
-  bool aggressive_decommit =
-    tcmalloc::commandlineflags::StringToBool(
-      TCMallocGetenvSafe("TCMALLOC_AGGRESSIVE_DECOMMIT"),
-                         kDefaultAggressiveDecommit);
-
-  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/gperftools/src/static_vars.h b/third_party/gperftools/src/static_vars.h
deleted file mode 100644
index bef0180..0000000
--- a/third_party/gperftools/src/static_vars.h
+++ /dev/null
@@ -1,126 +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_; }
-
-  // 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_;
-
-  // 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/gperftools/src/symbolize.cc b/third_party/gperftools/src/symbolize.cc
deleted file mode 100644
index 8c94c18..0000000
--- a/third_party/gperftools/src/symbolize.cc
+++ /dev/null
@@ -1,298 +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
-
-// pprof may be used 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 char* get_pprof_path() {
-  static char* result = ([] () {
-      string pprof_string = EnvToString("PPROF_PATH", "pprof-symbolize");
-      return strdup(pprof_string.c_str());
-    })();
-
-  return result;
-}
-
-// 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(get_pprof_path(), 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(get_pprof_path(), get_pprof_path(),
-             "--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/gperftools/src/symbolize.h b/third_party/gperftools/src/symbolize.h
deleted file mode 100644
index aa0aa33..0000000
--- a/third_party/gperftools/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/gperftools/src/system-alloc.cc b/third_party/gperftools/src/system-alloc.cc
deleted file mode 100644
index e84a5f1..0000000
--- a/third_party/gperftools/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/gperftools/src/system-alloc.h b/third_party/gperftools/src/system-alloc.h
deleted file mode 100644
index e88948d..0000000
--- a/third_party/gperftools/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/gperftools/src/tcmalloc.cc b/third_party/gperftools/src/tcmalloc.cc
deleted file mode 100644
index 9ec663e..0000000
--- a/third_party/gperftools/src/tcmalloc.cc
+++ /dev/null
@@ -1,2225 +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 std::max;
-using std::min;
-using std::numeric_limits;
-using std::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);
-DECLARE_int64(tcmalloc_heap_limit_mb);
-
-// 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_bytes = 0;
-    uint64_t cumulative_overhead = 0;
-    for (uint32 cl = 0; cl < Static::num_size_classes(); ++cl) {
-      if (class_count[cl] > 0) {
-        size_t cl_size = Static::sizemap()->ByteSizeForClass(cl);
-        const uint64_t class_bytes = class_count[cl] * cl_size;
-        cumulative_bytes += class_bytes;
-        const uint64_t class_overhead =
-            Static::central_cache()[cl].OverheadBytes();
-        cumulative_overhead += class_overhead;
-        out->printf("class %3d [ %8zu bytes ] : "
-                "%8" PRIu64 " objs; %5.1f MiB; %5.1f cum MiB; "
-                "%8.3f overhead MiB; %8.3f cum overhead MiB\n",
-                cl, cl_size,
-                class_count[cl],
-                class_bytes / MiB,
-                cumulative_bytes / MiB,
-                class_overhead / MiB,
-                cumulative_overhead / 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, "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.heap_limit_mb") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      *value = FLAGS_tcmalloc_heap_limit_mb;
-      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.heap_limit_mb") == 0) {
-      SpinLockHolder l(Static::pageheap_lock());
-      FLAGS_tcmalloc_heap_limit_mb = 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.
-#ifdef ENABLE_LARGE_ALLOC_REPORT
-static int64_t large_alloc_threshold =
-  (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
-   ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
-#endif
-
-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) {
-#ifdef ENABLE_LARGE_ALLOC_REPORT
-  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;
-  }
-#endif
-  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, tc_nallocx(size, 0));
-  }
-  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);
-}
-
-#ifndef NDEBUG
-// note, with sized deletions we have no means to support win32
-// behavior where we detect "not ours" points and delegate them native
-// memory management. This is because nature of sized deletes
-// bypassing addr -> size class checks. So in this validation code we
-// also assume that sized delete is always used with "our" pointers.
-bool ValidateSizeHint(void* ptr, size_t size_hint) {
-  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
-  Span* span  = Static::pageheap()->GetDescriptor(p);
-  uint32 cl = 0;
-  Static::sizemap()->GetSizeClass(size_hint, &cl);
-  return (span->sizeclass == cl);
-}
-#endif
-
-// 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;
-
-  ASSERT(!use_hint || ValidateSizeHint(ptr, size_hint));
-
-  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
-{
-  if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
-    tcmalloc::invoke_hooks_and_free(p);
-    return;
-  }
-  do_free(p);
-}
-
-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
-{
-  free_fast_path(p);
-}
-
-// 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
-{
-  free_fast_path(p);
-}
-
-extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW
-{
-  free_fast_path(p);
-}
-
-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/gperftools/src/tcmalloc.h b/third_party/gperftools/src/tcmalloc.h
deleted file mode 100644
index 016c805..0000000
--- a/third_party/gperftools/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_DECL_CFREE
-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/gperftools/src/tcmalloc_guard.h b/third_party/gperftools/src/tcmalloc_guard.h
deleted file mode 100644
index 84952ba..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/addressmap_unittest.cc b/third_party/gperftools/src/tests/addressmap_unittest.cc
deleted file mode 100644
index 45781f3..0000000
--- a/third_party/gperftools/src/tests/addressmap_unittest.cc
+++ /dev/null
@@ -1,174 +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 <random>
-#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::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
-    std::random_device rd;
-    std::mt19937 g(rd());
-    shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end(), g);
-
-    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/gperftools/src/tests/atomicops_unittest.cc b/third_party/gperftools/src/tests/atomicops_unittest.cc
deleted file mode 100644
index 22be839..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/current_allocated_bytes_test.cc b/third_party/gperftools/src/tests/current_allocated_bytes_test.cc
deleted file mode 100644
index 49b7dc3..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/debugallocation_test.cc b/third_party/gperftools/src/tests/debugallocation_test.cc
deleted file mode 100644
index 1e45db6..0000000
--- a/third_party/gperftools/src/tests/debugallocation_test.cc
+++ /dev/null
@@ -1,333 +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"
-#include "tests/testutil.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*>(noopt(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 = noopt(new int);
-    int* y = noopt(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 = noopt(new int[1]);
-    int* y = noopt(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 = noopt(new (std::nothrow) int);
-    int* y = noopt(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 = noopt(new (std::nothrow) int[1]);
-    int* y = noopt(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 = noopt(new int);
-  delete pint;
-  IF_DEBUG_EXPECT_DEATH(delete pint, "has been already deallocated");
-}
-
-TEST(DebugAllocationTest, StompBefore) {
-  int* pint = noopt(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 = noopt(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 = noopt(new int);
-  int* old_x = x;
-  delete x;
-  x = noopt(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 = noopt(new int);
-  delete x;
-  int poisoned_x_value = *x;
-  *x = 1;  // a dangling write.
-
-  char* s = noopt(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 = noopt(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 = noopt(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(noopt(malloc(1)));
-  FLAGS_max_free_queue_size = 1048576;
-#endif
-
-  // Free something and check that it disappears from allocated bytes
-  // immediately.
-  char* p = noopt(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 = noopt(malloc(i));
-    EXPECT_EQ(i, MallocExtension::instance()->GetAllocatedSize(p));
-    free(p);
-  }
-#endif
-  void* a = noopt(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 = noopt(malloc(noopt(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 = noopt(malloc(noopt(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 = noopt(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/gperftools/src/tests/debugallocation_test.sh b/third_party/gperftools/src/tests/debugallocation_test.sh
deleted file mode 100755
index 0f94ad0..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/frag_unittest.cc b/third_party/gperftools/src/tests/frag_unittest.cc
deleted file mode 100644
index 6d2619f..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/getpc_test.cc b/third_party/gperftools/src/tests/getpc_test.cc
deleted file mode 100644
index 9bc3266..0000000
--- a/third_party/gperftools/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 void* volatile 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/gperftools/src/tests/heap-checker-death_unittest.sh b/third_party/gperftools/src/tests/heap-checker-death_unittest.sh
deleted file mode 100755
index 69db0c9..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/heap-checker_unittest.cc b/third_party/gperftools/src/tests/heap-checker_unittest.cc
deleted file mode 100644
index b4bcb52..0000000
--- a/third_party/gperftools/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::value_type* ptrs[kSize];
-  for (int i = 0; i < kSize; ++i) {
-    typename Alloc::value_type* 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* (* volatile 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/gperftools/src/tests/heap-checker_unittest.sh b/third_party/gperftools/src/tests/heap-checker_unittest.sh
deleted file mode 100755
index 3c9c0e9..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/heap-profiler_unittest.cc b/third_party/gperftools/src/tests/heap-profiler_unittest.cc
deleted file mode 100644
index addb5f1..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/heap-profiler_unittest.sh b/third_party/gperftools/src/tests/heap-profiler_unittest.sh
deleted file mode 100755
index 91af04f..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/large_heap_fragmentation_unittest.cc b/third_party/gperftools/src/tests/large_heap_fragmentation_unittest.cc
deleted file mode 100644
index 0886599..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/low_level_alloc_unittest.cc b/third_party/gperftools/src/tests/low_level_alloc_unittest.cc
deleted file mode 100644
index 0474441..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/malloc_extension_c_test.c b/third_party/gperftools/src/tests/malloc_extension_c_test.c
deleted file mode 100644
index 2868b9c..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/malloc_extension_test.cc b/third_party/gperftools/src/tests/malloc_extension_test.cc
deleted file mode 100644
index 6570772..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/malloc_hook_test.cc b/third_party/gperftools/src/tests/malloc_hook_test.cc
deleted file mode 100644
index 6dc807b..0000000
--- a/third_party/gperftools/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 = num_threads_remaining - 1;
-
-    // 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/gperftools/src/tests/markidle_unittest.cc b/third_party/gperftools/src/tests/markidle_unittest.cc
deleted file mode 100644
index 829c503..0000000
--- a/third_party/gperftools/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: %zu\n", original);
-  VLOG(0, "Post allocation: %zu\n", post_allocation);
-  VLOG(0, "Post idle: %zu\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: %zu\n", original);
-  VLOG(0, "Post allocation: %zu\n", post_allocation);
-  VLOG(0, "Post idle: %zu\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/gperftools/src/tests/maybe_threads_unittest.sh b/third_party/gperftools/src/tests/maybe_threads_unittest.sh
deleted file mode 100755
index 77b3b78..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/memalign_unittest.cc b/third_party/gperftools/src/tests/memalign_unittest.cc
deleted file mode 100644
index 035f709..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/packed-cache_test.cc b/third_party/gperftools/src/tests/packed-cache_test.cc
deleted file mode 100644
index 3984594..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/page_heap_test.cc b/third_party/gperftools/src/tests/page_heap_test.cc
deleted file mode 100644
index 3caacc0..0000000
--- a/third_party/gperftools/src/tests/page_heap_test.cc
+++ /dev/null
@@ -1,202 +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>
-
-#include <memory>
-
-#include "page_heap.h"
-#include "system-alloc.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() {
-  std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
-
-  // Empty page heap
-  CheckStats(ph.get(), 0, 0, 0);
-
-  // Allocate a span 's1'
-  tcmalloc::Span* s1 = ph->New(256);
-  CheckStats(ph.get(), 256, 0, 0);
-
-  // Split span 's1' into 's1', 's2'.  Delete 's2'
-  tcmalloc::Span* s2 = ph->Split(s1, 128);
-  ph->Delete(s2);
-  CheckStats(ph.get(), 256, 128, 0);
-
-  // Unmap deleted span 's2'
-  ph->ReleaseAtLeastNPages(1);
-  CheckStats(ph.get(), 256, 0, 128);
-
-  // Delete span 's1'
-  ph->Delete(s1);
-  CheckStats(ph.get(), 256, 128, 128);
-}
-
-// The number of kMaxPages-sized Spans we will allocate and free during the
-// tests.
-// We will also do twice this many kMaxPages/2-sized ones.
-static constexpr int kNumberMaxPagesSpans = 10;
-
-// Allocates all the last-level page tables we will need. Doing this before
-// calculating the base heap usage is necessary, because otherwise if any of
-// these are allocated during the main test it will throw the heap usage
-// calculations off and cause the test to fail.
-static void AllocateAllPageTables() {
-  // Make a separate PageHeap from the main test so the test can start without
-  // any pages in the lists.
-  std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
-  tcmalloc::Span *spans[kNumberMaxPagesSpans * 2];
-  for (int i = 0; i < kNumberMaxPagesSpans; ++i) {
-    spans[i] = ph->New(kMaxPages);
-    EXPECT_NE(spans[i], NULL);
-  }
-  for (int i = 0; i < kNumberMaxPagesSpans; ++i) {
-    ph->Delete(spans[i]);
-  }
-  for (int i = 0; i < kNumberMaxPagesSpans * 2; ++i) {
-    spans[i] = ph->New(kMaxPages >> 1);
-    EXPECT_NE(spans[i], NULL);
-  }
-  for (int i = 0; i < kNumberMaxPagesSpans * 2; ++i) {
-    ph->Delete(spans[i]);
-  }
-}
-
-static void TestPageHeap_Limit() {
-  AllocateAllPageTables();
-
-  std::unique_ptr<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 += kNumberMaxPagesSpans - 1;
-    ph->Delete(s);
-    // We are [10, 11) mb from the limit now.
-  }
-
-  // Test AllocLarge and GrowHeap first:
-  {
-    tcmalloc::Span * spans[kNumberMaxPagesSpans];
-    for (int i=0; i<kNumberMaxPagesSpans; ++i) {
-      spans[i] = ph->New(kMaxPages);
-      EXPECT_NE(spans[i], NULL);
-    }
-    EXPECT_EQ(ph->New(kMaxPages), NULL);
-
-    for (int i=0; i<kNumberMaxPagesSpans; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    tcmalloc::Span *defragmented =
-        ph->New(kNumberMaxPagesSpans / 2 * 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<kNumberMaxPagesSpans; i += 2) {
-      ph->Delete(spans[i]);
-    }
-  }
-
-  // Once again, testing small lists this time (twice smaller spans):
-  {
-    tcmalloc::Span * spans[kNumberMaxPagesSpans * 2];
-    for (int i=0; i<kNumberMaxPagesSpans * 2; ++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<kNumberMaxPagesSpans * 2; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    for (Length len = kMaxPages >> 2;
-         len < kNumberMaxPagesSpans / 2 * 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<kNumberMaxPagesSpans * 2; i += 2) {
-      ph->Delete(spans[i]);
-    }
-
-    if (lastHalf != NULL) {
-      ph->Delete(lastHalf);
-    }
-  }
-}
-
-}  // 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/gperftools/src/tests/pagemap_unittest.cc b/third_party/gperftools/src/tests/pagemap_unittest.cc
deleted file mode 100644
index 71a94dc..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/profile-handler_unittest.cc b/third_party/gperftools/src/tests/profile-handler_unittest.cc
deleted file mode 100644
index a8afbca..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/profiledata_unittest.cc b/third_party/gperftools/src/tests/profiledata_unittest.cc
deleted file mode 100644
index 84bef5a..0000000
--- a/third_party/gperftools/src/tests/profiledata_unittest.cc
+++ /dev/null
@@ -1,617 +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() {
-    // Use Bazel's TEST_TMPDIR first if it exists.
-    const char *tmpdir = getenv("TEST_TMPDIR");
-    if (tmpdir == NULL) {
-      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/gperftools/src/tests/profiler_unittest.cc b/third_party/gperftools/src/tests/profiler_unittest.cc
deleted file mode 100644
index 4c814c0..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/profiler_unittest.sh b/third_party/gperftools/src/tests/profiler_unittest.sh
deleted file mode 100755
index 4085f2c..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/raw_printer_test.cc b/third_party/gperftools/src/tests/raw_printer_test.cc
deleted file mode 100644
index 2c7be6a..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/realloc_unittest.cc b/third_party/gperftools/src/tests/realloc_unittest.cc
deleted file mode 100644
index a4ea17c..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/sampler_test.cc b/third_party/gperftools/src/tests/sampler_test.cc
deleted file mode 100644
index 4095d6a..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/sampling_test.cc b/third_party/gperftools/src/tests/sampling_test.cc
deleted file mode 100644
index 729aba8..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/sampling_test.sh b/third_party/gperftools/src/tests/sampling_test.sh
deleted file mode 100755
index 2a58426..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/simple_compat_test.cc b/third_party/gperftools/src/tests/simple_compat_test.cc
deleted file mode 100644
index 24583a0..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/stack_trace_table_test.cc b/third_party/gperftools/src/tests/stack_trace_table_test.cc
deleted file mode 100644
index 393ebbe..0000000
--- a/third_party/gperftools/src/tests/stack_trace_table_test.cc
+++ /dev/null
@@ -1,93 +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, 512, 2, 2, 1, 1, 1024, 2, 1, 2, 0};
-  CheckTracesAndReset(&table, k3, ARRAYSIZE(k3));
-
-  // Table w/ t1, t3
-  // 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);
-
-  AddTrace(&table, t1);
-  AddTrace(&table, t3);
-  CHECK_EQ(table.depth_total(), 4);
-  CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k5[] = {1, 2, 2, 1, 2, 1, 1024, 2, 1, 2, 0};
-  CheckTracesAndReset(&table, k5, ARRAYSIZE(k5));
-
-  puts("PASS");
-  return 0;
-}
diff --git a/third_party/gperftools/src/tests/stacktrace_unittest.cc b/third_party/gperftools/src/tests/stacktrace_unittest.cc
deleted file mode 100644
index e55a632..0000000
--- a/third_party/gperftools/src/tests/stacktrace_unittest.cc
+++ /dev/null
@@ -1,298 +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.
-
-#include "config_for_unittests.h"
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-
-// On those architectures we can and should test if backtracing with
-// ucontext and from signal handler works
-#if __GNUC__ && __linux__ && (__x86_64__ || __aarch64__ || __riscv)
-#include <signal.h>
-#define TEST_UCONTEXT_BITS 1
-#endif
-
-#include "base/commandlineflags.h"
-#include "base/logging.h"
-#include <gperftools/stacktrace.h>
-#include "tests/testutil.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);
-}
-
-//-----------------------------------------------------------------------//
-
-#if TEST_UCONTEXT_BITS
-
-struct get_stack_trace_args {
-	int *size_ptr;
-	void **result;
-	int max_depth;
-	uintptr_t where;
-} gst_args;
-
-static
-void SignalHandler(int dummy, siginfo_t *si, void* ucv) {
-	auto uc = static_cast<ucontext_t*>(ucv);
-
-#ifdef __riscv
-	uc->uc_mcontext.__gregs[REG_PC] = gst_args.where;
-#elif __aarch64__
-	uc->uc_mcontext.pc = gst_args.where;
-#else
-	uc->uc_mcontext.gregs[REG_RIP] = gst_args.where;
-#endif
-
-	*gst_args.size_ptr = GetStackTraceWithContext(
-		gst_args.result,
-		gst_args.max_depth,
-		2,
-		uc);
-}
-
-int ATTRIBUTE_NOINLINE CaptureLeafUContext(void **stack, int stack_len) {
-  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
-  DECLARE_ADDRESS_LABEL(start);
-
-  int size;
-
-  printf("Capturing stack trace from signal's ucontext\n");
-  struct sigaction sa;
-  memset(&sa, 0, sizeof(sa));
-  sa.sa_sigaction = SignalHandler;
-  sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
-  int rv = sigaction(SIGSEGV, &sa, nullptr);
-  CHECK(rv == 0);
-
-  gst_args.size_ptr = &size;
-  gst_args.result = stack;
-  gst_args.max_depth = stack_len;
-  gst_args.where = reinterpret_cast<uintptr_t>(noopt(&&after));
-
-  // now, "write" to null pointer and trigger sigsegv to run signal
-  // handler. It'll then change PC to after, as if we jumped one line
-  // below.
-  *noopt(reinterpret_cast<void**>(0)) = 0;
-  // this is not reached, but gcc gets really odd if we don't actually
-  // use computed goto.
-  static void* jump_target = &&after;
-  goto *noopt(&jump_target);
-
-after:
-  printf("Obtained %d stack frames.\n", size);
-  CHECK_GE(size, 1);
-  CHECK_LE(size, stack_len);
-
-  DECLARE_ADDRESS_LABEL(end);
-
-  return size;
-}
-
-#endif  // TEST_UCONTEXT_BITS
-
-int ATTRIBUTE_NOINLINE CaptureLeafPlain(void **stack, int stack_len) {
-  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
-  DECLARE_ADDRESS_LABEL(start);
-
-  int size = GetStackTrace(stack, stack_len, 0);
-
-  printf("Obtained %d stack frames.\n", size);
-  CHECK_GE(size, 1);
-  CHECK_LE(size, stack_len);
-
-  DECLARE_ADDRESS_LABEL(end);
-
-  return size;
-}
-
-void ATTRIBUTE_NOINLINE CheckStackTrace(int);
-
-int (*leaf_capture_fn)(void**, int) = CaptureLeafPlain;
-
-void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(int i) {
-  const int STACK_LEN = 20;
-  void *stack[STACK_LEN];
-  int size;
-
-  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
-
-  size = leaf_capture_fn(stack, STACK_LEN);
-
-#ifdef HAVE_EXECINFO_H
-  {
-    char **strings = backtrace_symbols(stack, 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, j = 0; i < BACKTRACE_STEPS; i++, j++) {
-    if (i == 1 && j == 1) {
-      // this is expected to be our function for which we don't
-      // establish bounds. So skip.
-      j++;
-    }
-    printf("Backtrace %d: expected: %p..%p  actual: %p ... ",
-           i, expected_range[i].start, expected_range[i].end, stack[j]);
-    fflush(stdout);
-    CheckRetAddrIsInFunction(stack[j], expected_range[i]);
-    printf("OK\n");
-  }
-}
-
-//-----------------------------------------------------------------------//
-
-/* 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(j);
-  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");
-
-#if TEST_UCONTEXT_BITS
-  leaf_capture_fn = CaptureLeafUContext;
-  CheckStackTrace(0);
-  printf("PASS\n");
-#endif  // TEST_UCONTEXT_BITS
-
-  return 0;
-}
diff --git a/third_party/gperftools/src/tests/system-alloc_unittest.cc b/third_party/gperftools/src/tests/system-alloc_unittest.cc
deleted file mode 100644
index fd199e2..0000000
--- a/third_party/gperftools/src/tests/system-alloc_unittest.cc
+++ /dev/null
@@ -1,161 +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 "common.h"                      // for kAddressBits
-#include "gperftools/malloc_extension.h" // for MallocExtension::instance
-#include "gperftools/tcmalloc.h"
-#include "tests/testutil.h"
-
-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 =  noopt(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 = noopt(malloc(kHugeSize));
-  void* p2 = noopt(malloc(kHugeSize));
-  CHECK(p2 == NULL);
-  if (p1 != NULL) free(p1);
-
-  char* q = noopt(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/gperftools/src/tests/tcmalloc_large_unittest.cc b/third_party/gperftools/src/tests/tcmalloc_large_unittest.cc
deleted file mode 100644
index 02b8569..0000000
--- a/third_party/gperftools/src/tests/tcmalloc_large_unittest.cc
+++ /dev/null
@@ -1,139 +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
-#include "gperftools/tcmalloc.h"
-#include "tests/testutil.h"
-
-using std::set;
-
-// Alloc a size that should always fail.
-
-void TryAllocExpectFail(size_t size) {
-  void* p1 = noopt(malloc(size));
-  CHECK(p1 == NULL);
-
-  void* p2 = noopt(malloc(1));
-  CHECK(p2 != NULL);
-
-  void* p3 = noopt(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*>(noopt(malloc(size)));
-  if (p != NULL) {
-    static const size_t kPoints = 1024;
-
-    for ( size_t i = 0; i < kPoints; ++i ) {
-      p[i * (size / kPoints)] = static_cast<unsigned char>(i);
-    }
-
-    for ( size_t i = 0; i < kPoints; ++i ) {
-      CHECK(p[i * (size / kPoints)] == static_cast<unsigned char>(i));
-    }
-
-    p[size-1] = 'M';
-    CHECK(p[size-1] == 'M');
-  }
-
-  free(noopt(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 = noopt(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/gperftools/src/tests/tcmalloc_unittest.cc b/third_party/gperftools/src/tests/tcmalloc_unittest.cc
deleted file mode 100644
index 8ad282a..0000000
--- a/third_party/gperftools/src/tests/tcmalloc_unittest.cc
+++ /dev/null
@@ -1,1669 +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 noopt(memalign(align, noopt(size)));
-}
-static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  return noopt(posix_memalign(ptr, align, noopt(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 noopt(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(noopt(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(%zx, %zx): %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 = noopt(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 = noopt(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 = noopt(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)) {
-  func = noopt(func);
-  // 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&)) {
-  func = noopt(func);
-  // 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 = g_##hook_type##_calls + 1;                  \
-  }                                                                     \
-  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 = noopt(malloc(MB));
-  void* b = noopt(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 = noopt(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 = noopt(malloc(MB));
-  void* b = noopt(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 = noopt(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 = noopt(malloc(noopt(kTooBig)));
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  ret = noopt(calloc(1, noopt(kTooBig)));
-  EXPECT_EQ(NULL, ret);
-  EXPECT_TRUE(g_no_memory);
-
-  g_old_handler = std::set_new_handler(&OnNoMemory);
-  g_no_memory = false;
-  ret = noopt(realloc(nullptr, noopt(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 = noopt(malloc(noopt(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 = noopt(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());
-  }
-
-#ifdef ENABLE_SIZED_DELETE
-  {
-    fprintf(LOGSTREAM, "Testing large sized delete is not crashing\n");
-    // Large sized delete
-    // case. https://github.com/gperftools/gperftools/issues/1254
-    std::vector<char*> addresses;
-    constexpr int kSizedDepth = 1024;
-    addresses.reserve(kSizedDepth);
-    for (int i = 0; i < kSizedDepth; i++) {
-      addresses.push_back(noopt(new char[12686]));
-    }
-    for (int i = 0; i < kSizedDepth; i++) {
-      ::operator delete[](addresses[i], 12686);
-    }
-  }
-#endif
-
-  // 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 = noopt(valloc(60));
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    p1 = noopt(pvalloc(70));
-    CHECK(p1 != NULL);
-    VerifyNewHookWasCalled();
-    free(p1);
-    VerifyDeleteHookWasCalled();
-
-    char* p2 = noopt(new char);
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = noopt(new char[100]);
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete[] p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = noopt(new (std::nothrow) char);
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete p2;
-    VerifyDeleteHookWasCalled();
-
-    p2 = noopt(new (std::nothrow) char[100]);
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    delete[] p2;
-    VerifyDeleteHookWasCalled();
-
-    // Another way of calling operator new
-    p2 = noopt(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 = noopt(static_cast<char*>(::operator new(100, std::nothrow)));
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, std::nothrow);
-    VerifyDeleteHookWasCalled();
-
-#ifdef ENABLE_SIZED_DELETE
-    p2 = noopt(new char);
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete(p2, sizeof(char));
-    VerifyDeleteHookWasCalled();
-
-    p2 = noopt(new char[100]);
-    CHECK(p2 != NULL);
-    VerifyNewHookWasCalled();
-    ::operator delete[](p2, sizeof(char) * 100);
-    VerifyDeleteHookWasCalled();
-#endif
-
-#if defined(ENABLE_ALIGNED_NEW_DELETE)
-
-    overaligned_type* poveraligned = noopt(new overaligned_type);
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = noopt(new overaligned_type[10]);
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete[] poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = noopt(new(std::nothrow) overaligned_type);
-    CHECK(poveraligned != NULL);
-    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
-    VerifyNewHookWasCalled();
-    delete poveraligned;
-    VerifyDeleteHookWasCalled();
-
-    poveraligned = noopt(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 = noopt(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 = noopt(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 = noopt(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 = noopt(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 = noopt(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");
-  size_t old_limit;
-  CHECK(MallocExtension::instance()->GetNumericProperty("tcmalloc.heap_limit_mb", &old_limit));
-  // Don't exercise more than 1 gig, no need to.
-  CHECK(MallocExtension::instance()->SetNumericProperty("tcmalloc.heap_limit_mb", 1 << 10));
-  for (int s = 0; ; s += (10<<20)) {
-    void* large_object = rnd.alloc(s);
-    if (large_object == NULL) break;
-    free(large_object);
-  }
-  CHECK(MallocExtension::instance()->SetNumericProperty("tcmalloc.heap_limit_mb", old_limit));
-#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/gperftools/src/tests/tcmalloc_unittest.sh b/third_party/gperftools/src/tests/tcmalloc_unittest.sh
deleted file mode 100755
index 0e7996a..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/testutil.cc b/third_party/gperftools/src/tests/testutil.cc
deleted file mode 100644
index e5faa65..0000000
--- a/third_party/gperftools/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/gperftools/src/tests/testutil.h b/third_party/gperftools/src/tests/testutil.h
deleted file mode 100644
index dc1db9b..0000000
--- a/third_party/gperftools/src/tests/testutil.h
+++ /dev/null
@@ -1,73 +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();
-
-static void (* volatile noopt_helper)(void *) = +[] (void* dummy) {};
-
-// This function forces compiler to forget specific knowledge about
-// value of 'val'. This is useful to avoid compiler optimizing out
-// new/delete pairs for our unit tests.
-template <typename T>
-T noopt(T val) {
-  noopt_helper(&val);
-  return val;
-}
-
-#endif  // TCMALLOC_TOOLS_TESTUTIL_H_
diff --git a/third_party/gperftools/src/tests/thread_dealloc_unittest.cc b/third_party/gperftools/src/tests/thread_dealloc_unittest.cc
deleted file mode 100644
index 770a760..0000000
--- a/third_party/gperftools/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/gperftools/src/thread_cache.cc b/third_party/gperftools/src/thread_cache.cc
deleted file mode 100644
index 21d0f8e..0000000
--- a/third_party/gperftools/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 ATTR_INITIAL_EXEC;
-  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/gperftools/src/thread_cache.h b/third_party/gperftools/src/thread_cache.h
deleted file mode 100644
index f8be152..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/CMakeLists.txt b/third_party/gperftools/src/windows/CMakeLists.txt
deleted file mode 100644
index 2e83497..0000000
--- a/third_party/gperftools/src/windows/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_executable(addr2line-pdb addr2line-pdb.c)
-target_link_libraries(addr2line-pdb dbghelp)
-
-add_executable(nm-pdb nm-pdb.c)
-target_link_libraries(nm-pdb dbghelp)
-
-#enable_language(ASM)
-#add_executable(preamble_patcher_test preamble_patcher_test.cc shortproc.asm)
-#target_link_libraries(preamble_patcher_test tcmalloc_minimal)
-#add_test(preamble_patcher_test preamble_patcher_test)
\ No newline at end of file
diff --git a/third_party/gperftools/src/windows/TODO b/third_party/gperftools/src/windows/TODO
deleted file mode 100644
index 708ec23..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/addr2line-pdb.c b/third_party/gperftools/src/windows/addr2line-pdb.c
deleted file mode 100644
index 88d207b..0000000
--- a/third_party/gperftools/src/windows/addr2line-pdb.c
+++ /dev/null
@@ -1,183 +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: 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/gperftools/src/windows/auto_testing_hook.h b/third_party/gperftools/src/windows/auto_testing_hook.h
deleted file mode 100644
index fc2b710..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/config.h b/third_party/gperftools/src/windows/config.h
deleted file mode 100644
index bd520e4..0000000
--- a/third_party/gperftools/src/windows/config.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* 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_
-
-/* Enable aggressive decommit by default */
-/* #undef ENABLE_AGGRESSIVE_DECOMMIT_BY_DEFAULT */
-
-/* Build new/delete operators for overaligned types */
-/* #undef ENABLE_ALIGNED_NEW_DELETE */
-
-/* Build runtime detection for sized delete */
-/* #undef ENABLE_DYNAMIC_SIZED_DELETE */
-
-/* Report large allocation */
-/* #undef ENABLE_LARGE_ALLOC_REPORT */
-
-/* Build sized deletion operators */
-/* #undef ENABLE_SIZED_DELETE */
-
-/* Define to 1 if you have the <asm/ptrace.h> header file. */
-/* #undef HAVE_ASM_PTRACE_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 `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 <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 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. */
-#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. */
-/* #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/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 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 you have the `__sbrk' function. */
-/* #undef HAVE___SBRK */
-
-/* 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.9.1"
-
-/* 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.9.1"
-
-/* 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
-
-/* 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
-
-/* Define 8 bytes of allocation alignment for tcmalloc */
-/* #undef TCMALLOC_ALIGN_8BYTES */
-
-/* Define internal page size for tcmalloc as number of left bitshift */
-/* #undef TCMALLOC_PAGE_SIZE_SHIFT */
-
-/* Version number of package */
-#define VERSION "2.9.1"
-
-/* C99 says: define this to get the PRI... macros from stdint.h */
-#ifndef __STDC_FORMAT_MACROS
-# define __STDC_FORMAT_MACROS 1
-#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/gperftools/src/windows/get_mangled_names.cc b/third_party/gperftools/src/windows/get_mangled_names.cc
deleted file mode 100644
index fd6424b..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/google/tcmalloc.h b/third_party/gperftools/src/windows/google/tcmalloc.h
deleted file mode 100644
index 075482e..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/gperftools/tcmalloc.h b/third_party/gperftools/src/windows/gperftools/tcmalloc.h
deleted file mode 100644
index 5116b29..0000000
--- a/third_party/gperftools/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  9
-#define TC_VERSION_PATCH  ".1"
-#define TC_VERSION_STRING "gperftools 2.9.1"
-
-#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/gperftools/src/windows/gperftools/tcmalloc.h.in b/third_party/gperftools/src/windows/gperftools/tcmalloc.h.in
deleted file mode 100644
index adb7962..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/ia32_modrm_map.cc b/third_party/gperftools/src/windows/ia32_modrm_map.cc
deleted file mode 100644
index 817ac43..0000000
--- a/third_party/gperftools/src/windows/ia32_modrm_map.cc
+++ /dev/null
@@ -1,122 +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
- *
- * 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/gperftools/src/windows/ia32_opcode_map.cc b/third_party/gperftools/src/windows/ia32_opcode_map.cc
deleted file mode 100644
index 9d54f6b..0000000
--- a/third_party/gperftools/src/windows/ia32_opcode_map.cc
+++ /dev/null
@@ -1,1220 +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
- *
- * 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/gperftools/src/windows/mingw.h b/third_party/gperftools/src/windows/mingw.h
deleted file mode 100644
index 542f9ae..0000000
--- a/third_party/gperftools/src/windows/mingw.h
+++ /dev/null
@@ -1,72 +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
-
-// 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/gperftools/src/windows/mini_disassembler.cc b/third_party/gperftools/src/windows/mini_disassembler.cc
deleted file mode 100644
index 35d7a9d..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/mini_disassembler.h b/third_party/gperftools/src/windows/mini_disassembler.h
deleted file mode 100644
index 8b3e4ba..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/mini_disassembler_types.h b/third_party/gperftools/src/windows/mini_disassembler_types.h
deleted file mode 100644
index 97da92d..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/nm-pdb.c b/third_party/gperftools/src/windows/nm-pdb.c
deleted file mode 100644
index 9f6f431..0000000
--- a/third_party/gperftools/src/windows/nm-pdb.c
+++ /dev/null
@@ -1,274 +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: 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/gperftools/src/windows/override_functions.cc b/third_party/gperftools/src/windows/override_functions.cc
deleted file mode 100644
index 8afb851..0000000
--- a/third_party/gperftools/src/windows/override_functions.cc
+++ /dev/null
@@ -1,173 +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* old_ptr, size_t n, size_t size) {
-  // Ensure that (n * size) does not overflow
-  if (!(n == 0 || (std::numeric_limits<size_t>::max)() / n >= size)) {
-    errno = ENOMEM;
-    return NULL;
-  }
-
-  const size_t old_size = tc_malloc_size(old_ptr);
-  const size_t new_size = n * size;
-
-  void* new_ptr = realloc(old_ptr, new_size);
-
-  // If the reallocation succeeded and the new block is larger, zero-fill the
-  // new bytes:
-  if (new_ptr != NULL && new_size > old_size) {
-    memset(static_cast<char*>(new_ptr) + old_size, 0, tc_nallocx(new_size, 0) - old_size);
-  }
-
-  return new_ptr;
-}
-
-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/gperftools/src/windows/patch_functions.cc b/third_party/gperftools/src/windows/patch_functions.cc
deleted file mode 100644
index a2d0a03..0000000
--- a/third_party/gperftools/src/windows/patch_functions.cc
+++ /dev/null
@@ -1,1098 +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
-//
-// 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,
-    // Underlying deallocation functions called by CRT internal functions or operator delete
-    kFreeBase, kFreeDbg,
-    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_free_dbg(void* ptr, int block_use) __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", "_free_dbg"
-};
-
-// 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,
-  (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,
-  (GenericFnPtr)&Perftools_free_dbg
-};
-
-/*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_free_dbg(void* ptr, int block_use) __THROW {
-  MallocHook::InvokeDeleteHook(ptr);
-  // The windows _free_dbg is called if ptr isn't owned by tcmalloc.
-  if (MallocExtension::instance()->GetOwnership(ptr) == MallocExtension::kOwned) {
-    do_free(ptr);
-  } else {
-    reinterpret_cast<void (*)(void*, int)>(origstub_fn_[kFreeDbg])(ptr, block_use);
-  }
-}
-
-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/gperftools/src/windows/port.cc b/third_party/gperftools/src/windows/port.cc
deleted file mode 100644
index e73c508..0000000
--- a/third_party/gperftools/src/windows/port.cc
+++ /dev/null
@@ -1,249 +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 https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
-// and http://lallouslab.net/2017/05/30/using-cc-tls-callbacks-in-visual-studio-with-your-32-or-64bits-programs/.
-// 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.
-// Note that for some unknown reason, the extern "C" {} construct is ignored
-// by the MSVC VS2017 compiler (at least) when a const modifier is used
-#if defined(_M_IX86)
-extern "C" {
-// In x86, the PE loader looks for callbacks in a data segment
-#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"
-#elif defined(_M_X64)
-// In x64, the PE loader looks for callbacks in a constant segment
-#pragma const_seg(push, oldseg)
-#pragma const_seg(".CRT$XLB")
-extern "C" void (NTAPI * const p_thread_callback_tcmalloc)(
-	HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;
-#pragma const_seg(".CRT$XTU")
-extern "C" int (NTAPI * const p_process_term_tcmalloc)(void) = on_process_term;
-#pragma const_seg(pop, oldseg)
-#endif
-
-#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/gperftools/src/windows/port.h b/third_party/gperftools/src/windows/port.h
deleted file mode 100644
index 29c6cb9..0000000
--- a/third_party/gperftools/src/windows/port.h
+++ /dev/null
@@ -1,477 +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
-# error  Do not know how to set up type aliases.  Edit port.h for your system.
-#endif
-
-/* 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_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/gperftools/src/windows/preamble_patcher.cc b/third_party/gperftools/src/windows/preamble_patcher.cc
deleted file mode 100644
index 5b5fc35..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/preamble_patcher.h b/third_party/gperftools/src/windows/preamble_patcher.h
deleted file mode 100644
index 701e570..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/preamble_patcher_test.cc b/third_party/gperftools/src/windows/preamble_patcher_test.cc
deleted file mode 100644
index f3e0511..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/preamble_patcher_with_stub.cc b/third_party/gperftools/src/windows/preamble_patcher_with_stub.cc
deleted file mode 100644
index d2c896c..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/shortproc.asm b/third_party/gperftools/src/windows/shortproc.asm
deleted file mode 100644
index 7e8e3d7..0000000
--- a/third_party/gperftools/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/gperftools/src/windows/system-alloc.cc b/third_party/gperftools/src/windows/system-alloc.cc
deleted file mode 100644
index bdd0392..0000000
--- a/third_party/gperftools/src/windows/system-alloc.cc
+++ /dev/null
@@ -1,205 +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: 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/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj b/third_party/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj
deleted file mode 100644
index 4801616..0000000
--- a/third_party/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj
+++ /dev/null
@@ -1,191 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{81CA712E-90B8-4AE5-9E89-5B436578D6DA}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" />

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\windows\addr2line-pdb.c" />

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj.filters b/third_party/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj.filters
deleted file mode 100644
index 589e6c2..0000000
--- a/third_party/gperftools/vsprojects/addr2line-pdb/addr2line-pdb.vcxproj.filters
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\windows\addr2line-pdb.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj b/third_party/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj
deleted file mode 100644
index de44f74..0000000
--- a/third_party/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj
+++ /dev/null
@@ -1,229 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{32EECEB6-7D18-477E-BC7A-30CE98457A88}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c" />

-    <ClCompile Include="..\..\src\base\logging.cc" />

-    <ClCompile Include="..\..\src\base\spinlock.cc" />

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc" />

-    <ClCompile Include="..\..\src\base\sysinfo.cc" />

-    <ClCompile Include="..\..\src\tests\addressmap_unittest.cc" />

-    <ClCompile Include="..\..\src\windows\port.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\addressmap-inl.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h" />

-    <ClInclude Include="..\..\src\base\atomicops.h" />

-    <ClInclude Include="..\..\src\base\basictypes.h" />

-    <ClInclude Include="..\..\src\base\commandlineflags.h" />

-    <ClInclude Include="..\..\src\base\dynamic_annotations.h" />

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\base\spinlock.h" />

-    <ClInclude Include="..\..\src\base\spinlock_internal.h" />

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj.filters
deleted file mode 100644
index a4c6f43..0000000
--- a/third_party/gperftools/vsprojects/addressmap_unittest/addressmap_unittest.vcxproj.filters
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\addressmap_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\sysinfo.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\logging.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\port.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\addressmap-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\basictypes.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\commandlineflags.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_internal.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\dynamic_annotations.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj b/third_party/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj
deleted file mode 100644
index be6ebcf..0000000
--- a/third_party/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{4AFFF21D-9D0A-410C-A7DB-7D21DA5166C0}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\current_allocated_bytes_test.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_extension.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj.filters b/third_party/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj.filters
deleted file mode 100644
index 1ee4b1b..0000000
--- a/third_party/gperftools/vsprojects/current_allocated_bytes_test/current_allocated_bytes_test.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\current_allocated_bytes_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\malloc_extension.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj b/third_party/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj
deleted file mode 100644
index d463582..0000000
--- a/third_party/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj
+++ /dev/null
@@ -1,213 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{24754725-DE0D-4214-8979-324247AAD78E}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\frag_unittest.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj.filters
deleted file mode 100644
index 5d66aef..0000000
--- a/third_party/gperftools/vsprojects/frag_unittest/frag_unittest.vcxproj.filters
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\frag_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj b/third_party/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj
deleted file mode 100644
index 1bd87bc..0000000
--- a/third_party/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj
+++ /dev/null
@@ -1,297 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>StaticLibrary</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>StaticLibrary</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Windows</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Windows</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Windows</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>WIN32_OVERRIDE_ALLOCATORS;PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Windows</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Windows</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>WIN32_OVERRIDE_ALLOCATORS;PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Windows</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c" />

-    <ClCompile Include="..\..\src\base\logging.cc" />

-    <ClCompile Include="..\..\src\base\low_level_alloc.cc" />

-    <ClCompile Include="..\..\src\base\spinlock.cc" />

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc" />

-    <ClCompile Include="..\..\src\base\sysinfo.cc" />

-    <ClCompile Include="..\..\src\central_freelist.cc" />

-    <ClCompile Include="..\..\src\common.cc" />

-    <ClCompile Include="..\..\src\fake_stacktrace_scope.cc" />

-    <ClCompile Include="..\..\src\heap-profile-table.cc" />

-    <ClCompile Include="..\..\src\internal_logging.cc" />

-    <ClCompile Include="..\..\src\malloc_extension.cc" />

-    <ClCompile Include="..\..\src\malloc_hook.cc" />

-    <ClCompile Include="..\..\src\memory_region_map.cc" />

-    <ClCompile Include="..\..\src\page_heap.cc" />

-    <ClCompile Include="..\..\src\raw_printer.cc" />

-    <ClCompile Include="..\..\src\sampler.cc" />

-    <ClCompile Include="..\..\src\span.cc" />

-    <ClCompile Include="..\..\src\stacktrace.cc" />

-    <ClCompile Include="..\..\src\stack_trace_table.cc" />

-    <ClCompile Include="..\..\src\static_vars.cc" />

-    <ClCompile Include="..\..\src\symbolize.cc" />

-    <ClCompile Include="..\..\src\thread_cache.cc" />

-    <ClCompile Include="..\..\src\windows\ia32_modrm_map.cc" />

-    <ClCompile Include="..\..\src\windows\ia32_opcode_map.cc" />

-    <ClCompile Include="..\..\src\windows\mini_disassembler.cc" />

-    <ClCompile Include="..\..\src\windows\override_functions.cc">

-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">true</ExcludedFromBuild>

-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">true</ExcludedFromBuild>

-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>

-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\patch_functions.cc">

-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">true</ExcludedFromBuild>

-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">true</ExcludedFromBuild>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\port.cc" />

-    <ClCompile Include="..\..\src\windows\preamble_patcher.cc" />

-    <ClCompile Include="..\..\src\windows\preamble_patcher_with_stub.cc" />

-    <ClCompile Include="..\..\src\windows\system-alloc.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\addressmap-inl.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h" />

-    <ClInclude Include="..\..\src\base\atomicops.h" />

-    <ClInclude Include="..\..\src\base\basictypes.h" />

-    <ClInclude Include="..\..\src\base\commandlineflags.h" />

-    <ClInclude Include="..\..\src\base\googleinit.h" />

-    <ClInclude Include="..\..\src\base\linked_list.h" />

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\base\low_level_alloc.h" />

-    <ClInclude Include="..\..\src\base\mutex.h" />

-    <ClInclude Include="..\..\src\base\spinlock.h" />

-    <ClInclude Include="..\..\src\base\spinlock_internal.h" />

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h" />

-    <ClInclude Include="..\..\src\base\stl_allocator.h" />

-    <ClInclude Include="..\..\src\base\sysinfo.h" />

-    <ClInclude Include="..\..\src\base\thread_annotations.h" />

-    <ClInclude Include="..\..\src\central_freelist.h" />

-    <ClInclude Include="..\..\src\common.h" />

-    <ClInclude Include="..\..\src\gperftools\heap-checker.h" />

-    <ClInclude Include="..\..\src\gperftools\heap-profiler.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_extension.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_hook.h" />

-    <ClInclude Include="..\..\src\gperftools\profiler.h" />

-    <ClInclude Include="..\..\src\gperftools\stacktrace.h" />

-    <ClInclude Include="..\..\src\heap-profile-table.h" />

-    <ClInclude Include="..\..\src\internal_logging.h" />

-    <ClInclude Include="..\..\src\malloc_hook-inl.h" />

-    <ClInclude Include="..\..\src\memory_region_map.h" />

-    <ClInclude Include="..\..\src\packed-cache-inl.h" />

-    <ClInclude Include="..\..\src\pagemap.h" />

-    <ClInclude Include="..\..\src\page_heap.h" />

-    <ClInclude Include="..\..\src\page_heap_allocator.h" />

-    <ClInclude Include="..\..\src\raw_printer.h" />

-    <ClInclude Include="..\..\src\sampler.h" />

-    <ClInclude Include="..\..\src\span.h" />

-    <ClInclude Include="..\..\src\stacktrace_config.h" />

-    <ClInclude Include="..\..\src\stacktrace_win32-inl.h" />

-    <ClInclude Include="..\..\src\stack_trace_table.h" />

-    <ClInclude Include="..\..\src\static_vars.h" />

-    <ClInclude Include="..\..\src\symbolize.h" />

-    <ClInclude Include="..\..\src\system-alloc.h" />

-    <ClInclude Include="..\..\src\tcmalloc.h" />

-    <ClInclude Include="..\..\src\thread_cache.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\mini_disassembler.h" />

-    <ClInclude Include="..\..\src\windows\mini_disassembler_types.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-    <ClInclude Include="..\..\src\windows\preamble_patcher.h" />

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj.filters b/third_party/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj.filters
deleted file mode 100644
index ac8fcbf..0000000
--- a/third_party/gperftools/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj.filters
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\central_freelist.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\heap-profile-table.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\symbolize.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\ia32_modrm_map.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\ia32_opcode_map.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\common.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\internal_logging.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\logging.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\low_level_alloc.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\malloc_extension.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\malloc_hook.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\memory_region_map.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\mini_disassembler.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\page_heap.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\sampler.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\patch_functions.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\port.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\preamble_patcher.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\preamble_patcher_with_stub.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\system-alloc.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\raw_printer.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\span.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\stacktrace.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\stack_trace_table.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\static_vars.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\sysinfo.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\thread_cache.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\fake_stacktrace_scope.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\override_functions.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\addressmap-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\basictypes.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\central_freelist.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\commandlineflags.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\googleinit.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\heap-checker.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\heap-profile-table.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\symbolize.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\heap-profiler.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\common.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\internal_logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\linked_list.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\low_level_alloc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_internal.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\malloc_extension.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\malloc_hook.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\malloc_hook-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\memory_region_map.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\mini_disassembler.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\mini_disassembler_types.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\mutex.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\packed-cache-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\page_heap.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\page_heap_allocator.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\pagemap.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\preamble_patcher.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\profiler.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\raw_printer.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\sampler.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\span.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\stacktrace.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\stacktrace_config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\stacktrace_win32-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\stack_trace_table.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\static_vars.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\stl_allocator.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\sysinfo.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\system-alloc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\tcmalloc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\thread_annotations.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\thread_cache.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj b/third_party/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj
deleted file mode 100644
index 8f1a22b..0000000
--- a/third_party/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj
+++ /dev/null
@@ -1,238 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{A765198D-5305-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c" />

-    <ClCompile Include="..\..\src\base\logging.cc" />

-    <ClCompile Include="..\..\src\base\low_level_alloc.cc" />

-    <ClCompile Include="..\..\src\base\spinlock.cc" />

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc" />

-    <ClCompile Include="..\..\src\base\sysinfo.cc" />

-    <ClCompile Include="..\..\src\fake_stacktrace_scope.cc" />

-    <ClCompile Include="..\..\src\malloc_hook.cc" />

-    <ClCompile Include="..\..\src\stacktrace.cc" />

-    <ClCompile Include="..\..\src\tests\low_level_alloc_unittest.cc" />

-    <ClCompile Include="..\..\src\windows\port.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h" />

-    <ClInclude Include="..\..\src\base\atomicops.h" />

-    <ClInclude Include="..\..\src\base\basictypes.h" />

-    <ClInclude Include="..\..\src\base\commandlineflags.h" />

-    <ClInclude Include="..\..\src\base\dynamic_annotations.h" />

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\base\low_level_alloc.h" />

-    <ClInclude Include="..\..\src\base\spinlock.h" />

-    <ClInclude Include="..\..\src\base\spinlock_internal.h" />

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_hook.h" />

-    <ClInclude Include="..\..\src\gperftools\stacktrace.h" />

-    <ClInclude Include="..\..\src\gperftools\stacktrace_config.h" />

-    <ClInclude Include="..\..\src\malloc_hook-inl.h" />

-    <ClInclude Include="..\..\src\stacktrace_win32-inl.h.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj.filters
deleted file mode 100644
index eadf769..0000000
--- a/third_party/gperftools/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcxproj.filters
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\sysinfo.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\logging.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\low_level_alloc.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\low_level_alloc_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\malloc_hook.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\port.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\stacktrace.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\fake_stacktrace_scope.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\basictypes.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\commandlineflags.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_internal.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\dynamic_annotations.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\low_level_alloc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\malloc_hook.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\malloc_hook-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\stacktrace_win32-inl.h.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\stacktrace.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\stacktrace_config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj b/third_party/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj
deleted file mode 100644
index e1a8918..0000000
--- a/third_party/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj
+++ /dev/null
@@ -1,216 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{3765198D-5305-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\malloc_extension_test.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_extension.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_extension_c.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj.filters b/third_party/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj.filters
deleted file mode 100644
index e8b9814..0000000
--- a/third_party/gperftools/vsprojects/malloc_extension_test/malloc_extension_test.vcxproj.filters
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{3FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{33995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\malloc_extension_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\gperftools\malloc_extension.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\gperftools\malloc_extension_c.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj b/third_party/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj
deleted file mode 100644
index 8cfbf7a..0000000
--- a/third_party/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj
+++ /dev/null
@@ -1,217 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{3765198D-AA05-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\malloc_hook_test.cc" />

-    <ClCompile Include="..\..\src\tests\testutil.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\gperftools\malloc_hook.h" />

-    <ClInclude Include="..\..\src\tests\testutil.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj.filters b/third_party/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj.filters
deleted file mode 100644
index 8d1b9c1..0000000
--- a/third_party/gperftools/vsprojects/malloc_hook_test/malloc_hook_test.vcxproj.filters
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{3FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{33995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\malloc_hook_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\testutil.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\gperftools\malloc_hook.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\tests\testutil.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj b/third_party/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj
deleted file mode 100644
index 6294d56..0000000
--- a/third_party/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\markidle_unittest.cc" />

-    <ClCompile Include="..\..\src\tests\testutil.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\tests\testutil.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj.filters
deleted file mode 100644
index 4f9f86d..0000000
--- a/third_party/gperftools/vsprojects/markidle_unittest/markidle_unittest.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\markidle_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\testutil.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\tests\testutil.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj b/third_party/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj
deleted file mode 100644
index ac6caeb..0000000
--- a/third_party/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj
+++ /dev/null
@@ -1,191 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{3A559C75-FD26-4300-B86B-165FD43EE1CE}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" />

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\windows\nm-pdb.c" />

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj.filters b/third_party/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj.filters
deleted file mode 100644
index b06158c..0000000
--- a/third_party/gperftools/vsprojects/nm-pdb/nm-pdb.vcxproj.filters
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\windows\nm-pdb.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj b/third_party/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj
deleted file mode 100644
index 9f57d19..0000000
--- a/third_party/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj
+++ /dev/null
@@ -1,229 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{605D3CED-B530-424E-B7D2-2A31F14FD570}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\packed-cache_test.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h" />

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h" />

-    <ClInclude Include="..\..\src\base\atomicops.h" />

-    <ClInclude Include="..\..\src\base\basictypes.h" />

-    <ClInclude Include="..\..\src\base\commandlineflags.h" />

-    <ClInclude Include="..\..\src\base\dynamic_annotations.h" />

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\base\spinlock.h" />

-    <ClInclude Include="..\..\src\base\spinlock_internal.h" />

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h" />

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\packed-cache-inl.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj.filters b/third_party/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj.filters
deleted file mode 100644
index b3dc1ed..0000000
--- a/third_party/gperftools/vsprojects/packed-cache_test/packed-cache_test.vcxproj.filters
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\packed-cache_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-arm-gcc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-linuxppc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-macosx.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86-msvc.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops-internals-x86.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\atomicops.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_internal.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_linux-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_posix-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\spinlock_win32-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\basictypes.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\commandlineflags.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\dynamic_annotations.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\packed-cache-inl.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj b/third_party/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj
deleted file mode 100644
index 8503a0d..0000000
--- a/third_party/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj
+++ /dev/null
@@ -1,229 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{9765198D-5305-4AB0-9A21-A0CD8201EB2B}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c" />

-    <ClCompile Include="..\..\src\base\logging.cc" />

-    <ClCompile Include="..\..\src\base\low_level_alloc.cc" />

-    <ClCompile Include="..\..\src\base\spinlock.cc" />

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc" />

-    <ClCompile Include="..\..\src\base\sysinfo.cc" />

-    <ClCompile Include="..\..\src\central_freelist.cc" />

-    <ClCompile Include="..\..\src\common.cc" />

-    <ClCompile Include="..\..\src\fake_stacktrace_scope.cc" />

-    <ClCompile Include="..\..\src\internal_logging.cc" />

-    <ClCompile Include="..\..\src\malloc_extension.cc" />

-    <ClCompile Include="..\..\src\malloc_hook.cc" />

-    <ClCompile Include="..\..\src\page_heap.cc" />

-    <ClCompile Include="..\..\src\raw_printer.cc" />

-    <ClCompile Include="..\..\src\sampler.cc" />

-    <ClCompile Include="..\..\src\span.cc" />

-    <ClCompile Include="..\..\src\stack_trace_table.cc" />

-    <ClCompile Include="..\..\src\stacktrace.cc" />

-    <ClCompile Include="..\..\src\static_vars.cc" />

-    <ClCompile Include="..\..\src\symbolize.cc" />

-    <ClCompile Include="..\..\src\tests\page_heap_test.cc" />

-    <ClCompile Include="..\..\src\thread_cache.cc" />

-    <ClCompile Include="..\..\src\windows\port.cc" />

-    <ClCompile Include="..\..\src\windows\system-alloc.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\common.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\page_heap.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>

diff --git a/third_party/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj.filters b/third_party/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj.filters
deleted file mode 100644
index 2b8c023..0000000
--- a/third_party/gperftools/vsprojects/page_heap_test/page_heap_test.vcxproj.filters
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{9FC737F1-C7A5-4376-A066-2A32D752A2FE}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFE}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\base\dynamic_annotations.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\logging.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\low_level_alloc.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\spinlock_internal.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\base\sysinfo.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\central_freelist.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\common.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\fake_stacktrace_scope.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\internal_logging.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\malloc_extension.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\malloc_hook.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\page_heap.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\raw_printer.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\sampler.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\span.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\stack_trace_table.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\stacktrace.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\static_vars.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\symbolize.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\page_heap_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\thread_cache.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\port.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\windows\system-alloc.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\page_heap.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\common.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>

diff --git a/third_party/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj b/third_party/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj
deleted file mode 100644
index e5f267c..0000000
--- a/third_party/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{9765198D-5305-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\pagemap_unittest.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\pagemap.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj.filters
deleted file mode 100644
index e16fc13..0000000
--- a/third_party/gperftools/vsprojects/pagemap_unittest/pagemap_unittest.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{9FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\pagemap_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\pagemap.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj b/third_party/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj
deleted file mode 100644
index cf3daad..0000000
--- a/third_party/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj
+++ /dev/null
@@ -1,234 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{5765198D-5305-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\windows\preamble_patcher_test.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <CustomBuild Include="..\..\src\windows\shortproc.asm">

-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml64 /Fo"$(OutDir)%(Filename).obj"  /c /Cx /coff "%(FullPath)"</Command>

-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64 /Fo"$(OutDir)%(Filename).obj"  /c /Cx /coff "%(FullPath)"</Command>

-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)%(Filename).obj;%(Outputs)</Outputs>

-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)%(Filename).obj;%(Outputs)</Outputs>

-      <Command Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">ml64 /Fo"$(OutDir)%(Filename).obj"  /c /Cx /coff "%(FullPath)"</Command>

-      <Command Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">ml64 /Fo"$(OutDir)%(Filename).obj"  /c /Cx /coff "%(FullPath)"</Command>

-      <Command Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">ml64 /Fo"$(OutDir)%(Filename).obj"  /c /Cx /coff "%(FullPath)"</Command>

-      <Command Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">ml64 /Fo"$(OutDir)%(Filename).obj"  /c /Cx /coff "%(FullPath)"</Command>

-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">$(OutDir)%(Filename).obj;%(Outputs)</Outputs>

-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">$(OutDir)%(Filename).obj;%(Outputs)</Outputs>

-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">$(OutDir)%(Filename).obj;%(Outputs)</Outputs>

-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">$(OutDir)%(Filename).obj;%(Outputs)</Outputs>

-    </CustomBuild>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\basictypes.h" />

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\windows\auto_testing_hook.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\mini_disassembler.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-    <ClInclude Include="..\..\src\windows\preamble_patcher.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj.filters b/third_party/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj.filters
deleted file mode 100644
index 63ab7e5..0000000
--- a/third_party/gperftools/vsprojects/preamble_patcher_test/preamble_patcher_test.vcxproj.filters
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{3FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{33995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\windows\preamble_patcher_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\preamble_patcher.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\mini_disassembler.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\auto_testing_hook.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\basictypes.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-  <ItemGroup>

-    <CustomBuild Include="..\..\src\windows\shortproc.asm">

-      <Filter>Source Files</Filter>

-    </CustomBuild>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj b/third_party/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj
deleted file mode 100644
index e16c02f..0000000
--- a/third_party/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj
+++ /dev/null
@@ -1,214 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{4765198D-5305-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\realloc_unittest.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj.filters
deleted file mode 100644
index 96b419e..0000000
--- a/third_party/gperftools/vsprojects/realloc_unittest/realloc_unittest.vcxproj.filters
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{43995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\realloc_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/sampler_test/sampler_test.vcxproj b/third_party/gperftools/vsprojects/sampler_test/sampler_test.vcxproj
deleted file mode 100644
index 98d6bb4..0000000
--- a/third_party/gperftools/vsprojects/sampler_test/sampler_test.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{B765198D-5305-4AB0-9A21-A0CD8201EB2A}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\sampler_test.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\commandlineflags.h" />

-    <ClInclude Include="..\..\src\base\logging.h" />

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/sampler_test/sampler_test.vcxproj.filters b/third_party/gperftools/vsprojects/sampler_test/sampler_test.vcxproj.filters
deleted file mode 100644
index faf8c0a..0000000
--- a/third_party/gperftools/vsprojects/sampler_test/sampler_test.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{BFC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{B3995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\sampler_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\base\commandlineflags.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\base\logging.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj b/third_party/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj
deleted file mode 100644
index 23de726..0000000
--- a/third_party/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj
+++ /dev/null
@@ -1,214 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{A4754725-DE0D-4214-8979-324247AAD78E}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\stack_trace_table_test.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\stack_trace_table.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj.filters b/third_party/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj.filters
deleted file mode 100644
index df2be8c..0000000
--- a/third_party/gperftools/vsprojects/stack_trace_table_test/stack_trace_table_test.vcxproj.filters
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{AFC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{A3995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\stack_trace_table_test.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\stack_trace_table.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj b/third_party/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj
deleted file mode 100644
index a6dca2b..0000000
--- a/third_party/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{387F753A-0312-4A7B-A1D6-B2795E832E96}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\system-alloc_unittest.cc" />

-    <ClCompile Include="..\..\src\tests\testutil.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\tests\testutil.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj.filters
deleted file mode 100644
index a26e4de..0000000
--- a/third_party/gperftools/vsprojects/system-alloc_unittest/system-alloc_unittest.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\system-alloc_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\testutil.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\tests\testutil.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj b/third_party/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj
deleted file mode 100644
index dd0f686..0000000
--- a/third_party/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj
+++ /dev/null
@@ -1,213 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{2D8B9599-C74C-4298-B723-6CF6077563E3}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\tcmalloc_large_unittest.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj.filters
deleted file mode 100644
index c15df06..0000000
--- a/third_party/gperftools/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcxproj.filters
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\tcmalloc_large_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj b/third_party/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj
deleted file mode 100644
index 96689ff..0000000
--- a/third_party/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{7CC73D97-C057-43A6-82EF-E6B567488D02}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\tcmalloc_unittest.cc" />

-    <ClCompile Include="..\..\src\tests\testutil.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\tests\testutil.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj.filters
deleted file mode 100644
index edeed06..0000000
--- a/third_party/gperftools/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\tcmalloc_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\testutil.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\tests\testutil.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj b/third_party/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj
deleted file mode 100644
index 41f31c1..0000000
--- a/third_party/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|Win32">

-      <Configuration>Release-Override</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Override|x64">

-      <Configuration>Release-Override</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|Win32">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release-Patch|x64">

-      <Configuration>Release-Patch</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <UseNativeEnvironment>true</UseNativeEnvironment>

-    <ProjectGuid>{6CFFBD0F-09E3-4282-A711-0564451FDF74}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <PlatformToolset>v140</PlatformToolset>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup>

-    <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <IncludePath>..\..\src\windows;..\..\src;$(IncludePath)</IncludePath>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|Win32'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Patch|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <ForceSymbolReferences>__tcmalloc;%(ForceSymbolReferences)</ForceSymbolReferences>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Override|x64'">

-    <ClCompile>

-      <PreprocessorDefinitions>PERFTOOLS_DLL_DECL=;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <WarningLevel>Level3</WarningLevel>

-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

-      <BufferSecurityCheck>false</BufferSecurityCheck>

-      <EnforceTypeConversionRules>true</EnforceTypeConversionRules>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <OptimizeReferences>true</OptimizeReferences>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\testutil.cc" />

-    <ClCompile Include="..\..\src\tests\thread_dealloc_unittest.cc" />

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\config_for_unittests.h" />

-    <ClInclude Include="..\..\src\tests\testutil.h" />

-    <ClInclude Include="..\..\src\windows\config.h" />

-    <ClInclude Include="..\..\src\windows\port.h" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="..\libtcmalloc_minimal\libtcmalloc_minimal.vcxproj">

-      <Project>{55e2b3ae-3ca1-4db6-97f7-0a044d6f446f}</Project>

-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>

-    </ProjectReference>

-  </ItemGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>
\ No newline at end of file
diff --git a/third_party/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj.filters b/third_party/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj.filters
deleted file mode 100644
index c8d0f6d..0000000
--- a/third_party/gperftools/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup>

-    <Filter Include="Source Files">

-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

-      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

-    </Filter>

-    <Filter Include="Header Files">

-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

-    </Filter>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\src\tests\testutil.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-    <ClCompile Include="..\..\src\tests\thread_dealloc_unittest.cc">

-      <Filter>Source Files</Filter>

-    </ClCompile>

-  </ItemGroup>

-  <ItemGroup>

-    <ClInclude Include="..\..\src\windows\config.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\config_for_unittests.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\windows\port.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-    <ClInclude Include="..\..\src\tests\testutil.h">

-      <Filter>Header Files</Filter>

-    </ClInclude>

-  </ItemGroup>

-</Project>
\ No newline at end of file
diff --git a/tools/ci/buildkite.yaml b/tools/ci/buildkite.yaml
index be3cb07..afb565a 100644
--- a/tools/ci/buildkite.yaml
+++ b/tools/ci/buildkite.yaml
@@ -1,7 +1,7 @@
 env:
   STARTUP: --max_idle_secs=0
   COMMON: -c opt --stamp=no --curses=yes --symlink_prefix=/ --remote_cache=grpc://data-fast:9092 --repo_env=FRC971_RUNNING_IN_CI=1 --repository_cache=~/.cache/bazel_repository --experimental_repository_cache_hardlinks=true
-  TARGETS: //... @com_github_google_glog//... @com_google_ceres_solver//... @com_github_rawrtc_rawrtc//... @com_google_googletest//... @symengine//...
+  TARGETS: //... @com_google_absl//... @com_google_ceres_solver//... @com_github_rawrtc_rawrtc//... @com_google_googletest//... @symengine//...
   M4F_TARGETS: //...
   RP2040_TARGETS: //...
   # Sanity check that we are able to build the y2020 roborio code, which confirms
@@ -19,7 +19,7 @@
   - label: "x86_64"
     commands:
       - tools/ci/clean-disk.sh
-      - tools/bazel ${STARTUP} --output_base=../k8_output_base test ${COMMON} --config=k8 --config=eigen ${TARGETS}
+      - tools/bazel ${STARTUP} --output_base=../k8_output_base test ${COMMON} --config=k8 --config=eigen ${TARGETS} -- -@com_google_absl//absl/time:time_benchmark -@com_google_absl//absl/time:time_test -@com_google_absl//absl/time/internal/cctz:time_zone_format_test -@com_google_absl//absl/time/internal/cctz:time_zone_lookup_test
     agents:
       queue: "gpu"
 
diff --git a/tools/cpp/BUILD b/tools/cpp/BUILD
index 5b43edc..2619ff7 100644
--- a/tools/cpp/BUILD
+++ b/tools/cpp/BUILD
@@ -37,7 +37,9 @@
         "//tools:cpu_cortex_m0plus": [],
         # TODO(phil): Support this properly.
         #"//tools:cpu_cortex_m4f_k22": [],
-        "//conditions:default": ["//third_party/gperftools:tcmalloc"],
+        "//conditions:default": [],
+        # TODO(austin): Figure out how to make malloc hooks work with the new tcmalloc...
+        #"//conditions:default": ["@com_google_tcmalloc//tcmalloc"],
     }),
 )
 
diff --git a/y2014/BUILD b/y2014/BUILD
index c4e419f..8c22d28 100644
--- a/y2014/BUILD
+++ b/y2014/BUILD
@@ -17,8 +17,9 @@
         "//frc971:shifter_hall_effect",
         "//frc971/control_loops:state_feedback_loop",
         "//y2014/control_loops/drivetrain:polydrivetrain_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2014/constants.cc b/y2014/constants.cc
index 5ff44d4..792fc69 100644
--- a/y2014/constants.cc
+++ b/y2014/constants.cc
@@ -10,7 +10,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
diff --git a/y2016/BUILD b/y2016/BUILD
index 849f0f6..9c27142 100644
--- a/y2016/BUILD
+++ b/y2016/BUILD
@@ -18,8 +18,9 @@
         "//frc971:shifter_hall_effect",
         "//frc971/control_loops:state_feedback_loop",
         "//y2016/control_loops/drivetrain:polydrivetrain_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2016/constants.cc b/y2016/constants.cc
index 0c65b11..ec17afb 100644
--- a/y2016/constants.cc
+++ b/y2016/constants.cc
@@ -10,7 +10,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
diff --git a/y2017/BUILD b/y2017/BUILD
index aeb4d67..ade83c5 100644
--- a/y2017/BUILD
+++ b/y2017/BUILD
@@ -21,8 +21,9 @@
         "//y2017/control_loops/superstructure/hood:hood_plants",
         "//y2017/control_loops/superstructure/intake:intake_plants",
         "//y2017/control_loops/superstructure/shooter:shooter_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2017/constants.cc b/y2017/constants.cc
index d599772..e67c018 100644
--- a/y2017/constants.cc
+++ b/y2017/constants.cc
@@ -10,7 +10,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
diff --git a/y2017/control_loops/superstructure/column/column_zeroing_test.cc b/y2017/control_loops/superstructure/column/column_zeroing_test.cc
index 2edcab2..008dcd7 100644
--- a/y2017/control_loops/superstructure/column/column_zeroing_test.cc
+++ b/y2017/control_loops/superstructure/column/column_zeroing_test.cc
@@ -5,7 +5,8 @@
 #include <memory>
 #include <random>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/die.h"
diff --git a/y2018/BUILD b/y2018/BUILD
index 129cd84..a17df89 100644
--- a/y2018/BUILD
+++ b/y2018/BUILD
@@ -63,7 +63,8 @@
         "//y2018/control_loops/drivetrain:polydrivetrain_plants",
         "//y2018/control_loops/superstructure/arm:arm_constants",
         "//y2018/control_loops/superstructure/intake:intake_plants",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2018/constants.cc b/y2018/constants.cc
index 41c8f3a..d12b9b5 100644
--- a/y2018/constants.cc
+++ b/y2018/constants.cc
@@ -9,7 +9,8 @@
 #include "sanitizer/lsan_interface.h"
 #endif
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
diff --git a/y2018/control_loops/python/2d_plot.cc b/y2018/control_loops/python/2d_plot.cc
index 1d2a686..c65bae6 100644
--- a/y2018/control_loops/python/2d_plot.cc
+++ b/y2018/control_loops/python/2d_plot.cc
@@ -2,17 +2,18 @@
 #include <cmath>
 #include <thread>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
 #include "third_party/matplotlib-cpp/matplotlibcpp.h"
 
-DEFINE_double(yrange, 1.0, "+- y max");
+ABSL_FLAG(double, yrange, 1.0, "+- y max");
 
 double fx(double x, double yrange) {
   return 2.0 * ((1.0 / (1.0 + ::std::exp(-x * 2.0 / yrange)) - 0.5)) * yrange;
 }
 
 int main(int argc, char **argv) {
-  gflags::ParseCommandLineFlags(&argc, &argv, false);
+  absl::ParseCommandLine(argc, argv);
 
   matplotlibcpp::figure();
   ::std::vector<double> x;
@@ -21,10 +22,10 @@
 
   for (double i = -5.0; i < 5.0; i += 0.01) {
     x.push_back(i);
-    y.push_back(fx(i, FLAGS_yrange));
-    slope_y.push_back(
-        (fx(i + 0.0001, FLAGS_yrange) - fx(i - 0.0001, FLAGS_yrange)) /
-        (2.0 * 0.0001));
+    y.push_back(fx(i, absl::GetFlag(FLAGS_yrange)));
+    slope_y.push_back((fx(i + 0.0001, absl::GetFlag(FLAGS_yrange)) -
+                       fx(i - 0.0001, absl::GetFlag(FLAGS_yrange))) /
+                      (2.0 * 0.0001));
   }
 
   matplotlibcpp::plot(x, y, {{"label", "saturated x"}});
diff --git a/y2018/control_loops/python/BUILD b/y2018/control_loops/python/BUILD
index fcedf40..d286ce0 100644
--- a/y2018/control_loops/python/BUILD
+++ b/y2018/control_loops/python/BUILD
@@ -107,7 +107,8 @@
     target_compatible_with = ["@platforms//cpu:x86_64"],
     deps = [
         "//third_party/matplotlib-cpp",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/flags:parse",
     ],
 )
 
diff --git a/y2018/control_loops/superstructure/arm/BUILD b/y2018/control_loops/superstructure/arm/BUILD
index 319e591..495e214 100644
--- a/y2018/control_loops/superstructure/arm/BUILD
+++ b/y2018/control_loops/superstructure/arm/BUILD
@@ -76,7 +76,7 @@
         "//aos/analysis:in_process_plotter",
         "//frc971/control_loops/double_jointed_arm:ekf",
         "//frc971/control_loops/double_jointed_arm:trajectory",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
diff --git a/y2018/control_loops/superstructure/arm/trajectory_plot.cc b/y2018/control_loops/superstructure/arm/trajectory_plot.cc
index eeb0fbc..1811b95 100644
--- a/y2018/control_loops/superstructure/arm/trajectory_plot.cc
+++ b/y2018/control_loops/superstructure/arm/trajectory_plot.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/analysis/in_process_plotter.h"
 #include "aos/init.h"
@@ -8,9 +8,9 @@
 #include "y2018/control_loops/superstructure/arm/arm_constants.h"
 #include "y2018/control_loops/superstructure/arm/generated_graph.h"
 
-DEFINE_bool(forwards, true, "If true, run the forwards simulation.");
-DEFINE_bool(plot, true, "If true, plot");
-DEFINE_bool(plot_thetas, true, "If true, plot the angles");
+ABSL_FLAG(bool, forwards, true, "If true, run the forwards simulation.");
+ABSL_FLAG(bool, plot, true, "If true, plot");
+ABSL_FLAG(bool, plot_thetas, true, "If true, plot the angles");
 
 namespace y2018::control_loops::superstructure::arm {
 
@@ -18,8 +18,9 @@
   frc971::control_loops::arm::Dynamics dynamics(kArmConstants);
   frc971::control_loops::arm::Trajectory trajectory(
       &dynamics,
-      FLAGS_forwards ? MakeNeutralToFrontHighPath()
-                     : Path::Reversed(MakeNeutralToFrontHighPath()),
+      absl::GetFlag(FLAGS_forwards)
+          ? MakeNeutralToFrontHighPath()
+          : Path::Reversed(MakeNeutralToFrontHighPath()),
       0.001);
 
   constexpr double kAlpha0Max = 30.0;
@@ -254,7 +255,7 @@
     t += sim_dt;
   }
 
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     aos::analysis::Plotter plotter;
 
     plotter.AddFigure();
@@ -324,7 +325,7 @@
     plotter.AddLine(t_array, torque1_hat_t_array, "torque1_hat");
     plotter.Publish();
 
-    if (FLAGS_plot_thetas) {
+    if (absl::GetFlag(FLAGS_plot_thetas)) {
       plotter.AddFigure();
       plotter.Title("Angles");
       plotter.AddLine(t_array, theta0_goal_t_array, "theta0_t_goal");
diff --git a/y2018/vision/BUILD b/y2018/vision/BUILD
index a2c2d8c..0f11714 100644
--- a/y2018/vision/BUILD
+++ b/y2018/vision/BUILD
@@ -5,6 +5,7 @@
     srcs = ["image_streamer.cc"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
+        "//aos:init",
         "//aos/logging",
         "//aos/vision/blob:codec",
         "//aos/vision/events:epoll_events",
@@ -13,7 +14,7 @@
         "//aos/vision/image:image_stream",
         "//aos/vision/image:reader",
         "//y2018:vision_proto",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
diff --git a/y2018/vision/image_streamer.cc b/y2018/vision/image_streamer.cc
index 26e7ca1..81f2c6c 100644
--- a/y2018/vision/image_streamer.cc
+++ b/y2018/vision/image_streamer.cc
@@ -4,8 +4,9 @@
 #include <fstream>
 #include <string>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
+#include "aos/init.h"
 #include "aos/logging/implementations.h"
 #include "aos/logging/logging.h"
 #include "aos/vision/blob/codec.h"
@@ -23,9 +24,9 @@
 using ::aos::vision::Int32Codec;
 using ::y2018::VisionControl;
 
-DEFINE_bool(single_camera, true, "If true, only use video0");
-DEFINE_int32(camera0_exposure, 300, "Exposure for video0");
-DEFINE_int32(camera1_exposure, 300, "Exposure for video1");
+ABSL_FLAG(bool, single_camera, true, "If true, only use video0");
+ABSL_FLAG(int32_t, camera0_exposure, 300, "Exposure for video0");
+ABSL_FLAG(int32_t, camera1_exposure, 300, "Exposure for video1");
 
 aos::vision::DataRef mjpg_header =
     "HTTP/1.0 200 OK\r\n"
@@ -288,18 +289,18 @@
 };
 
 int main(int argc, char **argv) {
-  gflags::ParseCommandLineFlags(&argc, &argv, false);
+  aos::InitGoogle(&argc, &argv);
 
   TCPServer<MjpegDataSocket> tcp_server_(80);
   aos::vision::CameraParams params0;
-  params0.set_exposure(FLAGS_camera0_exposure);
+  params0.set_exposure(absl::GetFlag(FLAGS_camera0_exposure));
   params0.set_brightness(-40);
   params0.set_width(320);
   // params0.set_fps(10);
   params0.set_height(240);
 
   aos::vision::CameraParams params1 = params0;
-  params1.set_exposure(FLAGS_camera1_exposure);
+  params1.set_exposure(absl::GetFlag(FLAGS_camera1_exposure));
 
   ::y2018::VisionStatus vision_status;
   ::aos::events::ProtoTXUdpSocket<::y2018::VisionStatus> status_socket(
@@ -315,7 +316,7 @@
           status_socket.Send(vision_status);
         }
       }));
-  if (!FLAGS_single_camera) {
+  if (!absl::GetFlag(FLAGS_single_camera)) {
     camera1.reset(new CameraStream(
         // params,
         // "/dev/v4l/by-path/platform-tegra-xhci-usb-0:3.1:1.0-video-index0",
diff --git a/y2019/BUILD b/y2019/BUILD
index 7bc0c33..2bf0489 100644
--- a/y2019/BUILD
+++ b/y2019/BUILD
@@ -50,8 +50,9 @@
         "//y2019/control_loops/superstructure/stilts:stilts_plants",
         "//y2019/control_loops/superstructure/wrist:wrist_plants",
         "//y2019/vision:constants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2019/constants.cc b/y2019/constants.cc
index 26188de..e88fb54 100644
--- a/y2019/constants.cc
+++ b/y2019/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
diff --git a/y2019/control_loops/drivetrain/BUILD b/y2019/control_loops/drivetrain/BUILD
index 71bd0ee..9c45c1f 100644
--- a/y2019/control_loops/drivetrain/BUILD
+++ b/y2019/control_loops/drivetrain/BUILD
@@ -200,7 +200,7 @@
         "//frc971/control_loops/drivetrain:splinedrivetrain",
         "//frc971/control_loops/drivetrain:trajectory",
         "//y2019:constants",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ] + cpu_select({
         "amd64": [
             "//third_party/matplotlib-cpp",
@@ -254,7 +254,8 @@
         "//aos/events/logging:log_reader",
         "//aos/events/logging:log_writer",
         "//frc971/control_loops/drivetrain:drivetrain_lib",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/y2019/control_loops/drivetrain/drivetrain_replay.cc b/y2019/control_loops/drivetrain/drivetrain_replay.cc
index d9d928c..fa1c589 100644
--- a/y2019/control_loops/drivetrain/drivetrain_replay.cc
+++ b/y2019/control_loops/drivetrain/drivetrain_replay.cc
@@ -1,6 +1,6 @@
 #include <iostream>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -13,22 +13,24 @@
 #include "y2019/control_loops/drivetrain/drivetrain_base.h"
 #include "y2019/control_loops/drivetrain/event_loop_localizer.h"
 
-DEFINE_string(logfile, "/tmp/logfile.bfbs",
-              "Name of the logfile to read from.");
-DEFINE_string(config, "y2019/aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_string(output_file, "/tmp/replayed",
-              "Name of the logfile to write replayed data to.");
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, logfile, "/tmp/logfile.bfbs",
+          "Name of the logfile to read from.");
+ABSL_FLAG(std::string, config, "y2019/aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(std::string, output_file, "/tmp/replayed",
+          "Name of the logfile to write replayed data to.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
-  aos::logger::LogReader reader(FLAGS_logfile, &config.message());
+  aos::logger::LogReader reader(absl::GetFlag(FLAGS_logfile),
+                                &config.message());
   // TODO(james): Actually enforce not sending on the same buses as the logfile
   // spews out.
   reader.RemapLoggedChannel("/drivetrain",
@@ -43,7 +45,7 @@
   log_writer_event_loop->SkipAosLog();
   CHECK(nullptr == log_writer_event_loop->node());
   aos::logger::Logger writer(log_writer_event_loop.get());
-  writer.StartLoggingOnRun(FLAGS_output_file);
+  writer.StartLoggingOnRun(absl::GetFlag(FLAGS_output_file));
 
   std::unique_ptr<aos::EventLoop> drivetrain_event_loop =
       reader.event_loop_factory()->MakeEventLoop("drivetrain");
diff --git a/y2019/control_loops/drivetrain/localizer_test.cc b/y2019/control_loops/drivetrain/localizer_test.cc
index 278b958a..b92c466 100644
--- a/y2019/control_loops/drivetrain/localizer_test.cc
+++ b/y2019/control_loops/drivetrain/localizer_test.cc
@@ -3,7 +3,7 @@
 #include <queue>
 #include <random>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/testing/random_seed.h"
 #include "aos/testing/test_shm.h"
@@ -17,7 +17,7 @@
 #include "y2019/constants.h"
 #include "y2019/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_bool(plot, false, "If true, plot");
+ABSL_FLAG(bool, plot, false, "If true, plot");
 
 namespace y2019::control_loops::testing {
 
@@ -210,7 +210,7 @@
     printf("Each iteration of the simulation took on average %f seconds.\n",
            avg_time_.count());
 #if defined(SUPPORT_PLOT)
-    if (FLAGS_plot) {
+    if (absl::GetFlag(FLAGS_plot)) {
       matplotlibcpp::figure();
       matplotlibcpp::plot(simulation_t_, simulation_vl_, {{"label", "Vl"}});
       matplotlibcpp::plot(simulation_t_, simulation_vr_, {{"label", "Vr"}});
diff --git a/y2019/control_loops/drivetrain/replay_localizer.cc b/y2019/control_loops/drivetrain/replay_localizer.cc
index 80cf221..2e7591a 100644
--- a/y2019/control_loops/drivetrain/replay_localizer.cc
+++ b/y2019/control_loops/drivetrain/replay_localizer.cc
@@ -1,6 +1,6 @@
 #include <fcntl.h>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/init.h"
 #include "aos/logging/implementations.h"
@@ -17,13 +17,13 @@
 #include "third_party/matplotlib-cpp/matplotlibcpp.h"
 #endif
 
-DEFINE_string(logfile, "", "Path to the logfile to replay.");
+ABSL_FLAG(std::string, logfile, "", "Path to the logfile to replay.");
 // TODO(james): Figure out how to reliably source team number from logfile.
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_int32(plot_duration, 30,
-             "Duration, in seconds, to plot after the start time.");
-DEFINE_int32(start_offset, 0,
-             "Time, in seconds, to start replay plot after the first enable.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(int32_t, plot_duration, 30,
+          "Duration, in seconds, to plot after the start time.");
+ABSL_FLAG(int32_t, start_offset, 0,
+          "Time, in seconds, to start replay plot after the first enable.");
 
 namespace y2019::control_loops::drivetrain {
 using ::y2019::constants::Field;
diff --git a/y2019/control_loops/drivetrain/trajectory_generator_main.cc b/y2019/control_loops/drivetrain/trajectory_generator_main.cc
index 8f18222..4219d8d 100644
--- a/y2019/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2019/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
@@ -8,8 +10,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -22,7 +24,7 @@
       &event_loop, ::y2019::control_loops::drivetrain::GetDrivetrainConfig());
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2019/control_loops/superstructure/superstructure_lib_test.cc b/y2019/control_loops/superstructure/superstructure_lib_test.cc
index c2bf988..ec32d05 100644
--- a/y2019/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2019/control_loops/superstructure/superstructure_lib_test.cc
@@ -3,7 +3,8 @@
 #include <chrono>
 #include <memory>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "frc971/control_loops/capped_test_plant.h"
diff --git a/y2019/image_streamer/BUILD b/y2019/image_streamer/BUILD
index 5e49ebb..c4f7a6b 100644
--- a/y2019/image_streamer/BUILD
+++ b/y2019/image_streamer/BUILD
@@ -8,6 +8,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         ":flip_image",
+        "//aos:init",
         "//aos/logging",
         "//aos/vision/blob:codec",
         "//aos/vision/events:epoll_events",
@@ -16,7 +17,7 @@
         "//aos/vision/image:image_stream",
         "//aos/vision/image:reader",
         "//y2019:vision_proto",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
diff --git a/y2019/image_streamer/image_streamer.cc b/y2019/image_streamer/image_streamer.cc
index cbb4788..07acd6e 100644
--- a/y2019/image_streamer/image_streamer.cc
+++ b/y2019/image_streamer/image_streamer.cc
@@ -4,8 +4,9 @@
 #include <fstream>
 #include <string>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
+#include "aos/init.h"
 #include "aos/logging/implementations.h"
 #include "aos/logging/logging.h"
 #include "aos/vision/blob/codec.h"
@@ -24,13 +25,13 @@
 using ::aos::vision::Int32Codec;
 using ::y2019::VisionControl;
 
-DEFINE_string(roborio_ip, "10.9.71.2", "RoboRIO IP Address");
-DEFINE_string(log, "",
-              "If non-empty, log images to the specified prefix with the image "
-              "index appended to the filename");
-DEFINE_bool(single_camera, true, "If true, only use video0");
-DEFINE_int32(camera0_exposure, 600, "Exposure for video0");
-DEFINE_int32(camera1_exposure, 600, "Exposure for video1");
+ABSL_FLAG(std::string, roborio_ip, "10.9.71.2", "RoboRIO IP Address");
+ABSL_FLAG(std::string, log, "",
+          "If non-empty, log images to the specified prefix with the image "
+          "index appended to the filename");
+ABSL_FLAG(bool, single_camera, true, "If true, only use video0");
+ABSL_FLAG(int32_t, camera0_exposure, 600, "Exposure for video0");
+ABSL_FLAG(int32_t, camera1_exposure, 600, "Exposure for video1");
 
 aos::vision::DataRef mjpg_header =
     "HTTP/1.0 200 OK\r\n"
@@ -252,7 +253,7 @@
         tcp_server_(tcp_server),
         frame_callback_(frame_callback) {
     if (log) {
-      log_.reset(new BlobLog(FLAGS_log.c_str(), ".dat"));
+      log_.reset(new BlobLog(absl::GetFlag(FLAGS_log).c_str(), ".dat"));
     }
   }
 
@@ -307,30 +308,31 @@
 };
 
 int main(int argc, char **argv) {
-  gflags::ParseCommandLineFlags(&argc, &argv, false);
+  aos::InitGoogle(&argc, &argv);
+
   TCPServer<MjpegDataSocket> tcp_server_(80);
   aos::vision::CameraParams params0;
-  params0.set_exposure(FLAGS_camera0_exposure);
+  params0.set_exposure(absl::GetFlag(FLAGS_camera0_exposure));
   params0.set_brightness(-40);
   params0.set_width(320);
   // params0.set_fps(10);
   params0.set_height(240);
 
   aos::vision::CameraParams params1 = params0;
-  params1.set_exposure(FLAGS_camera1_exposure);
+  params1.set_exposure(absl::GetFlag(FLAGS_camera1_exposure));
 
   ::y2019::VisionStatus vision_status;
   AOS_LOG(INFO,
           "The UDP socket should be on port 5001 to 10.9.71.2 for "
           "the competition robot.\n");
   AOS_LOG(INFO, "Starting UDP socket on port 5001 to %s\n",
-          FLAGS_roborio_ip.c_str());
+          absl::GetFlag(FLAGS_roborio_ip).c_str());
   ::aos::events::ProtoTXUdpSocket<::y2019::VisionStatus> status_socket(
-      FLAGS_roborio_ip.c_str(), 5001);
+      absl::GetFlag(FLAGS_roborio_ip).c_str(), 5001);
 
   ::std::unique_ptr<CameraStream> camera1;
   ::std::unique_ptr<CameraStream> camera0(new CameraStream(
-      params0, "/dev/video0", &tcp_server_, !FLAGS_log.empty(),
+      params0, "/dev/video0", &tcp_server_, !absl::GetFlag(FLAGS_log).empty(),
       [&camera0, &status_socket, &vision_status]() {
         vision_status.set_low_frame_count(vision_status.low_frame_count() + 1);
         AOS_LOG(INFO, "Got a frame cam0\n");
@@ -338,7 +340,7 @@
           status_socket.Send(vision_status);
         }
       }));
-  if (!FLAGS_single_camera) {
+  if (!absl::GetFlag(FLAGS_single_camera)) {
     camera1.reset(new CameraStream(
         params1, "/dev/video1", &tcp_server_, false,
         [&camera1, &status_socket, &vision_status]() {
diff --git a/y2019/jevois/camera/BUILD b/y2019/jevois/camera/BUILD
index 6bd2b99..930571f 100644
--- a/y2019/jevois/camera/BUILD
+++ b/y2019/jevois/camera/BUILD
@@ -10,7 +10,8 @@
         "//aos/vision/image:camera_params",
         "//aos/vision/image:image_types",
         "//aos/vision/image:reader",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2019/jevois/camera/reader.cc b/y2019/jevois/camera/reader.cc
index 09e07db..57e0a26 100644
--- a/y2019/jevois/camera/reader.cc
+++ b/y2019/jevois/camera/reader.cc
@@ -13,7 +13,8 @@
 #include <cstdlib>
 #include <cstring>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/time/time.h"
 
diff --git a/y2019/vision/BUILD b/y2019/vision/BUILD
index 78298a1..af6da5b 100644
--- a/y2019/vision/BUILD
+++ b/y2019/vision/BUILD
@@ -40,7 +40,8 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         "//aos/vision/image:image_types",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -94,7 +95,7 @@
         "//aos/vision/blob:transpose",
         "//aos/vision/debug:debug_framework",
         "//aos/vision/math:vector",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -105,6 +106,7 @@
     deps = [
         ":image_writer",
         ":target_finder",
+        "//aos:init",
         "//aos/vision/blob:codec",
         "//aos/vision/blob:find_blob",
         "//aos/vision/events:epoll_events",
@@ -115,7 +117,8 @@
         "//y2019/jevois:uart",
         "//y2019/jevois/camera:image_stream",
         "//y2019/jevois/camera:reader",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_ceres_solver//:ceres",
     ],
 )
@@ -150,6 +153,7 @@
     target_compatible_with = VISION_TARGETS,
     deps = [
         ":target_finder",
+        "//aos:init",
         "//aos/logging",
         "//aos/vision/blob:codec",
         "//aos/vision/blob:find_blob",
diff --git a/y2019/vision/debug_viewer.cc b/y2019/vision/debug_viewer.cc
index 1a93f87..31fee54 100644
--- a/y2019/vision/debug_viewer.cc
+++ b/y2019/vision/debug_viewer.cc
@@ -1,6 +1,6 @@
 #include <iostream>
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include <Eigen/Dense>
 
 #include "aos/vision/blob/move_scale.h"
@@ -19,7 +19,7 @@
 using aos::vision::Segment;
 using aos::vision::Vector;
 
-DEFINE_int32(camera, 10, "The camera to use the intrinsics for");
+ABSL_FLAG(int32_t, camera, 10, "The camera to use the intrinsics for");
 
 namespace y2019::vision {
 
diff --git a/y2019/vision/global_calibration.cc b/y2019/vision/global_calibration.cc
index bb3259e..b502f3b 100644
--- a/y2019/vision/global_calibration.cc
+++ b/y2019/vision/global_calibration.cc
@@ -1,5 +1,8 @@
 #include <fstream>
 
+#include "absl/flags/flag.h"
+
+#include "aos/init.h"
 #include "aos/logging/implementations.h"
 #include "aos/logging/logging.h"
 #include "aos/vision/blob/codec.h"
@@ -14,28 +17,26 @@
 // CERES Clashes with logging symbols...
 #include "ceres/ceres.h"
 
-DEFINE_int32(camera_id, -1, "The camera ID to calibrate");
-DEFINE_string(prefix, "", "The image filename prefix");
+ABSL_FLAG(int32_t, camera_id, -1, "The camera ID to calibrate");
+ABSL_FLAG(std::string, prefix, "", "The image filename prefix");
 
-DEFINE_string(constants, "y2019/vision/constants.cc",
-              "Path to the constants file to update");
+ABSL_FLAG(std::string, constants, "y2019/vision/constants.cc",
+          "Path to the constants file to update");
 
-DEFINE_double(beginning_tape_measure_reading, 11,
-              "The tape measure measurement (in inches) of the first image.");
-DEFINE_int32(image_count, 75, "The number of images to capture");
-DEFINE_double(tape_start_x, -12.5,
-              "The starting location of the tape measure in x relative to the "
-              "CG in inches.");
-DEFINE_double(tape_start_y, -0.5,
-              "The starting location of the tape measure in y relative to the "
-              "CG in inches.");
+ABSL_FLAG(double, beginning_tape_measure_reading, 11,
+          "The tape measure measurement (in inches) of the first image.");
+ABSL_FLAG(int32_t, image_count, 75, "The number of images to capture");
+ABSL_FLAG(double, tape_start_x, -12.5,
+          "The starting location of the tape measure in x relative to the "
+          "CG in inches.");
+ABSL_FLAG(double, tape_start_y, -0.5,
+          "The starting location of the tape measure in y relative to the "
+          "CG in inches.");
 
-DEFINE_double(
-    tape_direction_x, -1.0,
-    "The x component of \"1\" inch along the tape measure in meters.");
-DEFINE_double(
-    tape_direction_y, 0.0,
-    "The y component of \"1\" inch along the tape measure in meters.");
+ABSL_FLAG(double, tape_direction_x, -1.0,
+          "The x component of \"1\" inch along the tape measure in meters.");
+ABSL_FLAG(double, tape_direction_y, 0.0,
+          "The y component of \"1\" inch along the tape measure in meters.");
 
 using ::aos::monotonic_clock;
 using ::aos::events::DataSocket;
@@ -88,17 +89,18 @@
 
 void main(int argc, char **argv) {
   using namespace y2019::vision;
-  ::gflags::ParseCommandLineFlags(&argc, &argv, false);
+  aos::InitGoogle(&argc, &argv);
 
+  std::string prefix = absl::GetFlag(FLAGS_prefix);
   DatasetInfo info = {
-      FLAGS_camera_id,
-      {{FLAGS_tape_start_x * kInchesToMeters,
-        FLAGS_tape_start_y * kInchesToMeters}},
-      {{FLAGS_tape_direction_x * kInchesToMeters,
-        FLAGS_tape_direction_y * kInchesToMeters}},
-      FLAGS_beginning_tape_measure_reading,
-      FLAGS_prefix.c_str(),
-      FLAGS_image_count,
+      absl::GetFlag(FLAGS_camera_id),
+      {{absl::GetFlag(FLAGS_tape_start_x) * kInchesToMeters,
+        absl::GetFlag(FLAGS_tape_start_y) * kInchesToMeters}},
+      {{absl::GetFlag(FLAGS_tape_direction_x) * kInchesToMeters,
+        absl::GetFlag(FLAGS_tape_direction_y) * kInchesToMeters}},
+      absl::GetFlag(FLAGS_beginning_tape_measure_reading),
+      prefix.c_str(),
+      absl::GetFlag(FLAGS_image_count),
   };
 
   TargetFinder target_finder;
@@ -140,8 +142,8 @@
   ::std::cout << "error = " << summary.final_cost << ";\n";
 
   for (int i = 0; i < info.num_images; ++i) {
-    ::aos::vision::DatasetFrame frame =
-        aos::vision::LoadFile(FLAGS_prefix + std::to_string(i) + ".yuyv");
+    ::aos::vision::DatasetFrame frame = aos::vision::LoadFile(
+        absl::GetFlag(FLAGS_prefix) + std::to_string(i) + ".yuyv");
 
     const ::aos::vision::ImageFormat fmt{640, 480};
     ::aos::vision::BlobList imgs =
@@ -289,7 +291,8 @@
   results.dataset = info;
   results.intrinsics = IntrinsicParams::get(&intrinsics[0]);
   results.geometry = CameraGeometry::get(&geometry[0]);
-  DumpCameraConstants(FLAGS_constants.c_str(), info.camera_id, results);
+  DumpCameraConstants(absl::GetFlag(FLAGS_constants).c_str(), info.camera_id,
+                      results);
 }
 
 }  // namespace y2019::vision
diff --git a/y2019/vision/image_writer.cc b/y2019/vision/image_writer.cc
index 9b73a81..18b8cae 100644
--- a/y2019/vision/image_writer.cc
+++ b/y2019/vision/image_writer.cc
@@ -4,7 +4,8 @@
 
 #include <fstream>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace y2019::vision {
 
diff --git a/y2019/vision/target_sender.cc b/y2019/vision/target_sender.cc
index 650693c..6be52a5 100644
--- a/y2019/vision/target_sender.cc
+++ b/y2019/vision/target_sender.cc
@@ -4,6 +4,7 @@
 #include <random>
 #include <thread>
 
+#include "aos/init.h"
 #include "aos/vision/blob/codec.h"
 #include "aos/vision/blob/find_blob.h"
 #include "aos/vision/events/socket_types.h"
@@ -18,7 +19,8 @@
 
 // This has to be last to preserve compatibility with other headers using AOS
 // logging.
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 using ::aos::monotonic_clock;
 using ::aos::events::DataSocket;
@@ -162,13 +164,9 @@
 }
 
 int main(int argc, char **argv) {
-  (void)argc;
-  (void)argv;
   using namespace y2019::vision;
   using frc971::jevois::CameraCommand;
-  // gflags::ParseCommandLineFlags(&argc, &argv, false);
-  FLAGS_logtostderr = true;
-  google::InitGoogleLogging(argv[0]);
+  aos::InitGoogle(&argc, &argv);
 
   int itsDev = open_terminos("/dev/ttyS0");
   frc971::jevois::CobsPacketizer<frc971::jevois::uart_to_camera_size()> cobs;
diff --git a/y2020/BUILD b/y2020/BUILD
index 3def80a..51fbb54 100644
--- a/y2020/BUILD
+++ b/y2020/BUILD
@@ -89,8 +89,9 @@
         "//y2020/control_loops/superstructure/hood:hood_plants",
         "//y2020/control_loops/superstructure/intake:intake_plants",
         "//y2020/control_loops/superstructure/turret:turret_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2020/actors/autonomous_actor.cc b/y2020/actors/autonomous_actor.cc
index 404372d..f68c7f7 100644
--- a/y2020/actors/autonomous_actor.cc
+++ b/y2020/actors/autonomous_actor.cc
@@ -4,6 +4,8 @@
 #include <cinttypes>
 #include <cmath>
 
+#include "absl/flags/flag.h"
+
 #include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/util/math.h"
@@ -12,9 +14,9 @@
 #include "y2020/constants.h"
 #include "y2020/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
-DEFINE_bool(just_shoot, false,
-            "If true, run the autonomous that just shoots balls.");
+ABSL_FLAG(bool, spline_auto, false, "If true, define a spline autonomous mode");
+ABSL_FLAG(bool, just_shoot, false,
+          "If true, run the autonomous that just shoots balls.");
 
 namespace y2020::actors {
 
@@ -93,7 +95,7 @@
     return;
   }
   sent_starting_position_ = false;
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     test_spline_ = PlanSpline(std::bind(&AutonomousSplines::TestSpline,
                                         &auto_splines_, std::placeholders::_1),
                               SplineDirection::kForward);
@@ -161,7 +163,7 @@
     AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
     return false;
   }
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     SplineAuto();
   } else {
     if (practice_robot_) {
diff --git a/y2020/actors/shooter_tuning_actor.cc b/y2020/actors/shooter_tuning_actor.cc
index a6efce7..ae34362 100644
--- a/y2020/actors/shooter_tuning_actor.cc
+++ b/y2020/actors/shooter_tuning_actor.cc
@@ -6,7 +6,8 @@
 #include <sstream>
 #include <utility>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/init.h"
 #include "frc971/autonomous/base_autonomous_actor.h"
diff --git a/y2020/constants.cc b/y2020/constants.cc
index b5456b4..7ae54b5 100644
--- a/y2020/constants.cc
+++ b/y2020/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
diff --git a/y2020/control_loops/drivetrain/BUILD b/y2020/control_loops/drivetrain/BUILD
index feabb62..9bf0fab 100644
--- a/y2020/control_loops/drivetrain/BUILD
+++ b/y2020/control_loops/drivetrain/BUILD
@@ -192,8 +192,9 @@
         "//aos/testing:googletest",
         "//frc971/control_loops/drivetrain:drivetrain_lib",
         "//frc971/control_loops/drivetrain:trajectory_schema",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -216,8 +217,9 @@
         "//frc971/control_loops/drivetrain:trajectory_generator",
         "//y2020:constants",
         "//y2020/control_loops/superstructure:superstructure_lib",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2020/control_loops/drivetrain/drivetrain_replay.cc b/y2020/control_loops/drivetrain/drivetrain_replay.cc
index 326c184..5c5c20b 100644
--- a/y2020/control_loops/drivetrain/drivetrain_replay.cc
+++ b/y2020/control_loops/drivetrain/drivetrain_replay.cc
@@ -4,7 +4,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original drivetrain status data will be on the
 // /original/drivetrain channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -21,12 +21,13 @@
 #include "y2020/control_loops/drivetrain/localizer.h"
 #include "y2020/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(config, "y2020/aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_string(output_folder, "/tmp/replayed",
-              "Name of the folder to write replayed logs to.");
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_bool(log_all_nodes, false, "Whether to rerun the logger on every node.");
+ABSL_FLAG(std::string, config, "y2020/aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(std::string, output_folder, "/tmp/replayed",
+          "Name of the folder to write replayed logs to.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(bool, log_all_nodes, false,
+          "Whether to rerun the logger on every node.");
 
 // TODO(james): Currently, this replay produces logfiles that can't be read due
 // to time estimation issues. Pending the active refactorings of the
@@ -34,10 +35,10 @@
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   // sort logfiles
   const std::vector<aos::logger::LogFile> logfiles =
@@ -60,16 +61,17 @@
   reader.Register();
 
   std::vector<std::unique_ptr<aos::util::LoggerState>> loggers;
-  if (FLAGS_log_all_nodes) {
-    loggers = aos::util::MakeLoggersForAllNodes(reader.event_loop_factory(),
-                                                FLAGS_output_folder);
+  if (absl::GetFlag(FLAGS_log_all_nodes)) {
+    loggers = aos::util::MakeLoggersForAllNodes(
+        reader.event_loop_factory(), absl::GetFlag(FLAGS_output_folder));
   } else {
     // List of nodes to create loggers for (note: currently just roborio; this
     // code was refactored to allow easily adding new loggers to accommodate
     // debugging and potential future changes).
     const std::vector<std::string> nodes_to_log = {"roborio"};
-    loggers = aos::util::MakeLoggersForNodes(reader.event_loop_factory(),
-                                             nodes_to_log, FLAGS_output_folder);
+    loggers = aos::util::MakeLoggersForNodes(
+        reader.event_loop_factory(), nodes_to_log,
+        absl::GetFlag(FLAGS_output_folder));
   }
 
   const aos::Node *node = nullptr;
diff --git a/y2020/control_loops/drivetrain/drivetrain_replay_test.cc b/y2020/control_loops/drivetrain/drivetrain_replay_test.cc
index 8d096cd..62592c0 100644
--- a/y2020/control_loops/drivetrain/drivetrain_replay_test.cc
+++ b/y2020/control_loops/drivetrain/drivetrain_replay_test.cc
@@ -8,7 +8,7 @@
 // longer be valid.
 // TODO(james): Do something about that when the time comes--could just copy
 // the existing drivetrain config into this file and use it directly.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/configuration.h"
@@ -22,17 +22,18 @@
 #include "frc971/control_loops/drivetrain/trajectory_schema.h"
 #include "y2020/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_string(logfile, "external/drivetrain_replay/",
-              "Name of the logfile to read from.");
-DEFINE_string(config, "y2020/aos_config.json",
-              "Name of the config file to replay using.");
+ABSL_FLAG(std::string, logfile, "external/drivetrain_replay/",
+          "Name of the logfile to read from.");
+ABSL_FLAG(std::string, config, "y2020/aos_config.json",
+          "Name of the config file to replay using.");
 
 namespace y2020::control_loops::drivetrain::testing {
 
 class DrivetrainReplayTest : public ::testing::Test {
  public:
   DrivetrainReplayTest()
-      : reader_(aos::logger::SortParts(aos::logger::FindLogs(FLAGS_logfile))) {
+      : reader_(aos::logger::SortParts(
+            aos::logger::FindLogs(absl::GetFlag(FLAGS_logfile)))) {
     aos::network::OverrideTeamNumber(971);
 
     // TODO(james): Actually enforce not sending on the same buses as the
diff --git a/y2020/control_loops/drivetrain/localizer.cc b/y2020/control_loops/drivetrain/localizer.cc
index 0943b28..f8518f3 100644
--- a/y2020/control_loops/drivetrain/localizer.cc
+++ b/y2020/control_loops/drivetrain/localizer.cc
@@ -1,10 +1,12 @@
 #include "y2020/control_loops/drivetrain/localizer.h"
 
+#include "absl/flags/flag.h"
+
 #include "y2020/constants.h"
 
-DEFINE_bool(send_empty_debug, false,
-            "If true, send LocalizerDebug messages on every tick, even if "
-            "they would be empty.");
+ABSL_FLAG(bool, send_empty_debug, false,
+          "If true, send LocalizerDebug messages on every tick, even if "
+          "they would be empty.");
 
 namespace y2020::control_loops::drivetrain {
 
@@ -181,7 +183,7 @@
       }
     }
   }
-  if (FLAGS_send_empty_debug || !debug_offsets.empty()) {
+  if (absl::GetFlag(FLAGS_send_empty_debug) || !debug_offsets.empty()) {
     const auto vector_offset =
         builder.fbb()->CreateVector(debug_offsets.data(), debug_offsets.size());
     const auto rejections_offset =
diff --git a/y2020/control_loops/drivetrain/localizer_test.cc b/y2020/control_loops/drivetrain/localizer_test.cc
index e509241..951a286 100644
--- a/y2020/control_loops/drivetrain/localizer_test.cc
+++ b/y2020/control_loops/drivetrain/localizer_test.cc
@@ -2,6 +2,7 @@
 
 #include <queue>
 
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -14,8 +15,8 @@
 #include "y2020/control_loops/drivetrain/drivetrain_base.h"
 #include "y2020/control_loops/superstructure/superstructure_status_generated.h"
 
-DEFINE_string(output_file, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_file, "",
+          "If set, logs all channels to the provided logfile.");
 
 // This file tests that the full 2020 localizer behaves sanely.
 
@@ -145,10 +146,10 @@
     set_team_id(frc971::control_loops::testing::kTeamNumber);
     set_battery_voltage(12.0);
 
-    if (!FLAGS_output_file.empty()) {
+    if (!absl::GetFlag(FLAGS_output_file).empty()) {
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_file);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_file));
     }
 
     test_event_loop_->MakeWatcher(
diff --git a/y2020/control_loops/drivetrain/trajectory_generator_main.cc b/y2020/control_loops/drivetrain/trajectory_generator_main.cc
index 152822e..e7634b7 100644
--- a/y2020/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2020/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
@@ -8,8 +10,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -22,7 +24,7 @@
       &event_loop, ::y2020::control_loops::drivetrain::GetDrivetrainConfig());
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2020/control_loops/superstructure/shooter/BUILD b/y2020/control_loops/superstructure/shooter/BUILD
index 96c933f..df676e4 100644
--- a/y2020/control_loops/superstructure/shooter/BUILD
+++ b/y2020/control_loops/superstructure/shooter/BUILD
@@ -57,7 +57,8 @@
         ":shooter_tuning_readings_fbs",
         "//aos:init",
         "//aos/events:shm_event_loop",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/y2020/control_loops/superstructure/shooter/shooter_tuning_params_setter.cc b/y2020/control_loops/superstructure/shooter/shooter_tuning_params_setter.cc
index 5e3010d..abd5463 100644
--- a/y2020/control_loops/superstructure/shooter/shooter_tuning_params_setter.cc
+++ b/y2020/control_loops/superstructure/shooter/shooter_tuning_params_setter.cc
@@ -1,22 +1,26 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2020/control_loops/superstructure/shooter/shooter_tuning_params_generated.h"
 
-DEFINE_double(velocity_initial_finisher, 300.0, "Initial finisher velocity");
-DEFINE_double(velocity_final_finisher, 500.0, "Final finisher velocity");
-DEFINE_double(velocity_finisher_increment, 25.0, "Finisher velocity increment");
+ABSL_FLAG(double, velocity_initial_finisher, 300.0,
+          "Initial finisher velocity");
+ABSL_FLAG(double, velocity_final_finisher, 500.0, "Final finisher velocity");
+ABSL_FLAG(double, velocity_finisher_increment, 25.0,
+          "Finisher velocity increment");
 
-DEFINE_double(velocity_initial_accelerator, 180.0,
-              "Initial accelerator velocity");
-DEFINE_double(velocity_final_accelerator, 250.0, "Final accelerator velocity");
-DEFINE_double(velocity_accelerator_increment, 20.0,
-              "Accelerator velocity increment");
+ABSL_FLAG(double, velocity_initial_accelerator, 180.0,
+          "Initial accelerator velocity");
+ABSL_FLAG(double, velocity_final_accelerator, 250.0,
+          "Final accelerator velocity");
+ABSL_FLAG(double, velocity_accelerator_increment, 20.0,
+          "Accelerator velocity increment");
 
-DEFINE_int32(balls_per_iteration, 10,
-             "Balls to shoot per iteration in the velocity sweep");
+ABSL_FLAG(int32_t, balls_per_iteration, 10,
+          "Balls to shoot per iteration in the velocity sweep");
 
 namespace shooter = y2020::control_loops::superstructure::shooter;
 
@@ -43,16 +47,19 @@
   auto builder = sender.MakeBuilder();
 
   auto finisher_params = BuildFlywheelTuningParams(
-      builder, FLAGS_velocity_initial_finisher, FLAGS_velocity_final_finisher,
-      FLAGS_velocity_finisher_increment);
+      builder, absl::GetFlag(FLAGS_velocity_initial_finisher),
+      absl::GetFlag(FLAGS_velocity_final_finisher),
+      absl::GetFlag(FLAGS_velocity_finisher_increment));
   auto accelerator_params = BuildFlywheelTuningParams(
-      builder, FLAGS_velocity_initial_accelerator,
-      FLAGS_velocity_final_accelerator, FLAGS_velocity_accelerator_increment);
+      builder, absl::GetFlag(FLAGS_velocity_initial_accelerator),
+      absl::GetFlag(FLAGS_velocity_final_accelerator),
+      absl::GetFlag(FLAGS_velocity_accelerator_increment));
 
   auto tuning_params_builder = builder.MakeBuilder<shooter::TuningParams>();
   tuning_params_builder.add_finisher(finisher_params);
   tuning_params_builder.add_accelerator(accelerator_params);
-  tuning_params_builder.add_balls_per_iteration(FLAGS_balls_per_iteration);
+  tuning_params_builder.add_balls_per_iteration(
+      absl::GetFlag(FLAGS_balls_per_iteration));
   builder.CheckOk(builder.Send(tuning_params_builder.Finish()));
 
   return 0;
diff --git a/y2020/control_loops/superstructure/superstructure_lib_test.cc b/y2020/control_loops/superstructure/superstructure_lib_test.cc
index fad888c..1a9e228 100644
--- a/y2020/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2020/control_loops/superstructure/superstructure_lib_test.cc
@@ -3,7 +3,8 @@
 #include <chrono>
 #include <memory>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_reader.h"
@@ -21,12 +22,12 @@
 #include "y2020/control_loops/superstructure/intake/intake_plant.h"
 #include "y2020/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(output_file, "",
-              "If set, logs all channels to the provided logfile.");
-DEFINE_string(replay_logfile, "external/superstructure_replay/",
-              "Name of the logfile to read from and replay.");
-DEFINE_string(config, "y2020/aos_config.json",
-              "Name of the config file to replay using.");
+ABSL_FLAG(std::string, output_file, "",
+          "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, replay_logfile, "external/superstructure_replay/",
+          "Name of the logfile to read from and replay.");
+ABSL_FLAG(std::string, config, "y2020/aos_config.json",
+          "Name of the config file to replay using.");
 
 namespace y2020::control_loops::superstructure::testing {
 
@@ -263,8 +264,10 @@
                accelerator_left_plant_->voltage_offset();
 
     // Confirm that we aren't drawing too much current.
-    CHECK_NEAR(accelerator_left_plant_->battery_current(accelerator_left_U),
-               0.0, 75.0);
+    CHECK_LE(accelerator_left_plant_->battery_current(accelerator_left_U),
+             75.0);
+    CHECK_GE(accelerator_left_plant_->battery_current(accelerator_left_U),
+             -75.0);
 
     ::Eigen::Matrix<double, 1, 1> accelerator_right_U;
     accelerator_right_U
@@ -272,8 +275,10 @@
                accelerator_right_plant_->voltage_offset();
 
     // Confirm that we aren't drawing too much current.
-    CHECK_NEAR(accelerator_right_plant_->battery_current(accelerator_right_U),
-               0.0, 75.0);
+    CHECK_LE(accelerator_right_plant_->battery_current(accelerator_right_U),
+             75.0);
+    CHECK_GE(accelerator_right_plant_->battery_current(accelerator_right_U),
+             -75.0);
 
     ::Eigen::Matrix<double, 1, 1> finisher_U;
     finisher_U << superstructure_output_fetcher_->finisher_voltage() +
@@ -281,7 +286,8 @@
 
     // Confirm that we aren't drawing too much current.  2 motors -> twice the
     // lumped current since our model can't tell them apart.
-    CHECK_NEAR(finisher_plant_->battery_current(finisher_U), 0.0, 200.0);
+    CHECK_LE(finisher_plant_->battery_current(finisher_U), 200.0);
+    CHECK_GE(finisher_plant_->battery_current(finisher_U), -200.0);
 
     hood_plant_->Update(hood_U);
     intake_plant_->Update(intake_U);
@@ -440,11 +446,11 @@
         superstructure_plant_(superstructure_plant_event_loop_.get(), dt()) {
     set_team_id(::frc971::control_loops::testing::kTeamNumber);
 
-    if (!FLAGS_output_file.empty()) {
-      unlink(FLAGS_output_file.c_str());
+    if (!absl::GetFlag(FLAGS_output_file).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_file).c_str());
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_file);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_file));
     }
   }
 
@@ -1143,7 +1149,7 @@
  public:
   SuperstructureReplayTest()
       : reader_(aos::logger::SortParts(
-            aos::logger::FindLogs(FLAGS_replay_logfile))) {
+            aos::logger::FindLogs(absl::GetFlag(FLAGS_replay_logfile)))) {
     aos::network::OverrideTeamNumber(971);
 
     reader_.RemapLoggedChannel("/superstructure",
@@ -1168,12 +1174,12 @@
     superstructure_status_fetcher_ =
         test_event_loop_->MakeFetcher<Status>("/superstructure");
 
-    if (!FLAGS_output_file.empty()) {
-      unlink(FLAGS_output_file.c_str());
+    if (!absl::GetFlag(FLAGS_output_file).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_file).c_str());
       logger_event_loop_ =
           reader_.event_loop_factory()->MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_file);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_file));
     }
   }
 
diff --git a/y2020/control_loops/superstructure/superstructure_replay.cc b/y2020/control_loops/superstructure/superstructure_replay.cc
index 36a6778..27816ce 100644
--- a/y2020/control_loops/superstructure/superstructure_replay.cc
+++ b/y2020/control_loops/superstructure/superstructure_replay.cc
@@ -4,7 +4,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original drivetrain status data will be on the
 // /original/drivetrain channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
@@ -15,12 +15,12 @@
 #include "y2020/constants.h"
 #include "y2020/control_loops/superstructure/superstructure.h"
 
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
   y2020::constants::InitValues();
 
   // open logfiles
diff --git a/y2020/setpoint_setter.cc b/y2020/setpoint_setter.cc
index 2bfb917..fe1738a 100644
--- a/y2020/setpoint_setter.cc
+++ b/y2020/setpoint_setter.cc
@@ -1,14 +1,13 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2020/setpoint_generated.h"
 
-DEFINE_double(accelerator, 250.0, "Accelerator speed");
-DEFINE_double(finisher, 500.0, "Finsher speed");
-DEFINE_double(hood, 0.45, "Hood setpoint");
-DEFINE_double(turret, 0.0, "Turret setpoint");
+ABSL_FLAG(double, accelerator, 250.0, "Accelerator speed");
+ABSL_FLAG(double, finisher, 500.0, "Finsher speed");
+ABSL_FLAG(double, hood, 0.45, "Hood setpoint");
+ABSL_FLAG(double, turret, 0.0, "Turret setpoint");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
@@ -27,10 +26,10 @@
   y2020::joysticks::Setpoint::Builder setpoint_builder =
       builder.MakeBuilder<y2020::joysticks::Setpoint>();
 
-  setpoint_builder.add_accelerator(FLAGS_accelerator);
-  setpoint_builder.add_finisher(FLAGS_finisher);
-  setpoint_builder.add_hood(FLAGS_hood);
-  setpoint_builder.add_turret(FLAGS_turret);
+  setpoint_builder.add_accelerator(absl::GetFlag(FLAGS_accelerator));
+  setpoint_builder.add_finisher(absl::GetFlag(FLAGS_finisher));
+  setpoint_builder.add_hood(absl::GetFlag(FLAGS_hood));
+  setpoint_builder.add_turret(absl::GetFlag(FLAGS_turret));
   builder.CheckOk(builder.Send(setpoint_builder.Finish()));
 
   return 0;
diff --git a/y2020/vision/camera_reader.cc b/y2020/vision/camera_reader.cc
index 251f988..37d35e6 100644
--- a/y2020/vision/camera_reader.cc
+++ b/y2020/vision/camera_reader.cc
@@ -2,6 +2,7 @@
 
 #include <math.h>
 
+#include "absl/flags/flag.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/features2d.hpp>
 #include <opencv2/imgproc.hpp>
@@ -16,12 +17,12 @@
 #include "y2020/vision/sift/sift_training_generated.h"
 #include "y2020/vision/tools/python_code/sift_training_data.h"
 
-DEFINE_bool(skip_sift, false,
-            "If true don't run any feature extraction.  Just forward images.");
-DEFINE_bool(ransac_pose, false,
-            "If true, do pose estimate with RANSAC; else, use ITERATIVE mode.");
-DEFINE_bool(use_prev_pose, true,
-            "If true, use previous pose estimate as seed for next estimate.");
+ABSL_FLAG(bool, skip_sift, false,
+          "If true don't run any feature extraction.  Just forward images.");
+ABSL_FLAG(bool, ransac_pose, false,
+          "If true, do pose estimate with RANSAC; else, use ITERATIVE mode.");
+ABSL_FLAG(bool, use_prev_pose, true,
+          "If true, use previous pose estimate as seed for next estimate.");
 
 namespace frc971::vision {
 
@@ -160,7 +161,7 @@
   std::vector<cv::KeyPoint> keypoints;
 
   cv::Mat descriptors;
-  if (!FLAGS_skip_sift) {
+  if (!absl::GetFlag(FLAGS_skip_sift)) {
     sift_->detectAndCompute(image_mat, cv::noArray(), keypoints, descriptors);
   }
 
@@ -176,7 +177,7 @@
   for (int image_idx = 0; image_idx < number_training_images(); ++image_idx) {
     // Then, match those features against our training data.
     std::vector<std::vector<cv::DMatch>> matches;
-    if (!FLAGS_skip_sift) {
+    if (!absl::GetFlag(FLAGS_skip_sift)) {
       matchers_[image_idx].knnMatch(/* queryDescriptors */ descriptors, matches,
                                     /* k */ 2);
     }
@@ -318,7 +319,7 @@
     // it's sometimes bouncing between two possible poses.  Putting it
     // near the previous pose helps it converge to the previous pose
     // estimate (assuming it's valid).
-    if (FLAGS_use_prev_pose) {
+    if (absl::GetFlag(FLAGS_use_prev_pose)) {
       R_camera_field_vec = prev_camera_field_R_vec_list_[i].clone();
       T_camera_field = prev_camera_field_T_list_[i].clone();
       VLOG(2) << "Using previous match for training image " << i
@@ -326,13 +327,13 @@
     }
 
     // Compute the pose of the camera (global origin relative to camera)
-    if (FLAGS_ransac_pose) {
+    if (absl::GetFlag(FLAGS_ransac_pose)) {
       // RANSAC computation is designed to be more robust to outliers.
       // But, we found it bounces around a lot, even with identical points
       cv::solvePnPRansac(per_image_good_match.training_points_3d,
                          per_image_good_match.query_points, CameraIntrinsics(),
                          CameraDistCoeffs(), R_camera_field_vec, T_camera_field,
-                         FLAGS_use_prev_pose);
+                         absl::GetFlag(FLAGS_use_prev_pose));
     } else {
       // ITERATIVE mode is potentially less robust to outliers, but we
       // found it to be more stable
@@ -340,7 +341,7 @@
       cv::solvePnP(per_image_good_match.training_points_3d,
                    per_image_good_match.query_points, CameraIntrinsics(),
                    CameraDistCoeffs(), R_camera_field_vec, T_camera_field,
-                   FLAGS_use_prev_pose, cv::SOLVEPNP_ITERATIVE);
+                   absl::GetFlag(FLAGS_use_prev_pose), cv::SOLVEPNP_ITERATIVE);
     }
 
     // We are occasionally seeing NaN in the prior estimate, so checking for
@@ -451,7 +452,7 @@
 
 void CameraReader::ReadImage() {
   if (!reader_->ReadLatestImage()) {
-    if (!FLAGS_skip_sift) {
+    if (!absl::GetFlag(FLAGS_skip_sift)) {
       LOG(INFO) << "No image, sleeping";
     }
     read_image_timer_->Schedule(event_loop_->monotonic_now() +
diff --git a/y2020/vision/camera_reader_main.cc b/y2020/vision/camera_reader_main.cc
index 1995151..90a2580 100644
--- a/y2020/vision/camera_reader_main.cc
+++ b/y2020/vision/camera_reader_main.cc
@@ -1,3 +1,6 @@
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2020/vision/camera_reader.h"
@@ -5,14 +8,15 @@
 // config used to allow running camera_reader independently.  E.g.,
 // bazel run //y2020/vision:camera_reader -- --config y2020/aos_config.json
 //   --override_hostname pi-7971-1  --ignore_timestamps true
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 namespace frc971::vision {
 namespace {
 
 void CameraReaderMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   const aos::FlatbufferSpan<sift::TrainingData> training_data(
       SiftTrainingData());
diff --git a/y2020/vision/extrinsics_calibration.cc b/y2020/vision/extrinsics_calibration.cc
index ddbe9af..9f50373 100644
--- a/y2020/vision/extrinsics_calibration.cc
+++ b/y2020/vision/extrinsics_calibration.cc
@@ -2,6 +2,7 @@
 
 #include "Eigen/Dense"
 #include "Eigen/Geometry"
+#include "absl/flags/flag.h"
 #include "absl/strings/str_format.h"
 
 #include "aos/events/logging/log_reader.h"
@@ -15,11 +16,11 @@
 #include "frc971/wpilib/imu_batch_generated.h"
 #include "y2020/control_loops/superstructure/superstructure_status_generated.h"
 
-DEFINE_string(pi, "pi-7971-2", "Pi name to calibrate.");
-DEFINE_bool(plot, false, "Whether to plot the resulting data.");
-DEFINE_bool(turret, false, "If true, the camera is on the turret");
-DEFINE_string(base_intrinsics, "",
-              "Intrinsics to use for extrinsics calibration.");
+ABSL_FLAG(std::string, pi, "pi-7971-2", "Pi name to calibrate.");
+ABSL_FLAG(bool, plot, false, "Whether to plot the resulting data.");
+ABSL_FLAG(bool, turret, false, "If true, the camera is on the turret");
+ABSL_FLAG(std::string, base_intrinsics, "",
+          "Intrinsics to use for extrinsics calibration.");
 
 namespace frc971::vision {
 namespace chrono = std::chrono;
@@ -46,7 +47,7 @@
         aos::configuration::GetNode(factory.configuration(), "roborio");
 
     std::optional<uint16_t> pi_number =
-        aos::network::ParsePiOrOrinNumber(FLAGS_pi);
+        aos::network::ParsePiOrOrinNumber(absl::GetFlag(FLAGS_pi));
     CHECK(pi_number);
     LOG(INFO) << "Pi " << *pi_number;
     const aos::Node *const pi_node = aos::configuration::GetNode(
@@ -65,13 +66,13 @@
 
     aos::FlatbufferDetachedBuffer<calibration::CameraCalibration> intrinsics =
         aos::JsonFileToFlatbuffer<calibration::CameraCalibration>(
-            FLAGS_base_intrinsics);
+            absl::GetFlag(FLAGS_base_intrinsics));
     // Now, hook Calibration up to everything.
     Calibration extractor(&factory, pi_event_loop.get(), imu_event_loop.get(),
-                          FLAGS_pi, &intrinsics.message(), TargetType::kCharuco,
-                          "/camera", &data);
+                          absl::GetFlag(FLAGS_pi), &intrinsics.message(),
+                          TargetType::kCharuco, "/camera", &data);
 
-    if (FLAGS_turret) {
+    if (absl::GetFlag(FLAGS_turret)) {
       aos::NodeEventLoopFactory *roborio_factory =
           factory.GetNodeEventLoopFactory(roborio_node->name()->string_view());
       roborio_event_loop->MakeWatcher(
@@ -141,7 +142,7 @@
                    nominal_board_to_world.inverse())
                    .transpose();
 
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     Plot(data, calibration_parameters);
   }
 }
diff --git a/y2020/vision/sift/BUILD b/y2020/vision/sift/BUILD
index a220664..96afd01 100644
--- a/y2020/vision/sift/BUILD
+++ b/y2020/vision/sift/BUILD
@@ -21,7 +21,8 @@
         ":get_gaussian_kernel",
         "//aos/testing:googletest",
         "//third_party:opencv",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -158,7 +159,8 @@
     deps = [
         ":fast_gaussian",
         "//third_party:opencv",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -175,7 +177,8 @@
         ":fast_gaussian_all",
         "//third_party:halide_runtime",
         "//third_party:opencv",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -204,7 +207,8 @@
         "//aos/time",
         "//third_party:opencv",
         "//y2020/vision/sift:sift971",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2020/vision/sift/fast_gaussian.h b/y2020/vision/sift/fast_gaussian.h
index d9a5f07..4e246e9 100644
--- a/y2020/vision/sift/fast_gaussian.h
+++ b/y2020/vision/sift/fast_gaussian.h
@@ -3,7 +3,8 @@
 
 #include <type_traits>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/core/mat.hpp>
 
 #include "HalideBuffer.h"
diff --git a/y2020/vision/sift/get_gaussian_kernel_test.cc b/y2020/vision/sift/get_gaussian_kernel_test.cc
index 3d2674f..854db64 100644
--- a/y2020/vision/sift/get_gaussian_kernel_test.cc
+++ b/y2020/vision/sift/get_gaussian_kernel_test.cc
@@ -2,7 +2,8 @@
 
 #include <tuple>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <opencv2/core/mat.hpp>
diff --git a/y2020/vision/sift/sift971.cc b/y2020/vision/sift/sift971.cc
index 21f9a97..1df8d1c 100644
--- a/y2020/vision/sift/sift971.cc
+++ b/y2020/vision/sift/sift971.cc
@@ -110,7 +110,8 @@
 #include <iostream>
 #include <mutex>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/core/hal/hal.hpp>
 #include <opencv2/imgproc.hpp>
 
diff --git a/y2020/vision/sift/testing_sift.cc b/y2020/vision/sift/testing_sift.cc
index c0d4ca2..73b5d08 100644
--- a/y2020/vision/sift/testing_sift.cc
+++ b/y2020/vision/sift/testing_sift.cc
@@ -1,6 +1,8 @@
 #include <memory>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgcodecs.hpp>
 #include <opencv2/imgproc.hpp>
@@ -10,15 +12,16 @@
 #include "y2020/vision/sift/fast_gaussian.h"
 #include "y2020/vision/sift/sift971.h"
 
-DEFINE_string(image, "", "Image to test with");
+ABSL_FLAG(std::string, image, "", "Image to test with");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
   cv::setNumThreads(4);
 
-  const cv::Mat raw_image = cv::imread(FLAGS_image);
-  CHECK(!raw_image.empty()) << ": Failed to read: " << FLAGS_image;
+  const cv::Mat raw_image = cv::imread(absl::GetFlag(FLAGS_image));
+  CHECK(!raw_image.empty())
+      << ": Failed to read: " << absl::GetFlag(FLAGS_image);
   CHECK_EQ(CV_8UC3, raw_image.type());
 #if 0
   cv::Mat color_image;
diff --git a/y2020/vision/tools/python_code/camera_param_test.cc b/y2020/vision/tools/python_code/camera_param_test.cc
index f47c327..68d7b4d 100644
--- a/y2020/vision/tools/python_code/camera_param_test.cc
+++ b/y2020/vision/tools/python_code/camera_param_test.cc
@@ -1,6 +1,7 @@
 #include <unistd.h>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 #include <opencv2/features2d.hpp>
 #include <opencv2/imgproc.hpp>
diff --git a/y2020/vision/viewer.cc b/y2020/vision/viewer.cc
index 8ba2955..c44490e 100644
--- a/y2020/vision/viewer.cc
+++ b/y2020/vision/viewer.cc
@@ -1,6 +1,7 @@
 #include <map>
 #include <random>
 
+#include "absl/flags/flag.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/features2d.hpp>
 #include <opencv2/highgui/highgui.hpp>
@@ -13,12 +14,13 @@
 #include "frc971/vision/vision_generated.h"
 #include "y2020/vision/sift/sift_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_bool(show_features, true, "Show the SIFT features that matched.");
-DEFINE_string(channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(bool, show_features, true, "Show the SIFT features that matched.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
 
-DEFINE_string(capture, "",
-              "If set, capture a single image and save it to this filename.");
+ABSL_FLAG(std::string, capture, "",
+          "If set, capture a single image and save it to this filename.");
 
 namespace frc971::vision {
 namespace {
@@ -72,8 +74,8 @@
   cv::Mat rgb_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
   cv::cvtColor(image_color_mat, rgb_image, cv::COLOR_YUV2BGR_YUYV);
 
-  if (!FLAGS_capture.empty()) {
-    cv::imwrite(FLAGS_capture, rgb_image);
+  if (!absl::GetFlag(FLAGS_capture).empty()) {
+    cv::imwrite(absl::GetFlag(FLAGS_capture), rgb_image);
     return false;
   }
 
@@ -88,7 +90,8 @@
                  5);
     }
 
-    if (FLAGS_show_features && match->image_matches() != nullptr &&
+    if (absl::GetFlag(FLAGS_show_features) &&
+        match->image_matches() != nullptr &&
         match->image_matches()->size() > 0) {
       // Iterate through matches and draw matched keypoints
       for (uint model_match_ind = 0;
@@ -138,15 +141,16 @@
   palette_ = cv::Mat(3, 5, CV_8U, &colors);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
-  image_fetcher = event_loop.MakeFetcher<CameraImage>(FLAGS_channel);
+  image_fetcher =
+      event_loop.MakeFetcher<CameraImage>(absl::GetFlag(FLAGS_channel));
 
   // If we want to show the features, we have to use the detailed channel
-  std::string result_channel = FLAGS_channel;
-  if (FLAGS_show_features) {
+  std::string result_channel = absl::GetFlag(FLAGS_channel);
+  if (absl::GetFlag(FLAGS_show_features)) {
     result_channel += "/detailed";
   }
   match_fetcher =
diff --git a/y2020/vision/viewer_replay.cc b/y2020/vision/viewer_replay.cc
index ee1c8d5..98b1f34 100644
--- a/y2020/vision/viewer_replay.cc
+++ b/y2020/vision/viewer_replay.cc
@@ -1,3 +1,4 @@
+#include "absl/flags/flag.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/features2d.hpp>
 #include <opencv2/highgui/highgui.hpp>
@@ -8,9 +9,9 @@
 #include "aos/init.h"
 #include "frc971/vision/vision_generated.h"
 
-DEFINE_string(node, "pi1", "Node name to replay.");
-DEFINE_string(image_save_prefix, "/tmp/img",
-              "Prefix to use for saving images from the logfile.");
+ABSL_FLAG(std::string, node, "pi1", "Node name to replay.");
+ABSL_FLAG(std::string, image_save_prefix, "/tmp/img",
+          "Prefix to use for saving images from the logfile.");
 
 namespace frc971::vision {
 namespace {
@@ -22,7 +23,8 @@
   reader.Register();
   const aos::Node *node = nullptr;
   if (aos::configuration::MultiNode(reader.configuration())) {
-    node = aos::configuration::GetNode(reader.configuration(), FLAGS_node);
+    node = aos::configuration::GetNode(reader.configuration(),
+                                       absl::GetFlag(FLAGS_node));
   }
   std::unique_ptr<aos::EventLoop> event_loop =
       reader.event_loop_factory()->MakeEventLoop("player", node);
@@ -38,7 +40,7 @@
     }
 
     cv::imshow("Display", image_mat);
-    if (!FLAGS_image_save_prefix.empty()) {
+    if (!absl::GetFlag(FLAGS_image_save_prefix).empty()) {
       cv::imwrite("/tmp/img" + std::to_string(image_count++) + ".png",
                   image_mat);
     }
diff --git a/y2020/wpilib_interface.cc b/y2020/wpilib_interface.cc
index f3ff00f..2213c16 100644
--- a/y2020/wpilib_interface.cc
+++ b/y2020/wpilib_interface.cc
@@ -20,8 +20,8 @@
 #include "frc971/wpilib/ahal/VictorSP.h"
 #undef ERROR
 
+#include "absl/flags/flag.h"
 #include "ctre/phoenix6/TalonFX.hpp"
-#include "gflags/gflags.h"
 
 #include "aos/commonmath.h"
 #include "aos/events/event_loop.h"
@@ -55,9 +55,9 @@
 #include "y2020/control_loops/superstructure/superstructure_output_generated.h"
 #include "y2020/control_loops/superstructure/superstructure_position_static.h"
 
-DEFINE_bool(shooter_tuning, true,
-            "If true, reads from ball beambreak sensors and sends shooter "
-            "tuning readings");
+ABSL_FLAG(bool, shooter_tuning, true,
+          "If true, reads from ball beambreak sensors and sends shooter "
+          "tuning readings");
 
 using ::aos::monotonic_clock;
 using ::y2020::constants::Values;
@@ -258,7 +258,7 @@
   }
 
   void Start() override {
-    if (FLAGS_shooter_tuning) {
+    if (absl::GetFlag(FLAGS_shooter_tuning)) {
       AddToDMA(&ball_beambreak_reader_);
     }
   }
@@ -344,7 +344,7 @@
       builder.CheckOk(builder.Send(auto_mode_builder.Finish()));
     }
 
-    if (FLAGS_shooter_tuning) {
+    if (absl::GetFlag(FLAGS_shooter_tuning)) {
       // Distance between beambreak sensors, in meters.
       constexpr double kDistanceBetweenBeambreaks = 0.4813;
 
@@ -606,7 +606,7 @@
 
     sensor_reader.set_ball_intake_beambreak(make_unique<frc::DigitalInput>(4));
 
-    if (FLAGS_shooter_tuning) {
+    if (absl::GetFlag(FLAGS_shooter_tuning)) {
       sensor_reader.set_ball_beambreak_inputs(
           make_unique<frc::DigitalInput>(6), make_unique<frc::DigitalInput>(7));
     }
diff --git a/y2021_bot3/BUILD b/y2021_bot3/BUILD
index 7d898f5..e3c70ff 100644
--- a/y2021_bot3/BUILD
+++ b/y2021_bot3/BUILD
@@ -30,8 +30,9 @@
         "//frc971/control_loops:pose",
         "//frc971/control_loops:static_zeroing_single_dof_profiled_subsystem",
         "//y2021_bot3/control_loops/drivetrain:polydrivetrain_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2021_bot3/constants.cc b/y2021_bot3/constants.cc
index 63ebf7a..71b591b 100644
--- a/y2021_bot3/constants.cc
+++ b/y2021_bot3/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc b/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc
index 089250b..c40e616 100644
--- a/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc
@@ -1,6 +1,7 @@
 #include <chrono>
 #include <memory>
 
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -10,8 +11,8 @@
 #include "frc971/control_loops/team_number_test_environment.h"
 #include "y2021_bot3/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace y2021_bot3::control_loops::superstructure::testing {
 
@@ -42,11 +43,11 @@
     phased_loop_handle_ = test_event_loop_->AddPhasedLoop(
         [this](int) { SendPositionMessage(); }, dt());
 
-    if (!FLAGS_output_folder.empty()) {
-      unlink(FLAGS_output_folder.c_str());
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_folder).c_str());
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
diff --git a/y2022/BUILD b/y2022/BUILD
index bce1f66..8727aaf 100644
--- a/y2022/BUILD
+++ b/y2022/BUILD
@@ -230,8 +230,9 @@
         "//y2022/control_loops/superstructure/climber:climber_plants",
         "//y2022/control_loops/superstructure/intake:intake_plants",
         "//y2022/control_loops/superstructure/turret:turret_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2022/actors/autonomous_actor.cc b/y2022/actors/autonomous_actor.cc
index 3fcb5ec..4f70ec9 100644
--- a/y2022/actors/autonomous_actor.cc
+++ b/y2022/actors/autonomous_actor.cc
@@ -4,6 +4,8 @@
 #include <cinttypes>
 #include <cmath>
 
+#include "absl/flags/flag.h"
+
 #include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/util/math.h"
@@ -12,11 +14,11 @@
 #include "y2022/constants.h"
 #include "y2022/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
-DEFINE_bool(rapid_react, true,
-            "If true, run the main rapid react autonomous mode");
-DEFINE_bool(rapid_react_two, false,
-            "If true, run the two ball rapid react autonomous mode");
+ABSL_FLAG(bool, spline_auto, false, "If true, define a spline autonomous mode");
+ABSL_FLAG(bool, rapid_react, true,
+          "If true, run the main rapid react autonomous mode");
+ABSL_FLAG(bool, rapid_react_two, false,
+          "If true, run the two ball rapid react autonomous mode");
 
 namespace y2022::actors {
 namespace {
@@ -96,14 +98,14 @@
     return;
   }
   sent_starting_position_ = false;
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     test_spline_ =
         PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
                              std::placeholders::_1, alliance_),
                    SplineDirection::kForward);
 
     starting_position_ = test_spline_->starting_position();
-  } else if (FLAGS_rapid_react) {
+  } else if (absl::GetFlag(FLAGS_rapid_react)) {
     rapid_react_splines_ = {
         PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
                              std::placeholders::_1, alliance_),
@@ -116,7 +118,7 @@
                    SplineDirection::kForward)};
     starting_position_ = rapid_react_splines_.value()[0].starting_position();
     CHECK(starting_position_);
-  } else if (FLAGS_rapid_react_two) {
+  } else if (absl::GetFlag(FLAGS_rapid_react_two)) {
     rapid_react_two_spline_ = {
         PlanSpline(std::bind(&AutonomousSplines::SplineTwoBall1, &auto_splines_,
                              std::placeholders::_1, alliance_),
@@ -172,11 +174,11 @@
     AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
     return false;
   }
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     SplineAuto();
-  } else if (FLAGS_rapid_react) {
+  } else if (absl::GetFlag(FLAGS_rapid_react)) {
     RapidReact();
-  } else if (FLAGS_rapid_react_two) {
+  } else if (absl::GetFlag(FLAGS_rapid_react_two)) {
     RapidReactTwo();
   }
 
diff --git a/y2022/constants.cc b/y2022/constants.cc
index 7ad6213..de2b4fb 100644
--- a/y2022/constants.cc
+++ b/y2022/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2022/control_loops/drivetrain/trajectory_generator_main.cc b/y2022/control_loops/drivetrain/trajectory_generator_main.cc
index 9a59811..899a978 100644
--- a/y2022/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2022/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
@@ -8,8 +10,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -22,7 +24,7 @@
       &event_loop, ::y2022::control_loops::drivetrain::GetDrivetrainConfig());
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2022/control_loops/superstructure/BUILD b/y2022/control_loops/superstructure/BUILD
index 0a72b71..650fa99 100644
--- a/y2022/control_loops/superstructure/BUILD
+++ b/y2022/control_loops/superstructure/BUILD
@@ -152,8 +152,9 @@
         ":superstructure_status_fbs",
         "//frc971/control_loops:control_loops_fbs",
         "//frc971/control_loops:profiled_subsystem_fbs",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/functional:bind_front",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2022/control_loops/superstructure/catapult/catapult_main.cc b/y2022/control_loops/superstructure/catapult/catapult_main.cc
index 5124745..62b5271 100644
--- a/y2022/control_loops/superstructure/catapult/catapult_main.cc
+++ b/y2022/control_loops/superstructure/catapult/catapult_main.cc
@@ -109,8 +109,6 @@
 
 int Main(int /*argc*/, char ** /*argv*/) {
   OSQPSolve();
-
-  gflags::ShutDownCommandLineFlags();
   return 0;
 }
 
diff --git a/y2022/control_loops/superstructure/catapult/catapult_test.cc b/y2022/control_loops/superstructure/catapult/catapult_test.cc
index 0077633..0aec698 100644
--- a/y2022/control_loops/superstructure/catapult/catapult_test.cc
+++ b/y2022/control_loops/superstructure/catapult/catapult_test.cc
@@ -1,6 +1,7 @@
 #include "frc971/control_loops/catapult/catapult.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "y2022/control_loops/superstructure/catapult/catapult_plant.h"
diff --git a/y2022/control_loops/superstructure/collision_avoidance.cc b/y2022/control_loops/superstructure/collision_avoidance.cc
index 33e4d6e..5b6cee6 100644
--- a/y2022/control_loops/superstructure/collision_avoidance.cc
+++ b/y2022/control_loops/superstructure/collision_avoidance.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 
 #include "absl/functional/bind_front.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace y2022::control_loops::superstructure {
 
diff --git a/y2022/control_loops/superstructure/superstructure.cc b/y2022/control_loops/superstructure/superstructure.cc
index dca0a96..b5cb3f3 100644
--- a/y2022/control_loops/superstructure/superstructure.cc
+++ b/y2022/control_loops/superstructure/superstructure.cc
@@ -1,13 +1,15 @@
 #include "y2022/control_loops/superstructure/superstructure.h"
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/event_loop.h"
 #include "aos/flatbuffer_merge.h"
 #include "aos/network/team_number.h"
 #include "frc971/zeroing/wrap.h"
 #include "y2022/control_loops/superstructure/collision_avoidance.h"
 
-DEFINE_bool(ignore_distance, false,
-            "If true, ignore distance when shooting and obay joystick_reader");
+ABSL_FLAG(bool, ignore_distance, false,
+          "If true, ignore distance when shooting and obay joystick_reader");
 
 namespace y2022::control_loops::superstructure {
 
@@ -140,7 +142,7 @@
 
     constants::Values::ShotParams shot_params;
     const double distance_to_goal = aimer_.DistanceToGoal();
-    if (!FLAGS_ignore_distance && unsafe_goal->auto_aim() &&
+    if (!absl::GetFlag(FLAGS_ignore_distance) && unsafe_goal->auto_aim() &&
         values_->shot_interpolation_table.GetInRange(distance_to_goal,
                                                      &shot_params)) {
       flatbuffers::FlatBufferBuilder *catapult_goal_fbb =
diff --git a/y2022/control_loops/superstructure/superstructure_lib_test.cc b/y2022/control_loops/superstructure/superstructure_lib_test.cc
index eb33f29..8eaa7f6 100644
--- a/y2022/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2022/control_loops/superstructure/superstructure_lib_test.cc
@@ -1,6 +1,7 @@
 #include <chrono>
 #include <memory>
 
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -16,8 +17,8 @@
 #include "y2022/control_loops/superstructure/superstructure.h"
 #include "y2022/control_loops/superstructure/turret/turret_plant.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace y2022::control_loops::superstructure::testing {
 namespace chrono = std::chrono;
@@ -275,11 +276,11 @@
 
     SetEnabled(true);
 
-    if (!FLAGS_output_folder.empty()) {
-      unlink(FLAGS_output_folder.c_str());
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_folder).c_str());
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
diff --git a/y2022/control_loops/superstructure/superstructure_replay.cc b/y2022/control_loops/superstructure/superstructure_replay.cc
index d7f03e6..70640de 100644
--- a/y2022/control_loops/superstructure/superstructure_replay.cc
+++ b/y2022/control_loops/superstructure/superstructure_replay.cc
@@ -3,7 +3,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original superstructure status data will be on the
 // /original/superstructure channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/log_writer.h"
@@ -15,14 +15,14 @@
 #include "y2022/constants.h"
 #include "y2022/control_loops/superstructure/superstructure.h"
 
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/superstructure_replay/",
-              "Logs all channels to the provided logfile.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/superstructure_replay/",
+          "Logs all channels to the provided logfile.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -40,11 +40,11 @@
   aos::NodeEventLoopFactory *roborio =
       factory.GetNodeEventLoopFactory("roborio");
 
-  unlink(FLAGS_output_folder.c_str());
+  unlink(absl::GetFlag(FLAGS_output_folder).c_str());
   std::unique_ptr<aos::EventLoop> logger_event_loop =
       roborio->MakeEventLoop("logger");
   auto logger = std::make_unique<aos::logger::Logger>(logger_event_loop.get());
-  logger->StartLoggingOnRun(FLAGS_output_folder);
+  logger->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
 
   roborio->OnStartup([roborio]() {
     roborio->AlwaysStart<y2022::control_loops::superstructure::Superstructure>(
diff --git a/y2022/localizer/imu_main.cc b/y2022/localizer/imu_main.cc
index 03dfc58..75af90f 100644
--- a/y2022/localizer/imu_main.cc
+++ b/y2022/localizer/imu_main.cc
@@ -1,16 +1,19 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/realtime.h"
 #include "frc971/imu_reader/imu.h"
 #include "y2022/constants.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   PCHECK(system("sudo chmod 644 /dev/adis16505") == 0)
       << ": Failed to set read permissions on IMU device.";
diff --git a/y2022/localizer/localizer.cc b/y2022/localizer/localizer.cc
index c4ccf85..0e8a7e5 100644
--- a/y2022/localizer/localizer.cc
+++ b/y2022/localizer/localizer.cc
@@ -1,12 +1,14 @@
 #include "y2022/localizer/localizer.h"
 
+#include "absl/flags/flag.h"
+
 #include "aos/json_to_flatbuffer.h"
 #include "frc971/control_loops/c2d.h"
 #include "frc971/wpilib/imu_batch_generated.h"
 #include "y2022/constants.h"
 
-DEFINE_bool(ignore_accelerometer, false,
-            "If set, ignores the accelerometer readings.");
+ABSL_FLAG(bool, ignore_accelerometer, false,
+          "If set, ignores the accelerometer readings.");
 
 namespace frc971::controls {
 
@@ -377,7 +379,7 @@
   constexpr size_t kShareStates = kNModelStates;
   static_assert(kUseModelThreshold < kUseAccelThreshold);
   if (using_model_) {
-    if (!FLAGS_ignore_accelerometer &&
+    if (!absl::GetFlag(FLAGS_ignore_accelerometer) &&
         filtered_residual_ > kUseAccelThreshold) {
       hysteresis_count_++;
     } else {
diff --git a/y2022/localizer/localizer_main.cc b/y2022/localizer/localizer_main.cc
index 29c2f1e..19f4f8a 100644
--- a/y2022/localizer/localizer_main.cc
+++ b/y2022/localizer/localizer_main.cc
@@ -1,15 +1,18 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2022/control_loops/drivetrain/drivetrain_base.h"
 #include "y2022/localizer/localizer.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   frc971::controls::EventLoopLocalizer localizer(
diff --git a/y2022/localizer/localizer_replay.cc b/y2022/localizer/localizer_replay.cc
index a3baf3b..753d011 100644
--- a/y2022/localizer/localizer_replay.cc
+++ b/y2022/localizer/localizer_replay.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -12,11 +12,11 @@
 #include "y2022/localizer/localizer.h"
 #include "y2022/localizer/localizer_schema.h"
 
-DEFINE_string(config, "y2022/aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_int32(team, 7971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/replayed",
-              "Name of the folder to write replayed logs to.");
+ABSL_FLAG(std::string, config, "y2022/aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(int32_t, team, 7971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/replayed",
+          "Name of the folder to write replayed logs to.");
 
 // TODO(james): Currently, this replay produces logfiles that can't be read due
 // to time estimation issues. Pending the active refactorings of the
@@ -24,10 +24,10 @@
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   // sort logfiles
   const std::vector<aos::logger::LogFile> logfiles =
@@ -52,7 +52,7 @@
   const std::vector<std::string> nodes_to_log = {"imu"};
   std::vector<std::unique_ptr<aos::util::LoggerState>> loggers =
       aos::util::MakeLoggersForNodes(reader.event_loop_factory(), nodes_to_log,
-                                     FLAGS_output_folder);
+                                     absl::GetFlag(FLAGS_output_folder));
 
   const aos::Node *node = nullptr;
   if (aos::configuration::MultiNode(reader.configuration())) {
diff --git a/y2022/localizer/localizer_test.cc b/y2022/localizer/localizer_test.cc
index 0db26b6..bcee192 100644
--- a/y2022/localizer/localizer_test.cc
+++ b/y2022/localizer/localizer_test.cc
@@ -1,5 +1,6 @@
 #include "y2022/localizer/localizer.h"
 
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -10,8 +11,8 @@
 #include "y2022/control_loops/superstructure/superstructure_status_generated.h"
 #include "y2022/vision/target_estimate_generated.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace frc971::controls::testing {
 typedef ModelBasedLocalizer::ModelState ModelState;
@@ -496,11 +497,11 @@
     CHECK(status_fetcher_.Fetch());
     CHECK(status_fetcher_->zeroed());
 
-    if (!FLAGS_output_folder.empty()) {
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
       logger_event_loop_ =
           event_loop_factory_.MakeEventLoop("logger", imu_node_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
diff --git a/y2022/setpoint_setter.cc b/y2022/setpoint_setter.cc
index fa1e536..b99d238 100644
--- a/y2022/setpoint_setter.cc
+++ b/y2022/setpoint_setter.cc
@@ -1,15 +1,15 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2022/setpoint_generated.h"
 
-DEFINE_double(catapult_position, 0.03, "Catapult shot position");
-DEFINE_double(catapult_velocity, 18.0, "Catapult shot velocity");
-DEFINE_double(turret, 0.0, "Turret setpoint");
+ABSL_FLAG(double, catapult_position, 0.03, "Catapult shot position");
+ABSL_FLAG(double, catapult_velocity, 18.0, "Catapult shot velocity");
+ABSL_FLAG(double, turret, 0.0, "Turret setpoint");
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 using y2022::input::joysticks::Setpoint;
 
@@ -17,7 +17,7 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
@@ -27,9 +27,11 @@
 
   Setpoint::Builder setpoint_builder = builder.MakeBuilder<Setpoint>();
 
-  setpoint_builder.add_catapult_position(FLAGS_catapult_position);
-  setpoint_builder.add_catapult_velocity(FLAGS_catapult_velocity);
-  setpoint_builder.add_turret(FLAGS_turret);
+  setpoint_builder.add_catapult_position(
+      absl::GetFlag(FLAGS_catapult_position));
+  setpoint_builder.add_catapult_velocity(
+      absl::GetFlag(FLAGS_catapult_velocity));
+  setpoint_builder.add_turret(absl::GetFlag(FLAGS_turret));
   builder.CheckOk(builder.Send(setpoint_builder.Finish()));
 
   return 0;
diff --git a/y2022/vision/ball_color.cc b/y2022/vision/ball_color.cc
index 930142f..17db26e 100644
--- a/y2022/vision/ball_color.cc
+++ b/y2022/vision/ball_color.cc
@@ -4,7 +4,8 @@
 #include <cmath>
 #include <thread>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "opencv2/imgproc.hpp"
 #include <opencv2/highgui/highgui.hpp>
 
diff --git a/y2022/vision/ball_color_main.cc b/y2022/vision/ball_color_main.cc
index 5f05b34..67d7711 100644
--- a/y2022/vision/ball_color_main.cc
+++ b/y2022/vision/ball_color_main.cc
@@ -1,3 +1,5 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2022/constants.h"
@@ -7,7 +9,8 @@
 // bazel run //y2022/vision:ball_color_detector -- --config
 // y2022/aos_config.json
 //   --override_hostname pi-7971-1  --ignore_timestamps true
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 namespace y2022::vision {
 namespace {
@@ -16,7 +19,7 @@
 
 void BallColorDetectorMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   std::shared_ptr<const constants::Values> values =
diff --git a/y2022/vision/ball_color_test.cc b/y2022/vision/ball_color_test.cc
index 96f59aa..6f018d1 100644
--- a/y2022/vision/ball_color_test.cc
+++ b/y2022/vision/ball_color_test.cc
@@ -2,7 +2,7 @@
 
 #include <cmath>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
 #include "gtest/gtest.h"
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc.hpp>
@@ -12,9 +12,6 @@
 #include "aos/testing/test_logging.h"
 #include "y2022/constants.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
-
 namespace y2022::vision::testing {
 
 class BallColorTest : public ::testing::Test {
diff --git a/y2022/vision/blob_detector.cc b/y2022/vision/blob_detector.cc
index 70ff1b2..887960d 100644
--- a/y2022/vision/blob_detector.cc
+++ b/y2022/vision/blob_detector.cc
@@ -4,6 +4,7 @@
 #include <optional>
 #include <string>
 
+#include "absl/flags/flag.h"
 #include "opencv2/features2d.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/imgproc.hpp"
@@ -12,28 +13,30 @@
 #include "aos/time/time.h"
 #include "frc971/vision/geometry.h"
 
-DEFINE_bool(
-    use_outdoors, true,
-    "If set, use the color filters and exposure for an outdoor setting.");
-DEFINE_int32(red_delta, 50, "Required difference between green pixels vs. red");
-DEFINE_int32(blue_delta, -20,
-             "Required difference between green pixels vs. blue");
-DEFINE_int32(outdoors_red_delta, 70,
-             "Required difference between green pixels vs. red when using "
-             "--use_outdoors");
-DEFINE_int32(outdoors_blue_delta, -10,
-             "Required difference between green pixels vs. blue when using "
-             "--use_outdoors");
+ABSL_FLAG(bool, use_outdoors, true,
+          "If set, use the color filters and exposure for an outdoor setting.");
+ABSL_FLAG(int32_t, red_delta, 50,
+          "Required difference between green pixels vs. red");
+ABSL_FLAG(int32_t, blue_delta, -20,
+          "Required difference between green pixels vs. blue");
+ABSL_FLAG(int32_t, outdoors_red_delta, 70,
+          "Required difference between green pixels vs. red when using "
+          "--use_outdoors");
+ABSL_FLAG(int32_t, outdoors_blue_delta, -10,
+          "Required difference between green pixels vs. blue when using "
+          "--use_outdoors");
 
 namespace y2022::vision {
 
 cv::Mat BlobDetector::ThresholdImage(cv::Mat bgr_image) {
   cv::Mat binarized_image(cv::Size(bgr_image.cols, bgr_image.rows), CV_8UC1);
 
-  const int red_delta =
-      (FLAGS_use_outdoors ? FLAGS_outdoors_red_delta : FLAGS_red_delta);
-  const int blue_delta =
-      (FLAGS_use_outdoors ? FLAGS_outdoors_blue_delta : FLAGS_blue_delta);
+  const int red_delta = (absl::GetFlag(FLAGS_use_outdoors)
+                             ? absl::GetFlag(FLAGS_outdoors_red_delta)
+                             : absl::GetFlag(FLAGS_red_delta));
+  const int blue_delta = (absl::GetFlag(FLAGS_use_outdoors)
+                              ? absl::GetFlag(FLAGS_outdoors_blue_delta)
+                              : absl::GetFlag(FLAGS_blue_delta));
 
   for (int row = 0; row < bgr_image.rows; row++) {
     for (int col = 0; col < bgr_image.cols; col++) {
diff --git a/y2022/vision/calibrate_extrinsics.cc b/y2022/vision/calibrate_extrinsics.cc
index 7b53d67..3388853 100644
--- a/y2022/vision/calibrate_extrinsics.cc
+++ b/y2022/vision/calibrate_extrinsics.cc
@@ -1,5 +1,6 @@
 #include "Eigen/Dense"
 #include "Eigen/Geometry"
+#include "absl/flags/flag.h"
 #include "absl/strings/str_format.h"
 
 #include "aos/events/logging/log_reader.h"
@@ -14,16 +15,17 @@
 #include "frc971/wpilib/imu_batch_generated.h"
 #include "y2022/control_loops/superstructure/superstructure_status_generated.h"
 
-DEFINE_string(pi, "pi-7971-2", "Pi name to calibrate.");
-DEFINE_bool(plot, false, "Whether to plot the resulting data.");
-DEFINE_bool(turret, true, "If true, the camera is on the turret");
-DEFINE_string(target_type, "charuco",
-              "Type of target: aruco|charuco|charuco_diamond");
-DEFINE_string(image_channel, "/camera", "Channel to listen for images on");
-DEFINE_string(output_logs, "/tmp/calibration/",
-              "Output folder for visualization logs.");
-DEFINE_string(base_intrinsics, "",
-              "Intrinsics to use for extrinsics calibration.");
+ABSL_FLAG(std::string, pi, "pi-7971-2", "Pi name to calibrate.");
+ABSL_FLAG(bool, plot, false, "Whether to plot the resulting data.");
+ABSL_FLAG(bool, turret, true, "If true, the camera is on the turret");
+ABSL_FLAG(std::string, target_type, "charuco",
+          "Type of target: aruco|charuco|charuco_diamond");
+ABSL_FLAG(std::string, image_channel, "/camera",
+          "Channel to listen for images on");
+ABSL_FLAG(std::string, output_logs, "/tmp/calibration/",
+          "Output folder for visualization logs.");
+ABSL_FLAG(std::string, base_intrinsics, "",
+          "Intrinsics to use for extrinsics calibration.");
 
 namespace frc971::vision {
 namespace chrono = std::chrono;
@@ -36,7 +38,7 @@
 void Main(int argc, char **argv) {
   CalibrationData data;
   std::optional<uint16_t> pi_number =
-      aos::network::ParsePiOrOrinNumber(FLAGS_pi);
+      aos::network::ParsePiOrOrinNumber(absl::GetFlag(FLAGS_pi));
   CHECK(pi_number);
   const std::string pi_name = absl::StrCat("pi", *pi_number);
   LOG(INFO) << "Pi " << *pi_number;
@@ -83,29 +85,30 @@
     std::unique_ptr<aos::EventLoop> logger_loop =
         factory.MakeEventLoop("logger", pi_node);
     aos::logger::Logger logger(logger_loop.get());
-    logger.StartLoggingOnRun(FLAGS_output_logs);
+    logger.StartLoggingOnRun(absl::GetFlag(FLAGS_output_logs));
 
     TargetType target_type = TargetType::kCharuco;
-    if (FLAGS_target_type == "aruco") {
+    if (absl::GetFlag(FLAGS_target_type) == "aruco") {
       target_type = TargetType::kAruco;
-    } else if (FLAGS_target_type == "charuco") {
+    } else if (absl::GetFlag(FLAGS_target_type) == "charuco") {
       target_type = TargetType::kCharuco;
-    } else if (FLAGS_target_type == "charuco_diamond") {
+    } else if (absl::GetFlag(FLAGS_target_type) == "charuco_diamond") {
       target_type = TargetType::kCharucoDiamond;
     } else {
-      LOG(FATAL) << "Unknown target type: " << FLAGS_target_type
+      LOG(FATAL) << "Unknown target type: " << absl::GetFlag(FLAGS_target_type)
                  << ", expected: aruco|charuco|charuco_diamond";
     }
 
     aos::FlatbufferDetachedBuffer<calibration::CameraCalibration> intrinsics =
         aos::JsonFileToFlatbuffer<calibration::CameraCalibration>(
-            FLAGS_base_intrinsics);
+            absl::GetFlag(FLAGS_base_intrinsics));
     // Now, hook Calibration up to everything.
     Calibration extractor(&factory, pi_event_loop.get(), imu_event_loop.get(),
-                          FLAGS_pi, &intrinsics.message(), target_type,
-                          FLAGS_image_channel, &data);
+                          absl::GetFlag(FLAGS_pi), &intrinsics.message(),
+                          target_type, absl::GetFlag(FLAGS_image_channel),
+                          &data);
 
-    if (FLAGS_turret) {
+    if (absl::GetFlag(FLAGS_turret)) {
       aos::NodeEventLoopFactory *roborio_factory =
           factory.GetNodeEventLoopFactory(roborio_node->name()->string_view());
       roborio_event_loop->MakeWatcher(
@@ -253,12 +256,12 @@
                    nominal_board_to_world.inverse())
                    .transpose();
 
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     LOG(INFO) << "Showing visualization";
     Visualize(data, calibration_parameters);
   }
 
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     Plot(data, calibration_parameters);
   }
 }  // namespace vision
diff --git a/y2022/vision/camera_reader.cc b/y2022/vision/camera_reader.cc
index a077d09..b3e24a8 100644
--- a/y2022/vision/camera_reader.cc
+++ b/y2022/vision/camera_reader.cc
@@ -4,6 +4,7 @@
 #include <cmath>
 #include <thread>
 
+#include "absl/flags/flag.h"
 #include "opencv2/imgproc.hpp"
 
 #include "aos/events/event_loop.h"
@@ -15,7 +16,7 @@
 #include "frc971/vision/vision_generated.h"
 #include "y2022/vision/blob_detector.h"
 
-DEFINE_string(image_png, "", "A set of PNG images");
+ABSL_FLAG(std::string, image_png, "", "A set of PNG images");
 
 namespace y2022::vision {
 
@@ -145,9 +146,9 @@
 
 void CameraReader::ReadImage() {
   // Path is for reading from the Disk.
-  if (FLAGS_image_png != "") {
+  if (absl::GetFlag(FLAGS_image_png) != "") {
     std::vector<cv::String> file_list;
-    cv::glob(FLAGS_image_png + "/*.png", file_list, false);
+    cv::glob(absl::GetFlag(FLAGS_image_png) + "/*.png", file_list, false);
     for (auto file : file_list) {
       // Sleep for 0.05 seconds in order to not reach the max number of messages
       // that can be sent in a second.
diff --git a/y2022/vision/camera_reader_main.cc b/y2022/vision/camera_reader_main.cc
index 278f14b..80b19d2 100644
--- a/y2022/vision/camera_reader_main.cc
+++ b/y2022/vision/camera_reader_main.cc
@@ -1,3 +1,5 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2022/vision/camera_reader.h"
@@ -5,14 +7,15 @@
 // config used to allow running camera_reader independently.  E.g.,
 // bazel run //y2022/vision:camera_reader -- --config y2022/aos_config.json
 //   --override_hostname pi-7971-1  --ignore_timestamps true
-DECLARE_bool(use_outdoors);
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_double(duty_cycle, 0.65, "Duty cycle of the LEDs");
-DEFINE_uint32(exposure, 3,
-              "Exposure time, in 100us increments; 0 implies auto exposure");
-DEFINE_uint32(outdoors_exposure, 2,
-              "Exposure time when using --use_outdoors, in 100us increments; 0 "
-              "implies auto exposure");
+ABSL_DECLARE_FLAG(bool, use_outdoors);
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(double, duty_cycle, 0.65, "Duty cycle of the LEDs");
+ABSL_FLAG(uint32_t, exposure, 3,
+          "Exposure time, in 100us increments; 0 implies auto exposure");
+ABSL_FLAG(uint32_t, outdoors_exposure, 2,
+          "Exposure time when using --use_outdoors, in 100us increments; 0 "
+          "implies auto exposure");
 
 namespace y2022::vision {
 namespace {
@@ -21,7 +24,7 @@
 
 void CameraReaderMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   const aos::FlatbufferSpan<calibration::CalibrationData> calibration_data(
       CalibrationData());
@@ -38,8 +41,9 @@
   }
 
   V4L2Reader v4l2_reader(&event_loop, "/dev/video0");
-  const uint32_t exposure =
-      (FLAGS_use_outdoors ? FLAGS_outdoors_exposure : FLAGS_exposure);
+  const uint32_t exposure = (absl::GetFlag(FLAGS_use_outdoors)
+                                 ? absl::GetFlag(FLAGS_outdoors_exposure)
+                                 : absl::GetFlag(FLAGS_exposure));
   if (exposure > 0) {
     LOG(INFO) << "Setting camera to Manual Exposure mode with exposure = "
               << exposure << " or " << static_cast<double>(exposure) / 10.0
@@ -52,7 +56,7 @@
 
   CameraReader camera_reader(&event_loop, &calibration_data.message(),
                              &v4l2_reader);
-  camera_reader.SetDutyCycle(FLAGS_duty_cycle);
+  camera_reader.SetDutyCycle(absl::GetFlag(FLAGS_duty_cycle));
 
   event_loop.Run();
 }
diff --git a/y2022/vision/image_decimator.cc b/y2022/vision/image_decimator.cc
index e83659d..7a5d7de 100644
--- a/y2022/vision/image_decimator.cc
+++ b/y2022/vision/image_decimator.cc
@@ -1,9 +1,12 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/flatbuffers.h"
 #include "aos/init.h"
 #include "frc971/vision/vision_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 namespace frc971::vision {
 // Reads images from /camera and resends them in /camera/decimated at a fixed
@@ -38,7 +41,7 @@
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   frc971::vision::ImageDecimator decimator(&event_loop);
diff --git a/y2022/vision/target_estimator.cc b/y2022/vision/target_estimator.cc
index ff72b11..ecff719 100644
--- a/y2022/vision/target_estimator.cc
+++ b/y2022/vision/target_estimator.cc
@@ -1,5 +1,6 @@
 #include "y2022/vision/target_estimator.h"
 
+#include "absl/flags/flag.h"
 #include "absl/strings/str_format.h"
 #include "ceres/ceres.h"
 #include "opencv2/core/core.hpp"
@@ -13,20 +14,20 @@
 #include "frc971/vision/geometry.h"
 #include "y2022/constants.h"
 
-DEFINE_bool(freeze_roll, false, "If true, don't solve for roll");
-DEFINE_bool(freeze_pitch, false, "If true, don't solve for pitch");
-DEFINE_bool(freeze_yaw, false, "If true, don't solve for yaw");
-DEFINE_bool(freeze_camera_height, true,
-            "If true, don't solve for camera height");
-DEFINE_bool(freeze_angle_to_camera, true,
-            "If true, don't solve for polar angle to camera");
+ABSL_FLAG(bool, freeze_roll, false, "If true, don't solve for roll");
+ABSL_FLAG(bool, freeze_pitch, false, "If true, don't solve for pitch");
+ABSL_FLAG(bool, freeze_yaw, false, "If true, don't solve for yaw");
+ABSL_FLAG(bool, freeze_camera_height, true,
+          "If true, don't solve for camera height");
+ABSL_FLAG(bool, freeze_angle_to_camera, true,
+          "If true, don't solve for polar angle to camera");
 
-DEFINE_uint64(max_solver_iterations, 200,
-              "Maximum number of iterations for the ceres solver");
-DEFINE_bool(solver_output, false,
-            "If true, log the solver progress and results");
-DEFINE_bool(draw_projected_hub, true,
-            "If true, draw the projected hub when drawing an estimate");
+ABSL_FLAG(uint64_t, max_solver_iterations, 200,
+          "Maximum number of iterations for the ceres solver");
+ABSL_FLAG(bool, solver_output, false,
+          "If true, log the solver progress and results");
+ABSL_FLAG(bool, draw_projected_hub, true,
+          "If true, draw the projected hub when drawing an estimate");
 
 namespace y2022::vision {
 
@@ -231,26 +232,28 @@
 
   // Constrain the rotation to be around the localizer's, otherwise there can be
   // multiple solutions. There shouldn't be too much roll or pitch
-  if (FLAGS_freeze_roll) {
+  if (absl::GetFlag(FLAGS_freeze_roll)) {
     roll_ = roll_seed;
   }
   constexpr double kMaxRollDelta = 0.1;
-  SetBoundsOrFreeze(&roll_, FLAGS_freeze_roll, roll_seed - kMaxRollDelta,
-                    roll_seed + kMaxRollDelta, &problem);
+  SetBoundsOrFreeze(&roll_, absl::GetFlag(FLAGS_freeze_roll),
+                    roll_seed - kMaxRollDelta, roll_seed + kMaxRollDelta,
+                    &problem);
 
-  if (FLAGS_freeze_pitch) {
+  if (absl::GetFlag(FLAGS_freeze_pitch)) {
     pitch_ = pitch_seed;
   }
   constexpr double kMaxPitchDelta = 0.15;
-  SetBoundsOrFreeze(&pitch_, FLAGS_freeze_pitch, pitch_seed - kMaxPitchDelta,
-                    pitch_seed + kMaxPitchDelta, &problem);
+  SetBoundsOrFreeze(&pitch_, absl::GetFlag(FLAGS_freeze_pitch),
+                    pitch_seed - kMaxPitchDelta, pitch_seed + kMaxPitchDelta,
+                    &problem);
   // Constrain the yaw to where the target would be visible
   constexpr double kMaxYawDelta = M_PI / 4.0;
-  SetBoundsOrFreeze(&yaw_, FLAGS_freeze_yaw, M_PI - kMaxYawDelta,
+  SetBoundsOrFreeze(&yaw_, absl::GetFlag(FLAGS_freeze_yaw), M_PI - kMaxYawDelta,
                     M_PI + kMaxYawDelta, &problem);
 
   constexpr double kMaxHeightDelta = 0.1;
-  SetBoundsOrFreeze(&camera_height_, FLAGS_freeze_camera_height,
+  SetBoundsOrFreeze(&camera_height_, absl::GetFlag(FLAGS_freeze_camera_height),
                     camera_height_ - kMaxHeightDelta,
                     camera_height_ + kMaxHeightDelta, &problem);
 
@@ -261,15 +264,16 @@
 
   // Keep the angle between +/- half of the angle between piece of tape
   constexpr double kMaxAngle = ((2.0 * M_PI) / kNumPiecesOfTape) / 2.0;
-  SetBoundsOrFreeze(&angle_to_camera_, FLAGS_freeze_angle_to_camera, -kMaxAngle,
+  SetBoundsOrFreeze(&angle_to_camera_,
+                    absl::GetFlag(FLAGS_freeze_angle_to_camera), -kMaxAngle,
                     kMaxAngle, &problem);
 
   ceres::Solver::Options options;
-  options.minimizer_progress_to_stdout = FLAGS_solver_output;
+  options.minimizer_progress_to_stdout = absl::GetFlag(FLAGS_solver_output);
   options.gradient_tolerance = 1e-12;
   options.function_tolerance = 1e-16;
   options.parameter_tolerance = 1e-12;
-  options.max_num_iterations = FLAGS_max_solver_iterations;
+  options.max_num_iterations = absl::GetFlag(FLAGS_max_solver_iterations);
   ceres::Solver::Summary summary;
   ceres::Solve(options, &problem, &summary);
 
@@ -302,7 +306,7 @@
       kSigmoidCapacity /
       (1.0 + kSigmoidScalar * std::exp(-kSigmoidGrowthRate * std_dev));
 
-  if (FLAGS_solver_output) {
+  if (absl::GetFlag(FLAGS_solver_output)) {
     LOG(INFO) << summary.FullReport();
 
     LOG(INFO) << "roll: " << roll_;
@@ -608,7 +612,7 @@
 }
 
 void TargetEstimator::DrawEstimate(cv::Mat view_image) const {
-  if (FLAGS_draw_projected_hub) {
+  if (absl::GetFlag(FLAGS_draw_projected_hub)) {
     // Draw projected hub
     const auto H_hub_camera = ComputeHubCameraTransform(
         roll_, pitch_, yaw_, distance_, angle_to_camera_, camera_height_);
diff --git a/y2022/vision/viewer.cc b/y2022/vision/viewer.cc
index b0bcdac..7638a4c 100644
--- a/y2022/vision/viewer.cc
+++ b/y2022/vision/viewer.cc
@@ -2,6 +2,7 @@
 #include <map>
 #include <random>
 
+#include "absl/flags/flag.h"
 #include "absl/strings/str_format.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/features2d.hpp>
@@ -18,23 +19,25 @@
 #include "y2022/vision/target_estimate_generated.h"
 #include "y2022/vision/target_estimator.h"
 
-DEFINE_string(capture, "",
-              "If set, capture a single image and save it to this filename.");
-DEFINE_string(channel, "/camera", "Channel name for the image.");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_string(png_dir, "", "Path to a set of images to display.");
-DEFINE_string(png_pattern, "*", R"(Pattern to match pngs using '*'/'?'.)");
-DEFINE_string(calibration_node, "",
-              "If reading locally, use the calibration for this node");
-DEFINE_int32(
-    calibration_team_number, 971,
+ABSL_FLAG(std::string, capture, "",
+          "If set, capture a single image and save it to this filename.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(std::string, png_dir, "", "Path to a set of images to display.");
+ABSL_FLAG(std::string, png_pattern, "*",
+          R"(Pattern to match pngs using '*'/'?'.)");
+ABSL_FLAG(std::string, calibration_node, "",
+          "If reading locally, use the calibration for this node");
+ABSL_FLAG(
+    int32_t, calibration_team_number, 971,
     "If reading locally, use the calibration for a node with this team number");
-DEFINE_uint64(skip, 0,
-              "Number of images to skip if doing local reading (png_dir set).");
-DEFINE_bool(show_features, true, "Show the blobs.");
-DEFINE_bool(display_estimation, false,
-            "If true, display the target estimation graphically");
-DEFINE_bool(sort_by_time, true, "If true, sort the images by time");
+ABSL_FLAG(uint64_t, skip, 0,
+          "Number of images to skip if doing local reading (png_dir set).");
+ABSL_FLAG(bool, show_features, true, "Show the blobs.");
+ABSL_FLAG(bool, display_estimation, false,
+          "If true, display the target estimation graphically");
+ABSL_FLAG(bool, sort_by_time, true, "If true, sort the images by time");
 
 namespace y2022::vision {
 namespace {
@@ -121,8 +124,8 @@
   cv::Mat bgr_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
   cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
 
-  if (!FLAGS_capture.empty()) {
-    cv::imwrite(FLAGS_capture, bgr_image);
+  if (!absl::GetFlag(FLAGS_capture).empty()) {
+    cv::imwrite(absl::GetFlag(FLAGS_capture), bgr_image);
     return false;
   }
 
@@ -157,15 +160,16 @@
 
 void ViewerMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
-  image_fetcher =
-      event_loop.MakeFetcher<frc971::vision::CameraImage>(FLAGS_channel);
+  image_fetcher = event_loop.MakeFetcher<frc971::vision::CameraImage>(
+      absl::GetFlag(FLAGS_channel));
 
   target_estimate_fetcher =
-      event_loop.MakeFetcher<y2022::vision::TargetEstimate>(FLAGS_channel);
+      event_loop.MakeFetcher<y2022::vision::TargetEstimate>(
+          absl::GetFlag(FLAGS_channel));
 
   // Run the display loop
   event_loop.AddPhasedLoop(
@@ -199,11 +203,12 @@
 
 void ViewerLocal() {
   std::vector<cv::String> file_list;
-  cv::glob(absl::StrFormat("%s/%s.png", FLAGS_png_dir, FLAGS_png_pattern),
+  cv::glob(absl::StrFormat("%s/%s.png", absl::GetFlag(FLAGS_png_dir),
+                           absl::GetFlag(FLAGS_png_pattern)),
            file_list, false);
 
   // Sort the images by timestamp
-  if (FLAGS_sort_by_time) {
+  if (absl::GetFlag(FLAGS_sort_by_time)) {
     std::sort(file_list.begin(), file_list.end(),
               [](std::string_view filename_1, std::string_view filename_2) {
                 return (FindImageTimestamp(filename_1) <
@@ -215,9 +220,9 @@
       CalibrationData());
 
   const calibration::CameraCalibration *calibration =
-      CameraReader::FindCameraCalibration(&calibration_data.message(),
-                                          FLAGS_calibration_node,
-                                          FLAGS_calibration_team_number);
+      CameraReader::FindCameraCalibration(
+          &calibration_data.message(), absl::GetFlag(FLAGS_calibration_node),
+          absl::GetFlag(FLAGS_calibration_team_number));
   const auto intrinsics = CameraReader::CameraIntrinsics(calibration);
   const auto extrinsics = CameraReader::CameraExtrinsics(calibration);
   const auto dist_coeffs = CameraReader::CameraDistCoeffs(calibration);
@@ -228,7 +233,8 @@
 
   TargetEstimator estimator(intrinsics, extrinsics);
 
-  for (auto it = file_list.begin() + FLAGS_skip; it < file_list.end(); it++) {
+  for (auto it = file_list.begin() + absl::GetFlag(FLAGS_skip);
+       it < file_list.end(); it++) {
     LOG(INFO) << "Reading file " << (it - file_list.begin()) << ": " << *it;
     cv::Mat image_mat =
         CameraReader::UndistortImage(cv::imread(it->c_str()), undistort_maps);
@@ -249,8 +255,9 @@
               << ")";
 
     estimator.Solve(blob_result.filtered_stats,
-                    FLAGS_display_estimation ? std::make_optional(ret_image)
-                                             : std::nullopt);
+                    absl::GetFlag(FLAGS_display_estimation)
+                        ? std::make_optional(ret_image)
+                        : std::nullopt);
     if (blob_result.filtered_blobs.size() > 0) {
       estimator.DrawEstimate(ret_image);
       LOG(INFO) << "Read file " << (it - file_list.begin()) << ": " << *it;
@@ -277,7 +284,7 @@
 // Quick and lightweight viewer for images
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
-  if (FLAGS_png_dir != "")
+  if (absl::GetFlag(FLAGS_png_dir) != "")
     y2022::vision::ViewerLocal();
   else
     y2022::vision::ViewerMain();
diff --git a/y2022/vision/viewer_replay.cc b/y2022/vision/viewer_replay.cc
index 15427e4..1df3363 100644
--- a/y2022/vision/viewer_replay.cc
+++ b/y2022/vision/viewer_replay.cc
@@ -12,19 +12,20 @@
 #include "y2022/control_loops/superstructure/superstructure_status_generated.h"
 #include "y2022/vision/blob_detector.h"
 
-DEFINE_string(pi, "pi3", "Node name to replay.");
-DEFINE_string(image_save_prefix, "/tmp/img",
-              "Prefix to use for saving images from the logfile.");
-DEFINE_bool(display, false, "If true, display the images with a timeout.");
-DEFINE_bool(detected_only, false,
-            "If true, only write images which had blobs (unfiltered) detected");
-DEFINE_bool(filtered_only, false,
-            "If true, only write images which had blobs (filtered) detected");
-DEFINE_bool(match_timestamps, false,
-            "If true, name the files based on the time since the robot was "
-            "enabled (match start). Only consider images during this time");
-DEFINE_string(logger_pi_log, "/tmp/logger_pi/", "Path to logger pi log");
-DEFINE_string(roborio_log, "/tmp/roborio/", "Path to roborio log");
+ABSL_FLAG(std::string, pi, "pi3", "Node name to replay.");
+ABSL_FLAG(std::string, image_save_prefix, "/tmp/img",
+          "Prefix to use for saving images from the logfile.");
+ABSL_FLAG(bool, display, false, "If true, display the images with a timeout.");
+ABSL_FLAG(bool, detected_only, false,
+          "If true, only write images which had blobs (unfiltered) detected");
+ABSL_FLAG(bool, filtered_only, false,
+          "If true, only write images which had blobs (filtered) detected");
+ABSL_FLAG(bool, match_timestamps, false,
+          "If true, name the files based on the time since the robot was "
+          "enabled (match start). Only consider images during this time");
+ABSL_FLAG(std::string, logger_pi_log, "/tmp/logger_pi/",
+          "Path to logger pi log");
+ABSL_FLAG(std::string, roborio_log, "/tmp/roborio/", "Path to roborio log");
 
 namespace y2022::vision {
 namespace {
@@ -47,8 +48,8 @@
   data->match_end = monotonic_clock::min_time;
 
   // Open logfiles
-  aos::logger::LogReader reader(
-      aos::logger::SortParts(aos::logger::FindLogs(FLAGS_roborio_log)));
+  aos::logger::LogReader reader(aos::logger::SortParts(
+      aos::logger::FindLogs(absl::GetFlag(FLAGS_roborio_log))));
   reader.Register();
   const aos::Node *roborio =
       aos::configuration::GetNode(reader.configuration(), "roborio");
@@ -140,7 +141,7 @@
 
 // Extract images from the pi logs
 void ReplayPi(const ReplayData &data) {
-  if (FLAGS_match_timestamps) {
+  if (absl::GetFlag(FLAGS_match_timestamps)) {
     CHECK_NE(data.match_start, monotonic_clock::min_time)
         << "Can't use match timestamps if match never started";
     CHECK_NE(data.match_end, monotonic_clock::min_time)
@@ -148,11 +149,11 @@
   }
 
   // Open logfiles
-  aos::logger::LogReader reader(
-      aos::logger::SortParts(aos::logger::FindLogs(FLAGS_logger_pi_log)));
+  aos::logger::LogReader reader(aos::logger::SortParts(
+      aos::logger::FindLogs(absl::GetFlag(FLAGS_logger_pi_log))));
   reader.Register();
-  const aos::Node *pi =
-      aos::configuration::GetNode(reader.configuration(), FLAGS_pi);
+  const aos::Node *pi = aos::configuration::GetNode(reader.configuration(),
+                                                    absl::GetFlag(FLAGS_pi));
 
   std::unique_ptr<aos::EventLoop> event_loop =
       reader.event_loop_factory()->MakeEventLoop("player", pi);
@@ -171,7 +172,7 @@
         const auto superstructure_state = ClosestElement(
             data.superstructure_states, event_loop->monotonic_now());
 
-        if (FLAGS_match_timestamps) {
+        if (absl::GetFlag(FLAGS_match_timestamps)) {
           if (event_loop->monotonic_now() < data.match_start) {
             // Ignore prematch images if we only care about ones during the
             // match
@@ -190,23 +191,24 @@
         cv::cvtColor(image_color_mat, image_mat, cv::COLOR_YUV2BGR_YUYV);
 
         bool use_image = true;
-        if (FLAGS_detected_only || FLAGS_filtered_only) {
+        if (absl::GetFlag(FLAGS_detected_only) ||
+            absl::GetFlag(FLAGS_filtered_only)) {
           // TODO(milind): if adding target estimation here in the future,
           // undistortion is needed
           BlobDetector::BlobResult blob_result;
           BlobDetector::ExtractBlobs(image_mat, &blob_result);
 
-          use_image =
-              ((FLAGS_filtered_only ? blob_result.filtered_blobs.size()
-                                    : blob_result.unfiltered_blobs.size()) > 0);
+          use_image = ((absl::GetFlag(FLAGS_filtered_only)
+                            ? blob_result.filtered_blobs.size()
+                            : blob_result.unfiltered_blobs.size()) > 0);
         }
 
         if (use_image) {
-          if (!FLAGS_image_save_prefix.empty()) {
+          if (!absl::GetFlag(FLAGS_image_save_prefix).empty()) {
             std::stringstream image_name;
-            image_name << FLAGS_image_save_prefix;
+            image_name << absl::GetFlag(FLAGS_image_save_prefix);
 
-            if (FLAGS_match_timestamps) {
+            if (absl::GetFlag(FLAGS_match_timestamps)) {
               // Add the time since match start into the image for debugging.
               // We can match images with the game recording.
               image_name << "match_"
@@ -239,9 +241,12 @@
 
             cv::imwrite(image_name.str(), image_mat);
           }
-          if (FLAGS_display) {
+          if (absl::GetFlag(FLAGS_display)) {
             cv::imshow("Display", image_mat);
-            cv::waitKey(FLAGS_detected_only || FLAGS_filtered_only ? 10 : 1);
+            cv::waitKey(absl::GetFlag(FLAGS_detected_only) ||
+                                absl::GetFlag(FLAGS_filtered_only)
+                            ? 10
+                            : 1);
           }
         }
       });
diff --git a/y2022/wpilib_interface.cc b/y2022/wpilib_interface.cc
index dd2224c..1f82e91 100644
--- a/y2022/wpilib_interface.cc
+++ b/y2022/wpilib_interface.cc
@@ -11,6 +11,7 @@
 #include <mutex>
 #include <thread>
 
+#include "absl/flags/flag.h"
 #include "ctre/phoenix/CANifier.h"
 
 #include "frc971/wpilib/ahal/AnalogInput.h"
@@ -63,7 +64,8 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-DEFINE_bool(can_catapult, false, "If true, use CAN to control the catapult.");
+ABSL_FLAG(bool, can_catapult, false,
+          "If true, use CAN to control the catapult.");
 
 namespace y2022::wpilib {
 namespace {
@@ -804,7 +806,7 @@
         make_unique<::ctre::phoenix6::hardware::TalonFX>(2));
     superstructure_writer.set_superstructure_reading(superstructure_reading);
 
-    if (!FLAGS_can_catapult) {
+    if (!absl::GetFlag(FLAGS_can_catapult)) {
       superstructure_writer.set_catapult_falcon_1(make_unique<frc::TalonFX>(9));
     } else {
       std::shared_ptr<::ctre::phoenix6::hardware::TalonFX> catapult1 =
diff --git a/y2022_bot3/BUILD b/y2022_bot3/BUILD
index 08f4e2c..f827497 100644
--- a/y2022_bot3/BUILD
+++ b/y2022_bot3/BUILD
@@ -120,8 +120,9 @@
         "//y2022_bot3/control_loops/drivetrain:polydrivetrain_plants",
         "//y2022_bot3/control_loops/superstructure/climber:climber_plants",
         "//y2022_bot3/control_loops/superstructure/intake:intake_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2022_bot3/actors/BUILD b/y2022_bot3/actors/BUILD
index 783894f..8b99197 100644
--- a/y2022_bot3/actors/BUILD
+++ b/y2022_bot3/actors/BUILD
@@ -57,6 +57,7 @@
         "//y2022_bot3/control_loops/drivetrain:drivetrain_base",
         "//y2022_bot3/control_loops/superstructure:superstructure_goal_fbs",
         "//y2022_bot3/control_loops/superstructure:superstructure_status_fbs",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
diff --git a/y2022_bot3/actors/autonomous_actor.cc b/y2022_bot3/actors/autonomous_actor.cc
index 6c5c244..42fa02c 100644
--- a/y2022_bot3/actors/autonomous_actor.cc
+++ b/y2022_bot3/actors/autonomous_actor.cc
@@ -4,6 +4,8 @@
 #include <cinttypes>
 #include <cmath>
 
+#include "absl/flags/flag.h"
+
 #include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/util/math.h"
@@ -12,7 +14,7 @@
 #include "y2022_bot3/constants.h"
 #include "y2022_bot3/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
+ABSL_FLAG(bool, spline_auto, false, "If true, define a spline autonomous mode");
 
 namespace y2022_bot3::actors {
 
@@ -84,7 +86,7 @@
     return;
   }
   sent_starting_position_ = false;
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     test_spline_ =
         PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
                              std::placeholders::_1, alliance_),
@@ -135,7 +137,7 @@
     AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
     return false;
   }
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     SplineAuto();
   }
 
diff --git a/y2022_bot3/constants.cc b/y2022_bot3/constants.cc
index 8defbc6..49d8bb6 100644
--- a/y2022_bot3/constants.cc
+++ b/y2022_bot3/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2022_bot3/control_loops/drivetrain/trajectory_generator_main.cc b/y2022_bot3/control_loops/drivetrain/trajectory_generator_main.cc
index 644ae8d..66cf014 100644
--- a/y2022_bot3/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2022_bot3/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
@@ -8,8 +10,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -23,7 +25,7 @@
       ::y2022_bot3::control_loops::drivetrain::GetDrivetrainConfig());
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc b/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc
index 493d2f5..3f6a015 100644
--- a/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc
@@ -12,9 +12,6 @@
 #include "y2022_bot3/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2022_bot3/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
-
 namespace y2022_bot3::control_loops::superstructure::testing {
 namespace chrono = std::chrono;
 
diff --git a/y2022_bot3/control_loops/superstructure/superstructure_replay.cc b/y2022_bot3/control_loops/superstructure/superstructure_replay.cc
index e7b81cd..bc76582 100644
--- a/y2022_bot3/control_loops/superstructure/superstructure_replay.cc
+++ b/y2022_bot3/control_loops/superstructure/superstructure_replay.cc
@@ -3,7 +3,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original superstructure status data will be on the
 // /original/superstructure channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/log_writer.h"
@@ -15,14 +15,14 @@
 #include "y2022_bot3/constants.h"
 #include "y2022_bot3/control_loops/superstructure/superstructure.h"
 
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/superstructure_replay/",
-              "Logs all channels to the provided logfile.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/superstructure_replay/",
+          "Logs all channels to the provided logfile.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -40,11 +40,11 @@
   aos::NodeEventLoopFactory *roborio =
       factory.GetNodeEventLoopFactory("roborio");
 
-  unlink(FLAGS_output_folder.c_str());
+  unlink(absl::GetFlag(FLAGS_output_folder).c_str());
   std::unique_ptr<aos::EventLoop> logger_event_loop =
       roborio->MakeEventLoop("logger");
   auto logger = std::make_unique<aos::logger::Logger>(logger_event_loop.get());
-  logger->StartLoggingOnRun(FLAGS_output_folder);
+  logger->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
 
   roborio->OnStartup([roborio]() {
     roborio->AlwaysStart<
diff --git a/y2023/BUILD b/y2023/BUILD
index e3d9a2e..bd20085 100644
--- a/y2023/BUILD
+++ b/y2023/BUILD
@@ -260,8 +260,9 @@
         "//y2023/control_loops/superstructure/arm:arm_constants",
         "//y2023/control_loops/superstructure/roll:roll_plants",
         "//y2023/control_loops/superstructure/wrist:wrist_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -352,7 +353,8 @@
         "//aos:init",
         "//aos/events:shm_event_loop",
         "//frc971/input:joystick_state_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2023/autonomous/autonomous_actor.cc b/y2023/autonomous/autonomous_actor.cc
index a23f693..4583c6c 100644
--- a/y2023/autonomous/autonomous_actor.cc
+++ b/y2023/autonomous/autonomous_actor.cc
@@ -4,6 +4,8 @@
 #include <cinttypes>
 #include <cmath>
 
+#include "absl/flags/flag.h"
+
 #include "aos/logging/logging.h"
 #include "aos/util/math.h"
 #include "frc971/control_loops/drivetrain/localizer_generated.h"
@@ -12,10 +14,11 @@
 #include "y2023/control_loops/drivetrain/drivetrain_base.h"
 #include "y2023/control_loops/superstructure/arm/generated_graph.h"
 
-DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
-DEFINE_bool(charged_up, true, "If true run charged up autonomous mode");
-DEFINE_bool(charged_up_cable, false, "If true run cable side autonomous mode");
-DEFINE_bool(do_balance, true, "If true run the balance.");
+ABSL_FLAG(bool, spline_auto, false, "Run simple test S-spline auto mode.");
+ABSL_FLAG(bool, charged_up, true, "If true run charged up autonomous mode");
+ABSL_FLAG(bool, charged_up_cable, false,
+          "If true run cable side autonomous mode");
+ABSL_FLAG(bool, do_balance, true, "If true run the balance.");
 
 namespace y2023::autonomous {
 
@@ -56,14 +59,14 @@
       points_(control_loops::superstructure::arm::PointList()) {}
 
 void AutonomousActor::Replan() {
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     test_spline_ =
         PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
                              std::placeholders::_1, alliance_),
                    SplineDirection::kForward);
 
     starting_position_ = test_spline_->starting_position();
-  } else if (FLAGS_charged_up) {
+  } else if (absl::GetFlag(FLAGS_charged_up)) {
     AOS_LOG(INFO, "Charged up replanning!");
     charged_up_splines_ = {
         PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
@@ -81,7 +84,7 @@
 
     starting_position_ = charged_up_splines_.value()[0].starting_position();
     CHECK(starting_position_);
-  } else if (FLAGS_charged_up_cable) {
+  } else if (absl::GetFlag(FLAGS_charged_up_cable)) {
     charged_up_cable_splines_ = {
         PlanSpline(std::bind(&AutonomousSplines::SplineCable1, &auto_splines_,
                              std::placeholders::_1, alliance_),
@@ -121,11 +124,11 @@
     AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
     return false;
   }
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     SplineAuto();
-  } else if (FLAGS_charged_up) {
+  } else if (absl::GetFlag(FLAGS_charged_up)) {
     ChargedUp();
-  } else if (FLAGS_charged_up_cable) {
+  } else if (absl::GetFlag(FLAGS_charged_up_cable)) {
     ChargedUpCableSide();
   } else {
     AOS_LOG(WARNING, "No auto mode selected.");
@@ -300,7 +303,7 @@
         INFO, "Done backing up %lf s\n",
         aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
 
-    if (!FLAGS_do_balance) {
+    if (!absl::GetFlag(FLAGS_do_balance)) {
       StopSpitting();
       return;
     }
diff --git a/y2023/constants.cc b/y2023/constants.cc
index 0b89ef0..1f537b7 100644
--- a/y2023/constants.cc
+++ b/y2023/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2023/constants/constants_sender.cc b/y2023/constants/constants_sender.cc
index 757a374..5485a6e 100644
--- a/y2023/constants/constants_sender.cc
+++ b/y2023/constants/constants_sender.cc
@@ -1,5 +1,4 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,16 +8,17 @@
 #include "y2023/constants/constants_generated.h"
 #include "y2023/constants/constants_list_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the AOS config.");
-DEFINE_string(constants_path, "constants.json", "Path to the constant file");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the AOS config.");
+ABSL_FLAG(std::string, constants_path, "constants.json",
+          "Path to the constant file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
   frc971::constants::ConstantSender<y2023::Constants, y2023::ConstantsList>
-      constants_sender(&event_loop, FLAGS_constants_path);
+      constants_sender(&event_loop, absl::GetFlag(FLAGS_constants_path));
   // Don't need to call Run().
   return 0;
 }
diff --git a/y2023/control_loops/drivetrain/trajectory_generator_main.cc b/y2023/control_loops/drivetrain/trajectory_generator_main.cc
index 03731e8..4908582 100644
--- a/y2023/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2023/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
@@ -8,8 +10,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -22,7 +24,7 @@
       &event_loop, ::y2023::control_loops::drivetrain::GetDrivetrainConfig());
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2023/control_loops/superstructure/arm/BUILD b/y2023/control_loops/superstructure/arm/BUILD
index a54f72c..c8ecaff 100644
--- a/y2023/control_loops/superstructure/arm/BUILD
+++ b/y2023/control_loops/superstructure/arm/BUILD
@@ -171,7 +171,7 @@
         "//frc971/control_loops:fixed_quadrature",
         "//frc971/control_loops/double_jointed_arm:ekf",
         "//y2023/control_loops/superstructure/roll:roll_plants",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
         "@org_tuxfamily_eigen//:eigen",
     ],
 )
diff --git a/y2023/control_loops/superstructure/arm/arm_design.cc b/y2023/control_loops/superstructure/arm/arm_design.cc
index 8c5664e..07439d6 100644
--- a/y2023/control_loops/superstructure/arm/arm_design.cc
+++ b/y2023/control_loops/superstructure/arm/arm_design.cc
@@ -1,3 +1,5 @@
+#include "absl/flags/flag.h"
+
 #include "aos/analysis/in_process_plotter.h"
 #include "aos/init.h"
 #include "frc971/control_loops/dlqr.h"
@@ -5,17 +7,17 @@
 #include "frc971/control_loops/jacobian.h"
 #include "y2023/control_loops/superstructure/arm/arm_constants.h"
 
-DEFINE_double(lqr_proximal_pos, 0.15, "Position LQR gain");
-DEFINE_double(lqr_proximal_vel, 4.0, "Velocity LQR gain");
-DEFINE_double(lqr_distal_pos, 0.20, "Position LQR gain");
-DEFINE_double(lqr_distal_vel, 4.0, "Velocity LQR gain");
-DEFINE_double(fx, 0.0, "X force");
-DEFINE_double(fy, 0.0, "y force");
+ABSL_FLAG(double, lqr_proximal_pos, 0.15, "Position LQR gain");
+ABSL_FLAG(double, lqr_proximal_vel, 4.0, "Velocity LQR gain");
+ABSL_FLAG(double, lqr_distal_pos, 0.20, "Position LQR gain");
+ABSL_FLAG(double, lqr_distal_vel, 4.0, "Velocity LQR gain");
+ABSL_FLAG(double, fx, 0.0, "X force");
+ABSL_FLAG(double, fy, 0.0, "y force");
 
-DEFINE_double(start0, 0.0, "starting position on proximal");
-DEFINE_double(start1, 0.0, "starting position on distal");
-DEFINE_double(goal0, 0.0, "goal position on proximal");
-DEFINE_double(goal1, 0.0, "goal position on distal");
+ABSL_FLAG(double, start0, 0.0, "starting position on proximal");
+ABSL_FLAG(double, start1, 0.0, "starting position on distal");
+ABSL_FLAG(double, goal0, 0.0, "goal position on proximal");
+ABSL_FLAG(double, goal1, 0.0, "goal position on distal");
 
 namespace y2023::control_loops::superstructure::arm {
 
@@ -26,14 +28,14 @@
 
   ::Eigen::Matrix<double, 4, 1> X = ::Eigen::Matrix<double, 4, 1>::Zero();
   ::Eigen::Matrix<double, 4, 1> goal = ::Eigen::Matrix<double, 4, 1>::Zero();
-  goal(0, 0) = FLAGS_goal0;
+  goal(0, 0) = absl::GetFlag(FLAGS_goal0);
   goal(1, 0) = 0;
-  goal(2, 0) = FLAGS_goal1;
+  goal(2, 0) = absl::GetFlag(FLAGS_goal1);
   goal(3, 0) = 0;
 
-  X(0, 0) = FLAGS_start0;
+  X(0, 0) = absl::GetFlag(FLAGS_start0);
   X(1, 0) = 0;
-  X(2, 0) = FLAGS_start1;
+  X(2, 0) = absl::GetFlag(FLAGS_start1);
   X(3, 0) = 0;
   ::Eigen::Matrix<double, 2, 1> U = ::Eigen::Matrix<double, 2, 1>::Zero();
 
@@ -52,10 +54,10 @@
   std::vector<double> torque0;
   std::vector<double> torque1;
 
-  const double kProximalPosLQR = FLAGS_lqr_proximal_pos;
-  const double kProximalVelLQR = FLAGS_lqr_proximal_vel;
-  const double kDistalPosLQR = FLAGS_lqr_distal_pos;
-  const double kDistalVelLQR = FLAGS_lqr_distal_vel;
+  const double kProximalPosLQR = absl::GetFlag(FLAGS_lqr_proximal_pos);
+  const double kProximalVelLQR = absl::GetFlag(FLAGS_lqr_proximal_vel);
+  const double kDistalPosLQR = absl::GetFlag(FLAGS_lqr_distal_pos);
+  const double kDistalVelLQR = absl::GetFlag(FLAGS_lqr_distal_vel);
   const ::Eigen::DiagonalMatrix<double, 4> Q =
       (::Eigen::DiagonalMatrix<double, 4>().diagonal()
            << 1.0 / ::std::pow(kProximalPosLQR, 2),
@@ -74,8 +76,9 @@
   {
     const ::Eigen::Matrix<double, 2, 1> torque =
         dynamics
-            .TorqueFromForce(X,
-                             ::Eigen::Matrix<double, 2, 1>(FLAGS_fx, FLAGS_fy))
+            .TorqueFromForce(
+                X, ::Eigen::Matrix<double, 2, 1>(absl::GetFlag(FLAGS_fx),
+                                                 absl::GetFlag(FLAGS_fy)))
             .transpose();
     LOG(INFO) << "Torque (N m): " << torque.transpose();
     const ::Eigen::Matrix<double, 2, 1> current =
diff --git a/y2023/control_loops/superstructure/arm/arm_trajectory_gen.cc b/y2023/control_loops/superstructure/arm/arm_trajectory_gen.cc
index 699cfcf..7116f92 100644
--- a/y2023/control_loops/superstructure/arm/arm_trajectory_gen.cc
+++ b/y2023/control_loops/superstructure/arm/arm_trajectory_gen.cc
@@ -1,8 +1,9 @@
 #include <iostream>
 #include <memory>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/shm_event_loop.h"
 #include "aos/flatbuffers.h"
@@ -24,7 +25,7 @@
 using y2023::control_loops::superstructure::arm::Path;
 using y2023::control_loops::superstructure::arm::Trajectory;
 
-DEFINE_string(output, "", "Defines the location of the output file");
+ABSL_FLAG(std::string, output, "", "Defines the location of the output file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
@@ -193,5 +194,5 @@
       fbb.Release());
 
   // This writes to a binary file so we can cache the optimization results
-  aos::WriteFlatbufferToFile(FLAGS_output, detatched_buffer);
+  aos::WriteFlatbufferToFile(absl::GetFlag(FLAGS_output), detatched_buffer);
 }
diff --git a/y2023/control_loops/superstructure/arm/trajectory.cc b/y2023/control_loops/superstructure/arm/trajectory.cc
index be339e4..f7ae5f9 100644
--- a/y2023/control_loops/superstructure/arm/trajectory.cc
+++ b/y2023/control_loops/superstructure/arm/trajectory.cc
@@ -1,7 +1,7 @@
 #include "y2023/control_loops/superstructure/arm/trajectory.h"
 
 #include "Eigen/Dense"
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/logging/logging.h"
 #include "frc971/control_loops/dlqr.h"
@@ -10,10 +10,10 @@
 #include "frc971/control_loops/runge_kutta.h"
 #include "y2023/control_loops/superstructure/arm/arm_trajectories_generated.h"
 
-DEFINE_double(lqr_proximal_pos, 0.5, "Position LQR gain");
-DEFINE_double(lqr_proximal_vel, 5, "Velocity LQR gain");
-DEFINE_double(lqr_distal_pos, 0.5, "Position LQR gain");
-DEFINE_double(lqr_distal_vel, 5, "Velocity LQR gain");
+ABSL_FLAG(double, lqr_proximal_pos, 0.5, "Position LQR gain");
+ABSL_FLAG(double, lqr_proximal_vel, 5, "Velocity LQR gain");
+ABSL_FLAG(double, lqr_distal_pos, 0.5, "Position LQR gain");
+ABSL_FLAG(double, lqr_distal_vel, 5, "Velocity LQR gain");
 
 namespace y2023::control_loops::superstructure::arm {
 
@@ -714,10 +714,10 @@
 ::Eigen::Matrix<double, 2, 6> TrajectoryFollower::ArmK_at_state(
     const Eigen::Ref<const ::Eigen::Matrix<double, 6, 1>> arm_X,
     const Eigen::Ref<const ::Eigen::Matrix<double, 2, 1>> arm_U) {
-  const double kProximalPos = FLAGS_lqr_proximal_pos;
-  const double kProximalVel = FLAGS_lqr_proximal_vel;
-  const double kDistalPos = FLAGS_lqr_distal_pos;
-  const double kDistalVel = FLAGS_lqr_distal_vel;
+  const double kProximalPos = absl::GetFlag(FLAGS_lqr_proximal_pos);
+  const double kProximalVel = absl::GetFlag(FLAGS_lqr_proximal_vel);
+  const double kDistalPos = absl::GetFlag(FLAGS_lqr_distal_pos);
+  const double kDistalVel = absl::GetFlag(FLAGS_lqr_distal_vel);
   const ::Eigen::DiagonalMatrix<double, 4> Q =
       (::Eigen::DiagonalMatrix<double, 4>().diagonal()
            << 1.0 / ::std::pow(kProximalPos, 2),
diff --git a/y2023/control_loops/superstructure/arm/trajectory_plot.cc b/y2023/control_loops/superstructure/arm/trajectory_plot.cc
index 8488d72..d2b6b59 100644
--- a/y2023/control_loops/superstructure/arm/trajectory_plot.cc
+++ b/y2023/control_loops/superstructure/arm/trajectory_plot.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/analysis/in_process_plotter.h"
 #include "aos/init.h"
@@ -12,16 +12,16 @@
 #include "y2023/control_loops/superstructure/roll/integral_hybrid_roll_plant.h"
 #include "y2023/control_loops/superstructure/roll/integral_roll_plant.h"
 
-DEFINE_bool(forwards, true, "If true, run the forwards simulation.");
-DEFINE_bool(plot, true, "If true, plot");
-DEFINE_bool(plot_thetas, true, "If true, plot the angles");
+ABSL_FLAG(bool, forwards, true, "If true, run the forwards simulation.");
+ABSL_FLAG(bool, plot, true, "If true, plot");
+ABSL_FLAG(bool, plot_thetas, true, "If true, plot the angles");
 
-DEFINE_double(alpha0_max, 15.0, "Max acceleration on joint 0.");
-DEFINE_double(alpha1_max, 10.0, "Max acceleration on joint 1.");
-DEFINE_double(alpha2_max, 90.0, "Max acceleration on joint 2.");
-DEFINE_double(vmax_plan, 9.5, "Max voltage to plan.");
-DEFINE_double(vmax_battery, 12.0, "Max battery voltage.");
-DEFINE_double(time, 2.0, "Simulation time.");
+ABSL_FLAG(double, alpha0_max, 15.0, "Max acceleration on joint 0.");
+ABSL_FLAG(double, alpha1_max, 10.0, "Max acceleration on joint 1.");
+ABSL_FLAG(double, alpha2_max, 90.0, "Max acceleration on joint 2.");
+ABSL_FLAG(double, vmax_plan, 9.5, "Max voltage to plan.");
+ABSL_FLAG(double, vmax_battery, 12.0, "Max battery voltage.");
+ABSL_FLAG(double, time, 2.0, "Simulation time.");
 
 namespace y2023::control_loops::superstructure::arm {
 using frc971::control_loops::MatrixGaussianQuadrature5;
@@ -55,16 +55,17 @@
 
   constexpr double sim_dt = 0.00505;
 
-  LOG(INFO) << "Planning with kAlpha0Max=" << FLAGS_alpha0_max
-            << ", kAlpha1Max=" << FLAGS_alpha1_max
-            << ", kAlpha2Max=" << FLAGS_alpha2_max;
+  LOG(INFO) << "Planning with kAlpha0Max=" << absl::GetFlag(FLAGS_alpha0_max)
+            << ", kAlpha1Max=" << absl::GetFlag(FLAGS_alpha1_max)
+            << ", kAlpha2Max=" << absl::GetFlag(FLAGS_alpha2_max);
 
   const ::Eigen::DiagonalMatrix<double, 3> alpha_unitizer(
       (::Eigen::DiagonalMatrix<double, 3>().diagonal()
-           << (1.0 / FLAGS_alpha0_max),
-       (1.0 / FLAGS_alpha1_max), (1.0 / FLAGS_alpha2_max))
+           << (1.0 / absl::GetFlag(FLAGS_alpha0_max)),
+       (1.0 / absl::GetFlag(FLAGS_alpha1_max)),
+       (1.0 / absl::GetFlag(FLAGS_alpha2_max)))
           .finished());
-  trajectory.OptimizeTrajectory(alpha_unitizer, FLAGS_vmax_plan);
+  trajectory.OptimizeTrajectory(alpha_unitizer, absl::GetFlag(FLAGS_vmax_plan));
 
   const ::std::vector<double> distance_array = trajectory.DistanceArray();
 
@@ -301,7 +302,7 @@
   ::std::cout << "Really stabilized P: " << arm_ekf.P_converged()
               << ::std::endl;
 
-  while (t < FLAGS_time) {
+  while (t < absl::GetFlag(FLAGS_time)) {
     t_array.push_back(t);
     arm_ekf.Correct(
         (::Eigen::Matrix<double, 2, 1>() << arm_X(0), arm_X(2)).finished(),
@@ -314,7 +315,8 @@
     follower.Update(
         (Eigen::Matrix<double, 9, 1>() << arm_ekf.X_hat(), roll.X_hat())
             .finished(),
-        disabled, sim_dt, FLAGS_vmax_plan, FLAGS_vmax_battery);
+        disabled, sim_dt, absl::GetFlag(FLAGS_vmax_plan),
+        absl::GetFlag(FLAGS_vmax_battery));
 
     const ::Eigen::Matrix<double, 3, 1> theta_t =
         trajectory.ThetaT(follower.goal()(0));
@@ -395,7 +397,7 @@
     t += sim_dt;
   }
 
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     aos::analysis::Plotter plotter;
 
     plotter.AddFigure();
@@ -488,7 +490,7 @@
     plotter.AddLine(t_array, torque2_hat_t_array, "torque2_hat");
     plotter.Publish();
 
-    if (FLAGS_plot_thetas) {
+    if (absl::GetFlag(FLAGS_plot_thetas)) {
       plotter.AddFigure();
       plotter.Title("Angles");
       plotter.AddLine(t_array, theta0_goal_t_array, "theta0_t_goal");
diff --git a/y2023/control_loops/superstructure/superstructure.cc b/y2023/control_loops/superstructure/superstructure.cc
index bfb7a9d..60881f2 100644
--- a/y2023/control_loops/superstructure/superstructure.cc
+++ b/y2023/control_loops/superstructure/superstructure.cc
@@ -7,8 +7,8 @@
 #include "frc971/zeroing/wrap.h"
 #include "y2023/control_loops/superstructure/arm/arm_trajectories_generated.h"
 
-DEFINE_bool(ignore_distance, false,
-            "If true, ignore distance when shooting and obay joystick_reader");
+ABSL_FLAG(bool, ignore_distance, false,
+          "If true, ignore distance when shooting and obay joystick_reader");
 
 namespace y2023::control_loops::superstructure {
 
diff --git a/y2023/control_loops/superstructure/superstructure_lib_test.cc b/y2023/control_loops/superstructure/superstructure_lib_test.cc
index 5973eee..cc6e3ae 100644
--- a/y2023/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2023/control_loops/superstructure/superstructure_lib_test.cc
@@ -15,8 +15,8 @@
 #include "y2023/control_loops/superstructure/roll/integral_roll_plant.h"
 #include "y2023/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace y2023::control_loops::superstructure::testing {
 namespace {
@@ -320,11 +320,11 @@
 
     SetEnabled(true);
 
-    if (!FLAGS_output_folder.empty()) {
-      unlink(FLAGS_output_folder.c_str());
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_folder).c_str());
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
diff --git a/y2023/control_loops/superstructure/superstructure_main.cc b/y2023/control_loops/superstructure/superstructure_main.cc
index 4a044b6..bc20e44 100644
--- a/y2023/control_loops/superstructure/superstructure_main.cc
+++ b/y2023/control_loops/superstructure/superstructure_main.cc
@@ -1,9 +1,11 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2023/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(arm_trajectories, "arm_trajectories_generated.bfbs",
-              "The path to the generated arm trajectories bfbs file.");
+ABSL_FLAG(std::string, arm_trajectories, "arm_trajectories_generated.bfbs",
+          "The path to the generated arm trajectories bfbs file.");
 
 using y2023::control_loops::superstructure::Superstructure;
 using y2023::control_loops::superstructure::arm::ArmTrajectories;
@@ -20,7 +22,7 @@
 
   auto trajectories =
       y2023::control_loops::superstructure::Superstructure::GetArmTrajectories(
-          FLAGS_arm_trajectories);
+          absl::GetFlag(FLAGS_arm_trajectories));
 
   std::shared_ptr<const y2023::constants::Values> values =
       std::make_shared<const y2023::constants::Values>(
diff --git a/y2023/control_loops/superstructure/superstructure_replay.cc b/y2023/control_loops/superstructure/superstructure_replay.cc
index 6f23ec2..1f13aeb 100644
--- a/y2023/control_loops/superstructure/superstructure_replay.cc
+++ b/y2023/control_loops/superstructure/superstructure_replay.cc
@@ -3,7 +3,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original superstructure status data will be on the
 // /original/superstructure channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/log_writer.h"
@@ -15,16 +15,16 @@
 #include "y2023/constants.h"
 #include "y2023/control_loops/superstructure/superstructure.h"
 
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/superstructure_replay/",
-              "Logs all channels to the provided logfile.");
-DEFINE_string(arm_trajectories, "arm/arm_trajectories_generated.bfbs",
-              "The path to the generated arm trajectories bfbs file.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/superstructure_replay/",
+          "Logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, arm_trajectories, "arm/arm_trajectories_generated.bfbs",
+          "The path to the generated arm trajectories bfbs file.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -42,15 +42,15 @@
   aos::NodeEventLoopFactory *roborio =
       factory.GetNodeEventLoopFactory("roborio");
 
-  unlink(FLAGS_output_folder.c_str());
+  unlink(absl::GetFlag(FLAGS_output_folder).c_str());
   std::unique_ptr<aos::EventLoop> logger_event_loop =
       roborio->MakeEventLoop("logger");
   auto logger = std::make_unique<aos::logger::Logger>(logger_event_loop.get());
-  logger->StartLoggingOnRun(FLAGS_output_folder);
+  logger->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
 
   auto trajectories =
       y2023::control_loops::superstructure::Superstructure::GetArmTrajectories(
-          FLAGS_arm_trajectories);
+          absl::GetFlag(FLAGS_arm_trajectories));
 
   roborio->OnStartup([roborio, &trajectories]() {
     roborio->AlwaysStart<y2023::control_loops::superstructure::Superstructure>(
diff --git a/y2023/joystick_republish.cc b/y2023/joystick_republish.cc
index ae6f340..9ea6a1a 100644
--- a/y2023/joystick_republish.cc
+++ b/y2023/joystick_republish.cc
@@ -1,7 +1,7 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,13 +9,13 @@
 #include "aos/init.h"
 #include "frc971/input/joystick_state_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
 
   aos::Sender<aos::JoystickState> sender(
diff --git a/y2023/localizer/localizer.cc b/y2023/localizer/localizer.cc
index a00ebe6..586ffb6 100644
--- a/y2023/localizer/localizer.cc
+++ b/y2023/localizer/localizer.cc
@@ -1,6 +1,6 @@
 #include "y2023/localizer/localizer.h"
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/containers/sized_array.h"
 #include "frc971/control_loops/drivetrain/localizer_generated.h"
@@ -8,28 +8,27 @@
 #include "frc971/vision/target_map_utils.h"
 #include "y2023/constants.h"
 
-DEFINE_double(max_pose_error, 1e-6,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_double(distortion_noise_scalar, 1.0,
-              "Scale the target pose distortion factor by this when computing "
-              "the noise.");
-DEFINE_double(
-    max_implied_yaw_error, 3.0,
+ABSL_FLAG(double, max_pose_error, 1e-6,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(double, distortion_noise_scalar, 1.0,
+          "Scale the target pose distortion factor by this when computing "
+          "the noise.");
+ABSL_FLAG(
+    double, max_implied_yaw_error, 3.0,
     "Reject target poses that imply a robot yaw of more than this many degrees "
     "off from our estimate.");
-DEFINE_double(
-    max_implied_teleop_yaw_error, 30.0,
+ABSL_FLAG(
+    double, max_implied_teleop_yaw_error, 30.0,
     "Reject target poses that imply a robot yaw of more than this many degrees "
     "off from our estimate.");
-DEFINE_double(max_distance_to_target, 5.0,
-              "Reject target poses that have a 3d distance of more than this "
-              "many meters.");
-DEFINE_double(max_auto_image_robot_speed, 2.0,
-              "Reject target poses when the robot is travelling faster than "
-              "this speed in auto.");
+ABSL_FLAG(double, max_distance_to_target, 5.0,
+          "Reject target poses that have a 3d distance of more than this "
+          "many meters.");
+ABSL_FLAG(double, max_auto_image_robot_speed, 2.0,
+          "Reject target poses when the robot is travelling faster than "
+          "this speed in auto.");
 
 namespace y2023::localizer {
 namespace {
@@ -348,8 +347,9 @@
   Eigen::Matrix<double, 3, 1> noises(1.0, 1.0, 0.5);
   noises /= 4.0;
   // Scale noise by the distortion factor for this detection
-  noises *= (1.0 + FLAGS_distortion_noise_scalar * target.distortion_factor() *
-                       std::exp(distance_to_target));
+  noises *=
+      (1.0 + absl::GetFlag(FLAGS_distortion_noise_scalar) *
+                 target.distortion_factor() * std::exp(distance_to_target));
 
   Eigen::Matrix3d R = Eigen::Matrix3d::Zero();
   R.diagonal() = noises.cwiseAbs2();
@@ -365,12 +365,13 @@
   if (!state_at_capture.has_value()) {
     VLOG(1) << "Rejecting image due to being too old.";
     return RejectImage(camera_index, RejectionReason::IMAGE_TOO_OLD, &builder);
-  } else if (target.pose_error() > FLAGS_max_pose_error) {
+  } else if (target.pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
     VLOG(1) << "Rejecting target due to high pose error "
             << target.pose_error();
     return RejectImage(camera_index, RejectionReason::HIGH_POSE_ERROR,
                        &builder);
-  } else if (target.pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+  } else if (target.pose_error_ratio() >
+             absl::GetFlag(FLAGS_max_pose_error_ratio)) {
     VLOG(1) << "Rejecting target due to high pose error ratio "
             << target.pose_error_ratio();
     return RejectImage(camera_index, RejectionReason::HIGH_POSE_ERROR_RATIO,
@@ -386,17 +387,19 @@
        state_at_capture.value()(StateIdx::kRightVelocity)) /
       2.0;
   const double yaw_threshold =
-      (utils_.MaybeInAutonomous() ? FLAGS_max_implied_yaw_error
-                                  : FLAGS_max_implied_teleop_yaw_error) *
+      (utils_.MaybeInAutonomous()
+           ? absl::GetFlag(FLAGS_max_implied_yaw_error)
+           : absl::GetFlag(FLAGS_max_implied_teleop_yaw_error)) *
       kDegToRad;
   if (utils_.MaybeInAutonomous() &&
-      (std::abs(robot_speed) > FLAGS_max_auto_image_robot_speed)) {
+      (std::abs(robot_speed) >
+       absl::GetFlag(FLAGS_max_auto_image_robot_speed))) {
     return RejectImage(camera_index, RejectionReason::ROBOT_TOO_FAST, &builder);
   } else if (std::abs(aos::math::NormalizeAngle(
                  camera_implied_theta - theta_at_capture)) > yaw_threshold) {
     return RejectImage(camera_index, RejectionReason::HIGH_IMPLIED_YAW_ERROR,
                        &builder);
-  } else if (distance_to_target > FLAGS_max_distance_to_target) {
+  } else if (distance_to_target > absl::GetFlag(FLAGS_max_distance_to_target)) {
     return RejectImage(camera_index, RejectionReason::HIGH_DISTANCE_TO_TARGET,
                        &builder);
   }
diff --git a/y2023/localizer/localizer_main.cc b/y2023/localizer/localizer_main.cc
index 98f0e81..40b3ee5 100644
--- a/y2023/localizer/localizer_main.cc
+++ b/y2023/localizer/localizer_main.cc
@@ -1,16 +1,19 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/constants/constants_sender_lib.h"
 #include "y2023/control_loops/drivetrain/drivetrain_base.h"
 #include "y2023/localizer/localizer.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<y2023::Constants>(&config.message());
 
diff --git a/y2023/localizer/localizer_replay.cc b/y2023/localizer/localizer_replay.cc
index 859b77e..55b81b1 100644
--- a/y2023/localizer/localizer_replay.cc
+++ b/y2023/localizer/localizer_replay.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -11,19 +11,19 @@
 #include "y2023/control_loops/drivetrain/drivetrain_base.h"
 #include "y2023/localizer/localizer.h"
 
-DEFINE_string(config, "y2023/aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_int32(team, 9971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/replayed",
-              "Name of the folder to write replayed logs to.");
+ABSL_FLAG(std::string, config, "y2023/aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(int32_t, team, 9971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/replayed",
+          "Name of the folder to write replayed logs to.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   // sort logfiles
   const std::vector<aos::logger::LogFile> logfiles =
@@ -50,7 +50,7 @@
   const std::vector<std::string> nodes_to_log = {"imu"};
   std::vector<std::unique_ptr<aos::util::LoggerState>> loggers =
       aos::util::MakeLoggersForNodes(reader.event_loop_factory(), nodes_to_log,
-                                     FLAGS_output_folder);
+                                     absl::GetFlag(FLAGS_output_folder));
 
   const aos::Node *node = nullptr;
   if (aos::configuration::MultiNode(reader.configuration())) {
diff --git a/y2023/localizer/localizer_test.cc b/y2023/localizer/localizer_test.cc
index c47e46e..79454ab 100644
--- a/y2023/localizer/localizer_test.cc
+++ b/y2023/localizer/localizer_test.cc
@@ -1,5 +1,8 @@
 #include "y2023/localizer/localizer.h"
 
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -13,9 +16,9 @@
 #include "y2023/control_loops/drivetrain/drivetrain_base.h"
 #include "y2023/localizer/status_generated.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
-DECLARE_double(max_distance_to_target);
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
+ABSL_DECLARE_FLAG(double, max_distance_to_target);
 
 namespace y2023::localizer::testing {
 
@@ -74,7 +77,7 @@
                 ->MakeFetcher<frc971::controls::LocalizerOutput>("/localizer")),
         status_fetcher_(
             imu_test_event_loop_->MakeFetcher<Status>("/localizer")) {
-    FLAGS_max_distance_to_target = 100.0;
+    absl::SetFlag(&FLAGS_max_distance_to_target, 100.0);
     {
       aos::TimerHandler *timer = roborio_test_event_loop_->AddTimer([this]() {
         {
@@ -191,11 +194,11 @@
     CHECK(status_fetcher_.Fetch());
     CHECK(status_fetcher_->imu()->zeroed());
 
-    if (!FLAGS_output_folder.empty()) {
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
       logger_event_loop_ =
           event_loop_factory_.MakeEventLoop("logger", imu_node_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
@@ -280,7 +283,7 @@
   double pose_error_ratio_ = 0.1;
   double implied_yaw_error_ = 0.0;
 
-  gflags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
 };
 
 // Test a simple scenario with no errors where the robot should just drive
diff --git a/y2023/localizer/map_expander.cc b/y2023/localizer/map_expander.cc
index 32efcd8..9582c6b 100644
--- a/y2023/localizer/map_expander.cc
+++ b/y2023/localizer/map_expander.cc
@@ -1,24 +1,25 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/init.h"
 #include "aos/util/file.h"
 #include "y2023/localizer/map_expander_lib.h"
 
-DEFINE_string(target_map, "y2023/vision/maps/target_map.json",
-              "Path to the target map JSON file.");
-DEFINE_string(relative_map, "y2023/constants/relative_scoring_map.json",
-              "Path to the relative scoring map JSON file.");
-DEFINE_string(output, "y2023/constants/scoring_map.json",
-              "Path to the output scoring map JSON file.");
+ABSL_FLAG(std::string, target_map, "y2023/vision/maps/target_map.json",
+          "Path to the target map JSON file.");
+ABSL_FLAG(std::string, relative_map,
+          "y2023/constants/relative_scoring_map.json",
+          "Path to the relative scoring map JSON file.");
+ABSL_FLAG(std::string, output, "y2023/constants/scoring_map.json",
+          "Path to the output scoring map JSON file.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<y2023::localizer::ScoringMap> map =
       y2023::localizer::ExpandMap(
-          aos::util::ReadFileToStringOrDie(FLAGS_relative_map),
-          aos::util::ReadFileToStringOrDie(FLAGS_target_map));
+          aos::util::ReadFileToStringOrDie(absl::GetFlag(FLAGS_relative_map)),
+          aos::util::ReadFileToStringOrDie(absl::GetFlag(FLAGS_target_map)));
   aos::util::WriteStringToFileOrDie(
-      FLAGS_output,
+      absl::GetFlag(FLAGS_output),
       aos::FlatbufferToJson(map, {.multi_line = true, .max_multi_line = true}));
   return EXIT_SUCCESS;
 }
diff --git a/y2023/rockpi/imu_main.cc b/y2023/rockpi/imu_main.cc
index d53b3fb..ed8bcb1 100644
--- a/y2023/rockpi/imu_main.cc
+++ b/y2023/rockpi/imu_main.cc
@@ -1,16 +1,19 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/realtime.h"
 #include "frc971/imu_reader/imu.h"
 #include "y2023/constants.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   frc971::imu::Imu imu(&event_loop,
diff --git a/y2023/vision/BUILD b/y2023/vision/BUILD
index 25f4d87..f415b6a 100644
--- a/y2023/vision/BUILD
+++ b/y2023/vision/BUILD
@@ -123,7 +123,8 @@
     deps = [
         "//third_party:opencv",
         "//y2023/constants:constants_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -357,8 +358,9 @@
         "//aos/events/logging:log_writer",
         "//aos/logging:log_namer",
         "//frc971/input:joystick_state_fbs",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -368,8 +370,9 @@
     hdrs = ["yolov5.h"],
     deps = [
         "//third_party:opencv",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/types:span",
     ] + cpu_select({
         "amd64": [
@@ -426,8 +429,9 @@
         "//aos/events:simulated_event_loop",
         "//aos/events/logging:log_reader",
         "//frc971/vision:vision_fbs",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2023/vision/april_detection_test.cc b/y2023/vision/april_detection_test.cc
index 71e34cb..9f4f8b7 100644
--- a/y2023/vision/april_detection_test.cc
+++ b/y2023/vision/april_detection_test.cc
@@ -1,6 +1,7 @@
 #include <string>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
diff --git a/y2023/vision/aprilrobotics.cc b/y2023/vision/aprilrobotics.cc
index 342e046..db9a4f2 100644
--- a/y2023/vision/aprilrobotics.cc
+++ b/y2023/vision/aprilrobotics.cc
@@ -1,24 +1,25 @@
 #include "y2023/vision/aprilrobotics.h"
 
+#include "absl/flags/flag.h"
 #include <opencv2/highgui.hpp>
 
 #include "y2023/vision/vision_util.h"
 
-DEFINE_bool(
-    debug, false,
+ABSL_FLAG(
+    bool, debug, false,
     "If true, dump a ton of debug and crash on the first valid detection.");
 
-DEFINE_double(min_decision_margin, 50.0,
-              "Minimum decision margin (confidence) for an apriltag detection");
-DEFINE_int32(pixel_border, 10,
-             "Size of image border within which to reject detected corners");
-DEFINE_double(
-    max_expected_distortion, 0.314,
+ABSL_FLAG(double, min_decision_margin, 50.0,
+          "Minimum decision margin (confidence) for an apriltag detection");
+ABSL_FLAG(int32_t, pixel_border, 10,
+          "Size of image border within which to reject detected corners");
+ABSL_FLAG(
+    double, max_expected_distortion, 0.314,
     "Maximum expected value for unscaled distortion factors. Will scale "
     "distortion factors so that this value (and a higher distortion) maps to "
     "1.0.");
-DEFINE_uint64(pose_estimation_iterations, 50,
-              "Number of iterations for apriltag pose estimation.");
+ABSL_FLAG(uint64_t, pose_estimation_iterations, 50,
+          "Number of iterations for apriltag pose estimation.");
 
 namespace y2023::vision {
 
@@ -56,7 +57,7 @@
   tag_detector_->nthreads = 6;
   tag_detector_->wp = workerpool_create(tag_detector_->nthreads);
   tag_detector_->qtp.min_white_black_diff = 5;
-  tag_detector_->debug = FLAGS_debug;
+  tag_detector_->debug = absl::GetFlag(FLAGS_debug);
 
   std::string hostname = aos::network::GetHostname();
 
@@ -178,7 +179,8 @@
   double distortion_factor =
       avg_distance /
       cv::norm(cv::Point2d(image_size_.width, image_size_.height));
-  return std::min(distortion_factor / FLAGS_max_expected_distortion, 1.0);
+  return std::min(
+      distortion_factor / absl::GetFlag(FLAGS_max_expected_distortion), 1.0);
 }
 
 std::vector<cv::Point2f> AprilRoboticsDetector::MakeCornerVector(
@@ -210,10 +212,10 @@
       .stride = image.cols,
       .buf = image.data,
   };
-  const uint32_t min_x = FLAGS_pixel_border;
-  const uint32_t max_x = image.cols - FLAGS_pixel_border;
-  const uint32_t min_y = FLAGS_pixel_border;
-  const uint32_t max_y = image.rows - FLAGS_pixel_border;
+  const uint32_t min_x = absl::GetFlag(FLAGS_pixel_border);
+  const uint32_t max_x = image.cols - absl::GetFlag(FLAGS_pixel_border);
+  const uint32_t min_y = absl::GetFlag(FLAGS_pixel_border);
+  const uint32_t max_y = image.rows - absl::GetFlag(FLAGS_pixel_border);
 
   ftrace_.FormatMessage("Starting detect\n");
   zarray_t *detections = apriltag_detector_detect(tag_detector_, &im);
@@ -228,7 +230,7 @@
     apriltag_detection_t *det;
     zarray_get(detections, i, &det);
 
-    if (det->decision_margin > FLAGS_min_decision_margin) {
+    if (det->decision_margin > absl::GetFlag(FLAGS_min_decision_margin)) {
       if (det->p[0][0] < min_x || det->p[0][0] > max_x ||
           det->p[1][0] < min_x || det->p[1][0] > max_x ||
           det->p[2][0] < min_x || det->p[2][0] > max_x ||
@@ -274,9 +276,9 @@
       apriltag_pose_t pose_2;
       double pose_error_1;
       double pose_error_2;
-      estimate_tag_pose_orthogonal_iteration(&info, &pose_error_1, &pose_1,
-                                             &pose_error_2, &pose_2,
-                                             FLAGS_pose_estimation_iterations);
+      estimate_tag_pose_orthogonal_iteration(
+          &info, &pose_error_1, &pose_1, &pose_error_2, &pose_2,
+          absl::GetFlag(FLAGS_pose_estimation_iterations));
 
       const aos::monotonic_clock::time_point after_pose_estimation =
           aos::monotonic_clock::now();
@@ -320,7 +322,7 @@
                                      .distortion_factor = distortion_factor,
                                      .pose_error_ratio = pose_error_ratio});
 
-      if (FLAGS_visualize) {
+      if (absl::GetFlag(FLAGS_visualize)) {
         // Draw raw (distorted) corner points in green
         cv::line(color_image, orig_corner_points[0], orig_corner_points[1],
                  cv::Scalar(0, 255, 0), 2);
@@ -349,7 +351,7 @@
       rejections_++;
     }
   }
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     // Display the result
     // Rotate by 180 degrees to make it upright
     if (flip_image_) {
@@ -368,7 +370,7 @@
 
   const aos::monotonic_clock::time_point end_time = aos::monotonic_clock::now();
 
-  if (FLAGS_debug) {
+  if (absl::GetFlag(FLAGS_debug)) {
     timeprofile_display(tag_detector_->tp);
   }
 
diff --git a/y2023/vision/aprilrobotics_main.cc b/y2023/vision/aprilrobotics_main.cc
index 5e5bad7..013730e 100644
--- a/y2023/vision/aprilrobotics_main.cc
+++ b/y2023/vision/aprilrobotics_main.cc
@@ -1,14 +1,17 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/constants/constants_sender_lib.h"
 #include "y2023/vision/aprilrobotics.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 namespace y2023::vision {
 void AprilViewerMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<Constants>(&config.message());
 
diff --git a/y2023/vision/calibrate_extrinsics.cc b/y2023/vision/calibrate_extrinsics.cc
index 59c27e6..8c00d65 100644
--- a/y2023/vision/calibrate_extrinsics.cc
+++ b/y2023/vision/calibrate_extrinsics.cc
@@ -17,19 +17,20 @@
 #include "y2023/constants/constants_generated.h"
 #include "y2023/vision/vision_util.h"
 
-DEFINE_string(pi, "pi-7971-2", "Pi name to calibrate.");
-DEFINE_bool(plot, false, "Whether to plot the resulting data.");
-DEFINE_string(target_type, "charuco_diamond",
-              "Type of target: aruco|charuco|charuco_diamond");
-DEFINE_string(image_channel, "/camera", "Channel to listen for images on");
-DEFINE_string(output_logs, "/tmp/calibration/",
-              "Output folder for visualization logs.");
-DEFINE_string(base_calibration, "",
-              "Intrinsics (and optionally extrinsics) to use for extrinsics "
-              "calibration.");
-DEFINE_string(output_calibration, "",
-              "Output json file to use for the resulting calibration "
-              "(intrinsics and extrinsics).");
+ABSL_FLAG(std::string, pi, "pi-7971-2", "Pi name to calibrate.");
+ABSL_FLAG(bool, plot, false, "Whether to plot the resulting data.");
+ABSL_FLAG(std::string, target_type, "charuco_diamond",
+          "Type of target: aruco|charuco|charuco_diamond");
+ABSL_FLAG(std::string, image_channel, "/camera",
+          "Channel to listen for images on");
+ABSL_FLAG(std::string, output_logs, "/tmp/calibration/",
+          "Output folder for visualization logs.");
+ABSL_FLAG(std::string, base_calibration, "",
+          "Intrinsics (and optionally extrinsics) to use for extrinsics "
+          "calibration.");
+ABSL_FLAG(std::string, output_calibration, "",
+          "Output json file to use for the resulting calibration "
+          "(intrinsics and extrinsics).");
 
 namespace frc971::vision {
 namespace chrono = std::chrono;
@@ -51,10 +52,11 @@
   std::unique_ptr<Calibration> extractor;
   void MaybeMakeExtractor() {
     if (imu_event_loop && pi_event_loop) {
-      TargetType target_type = TargetTypeFromString(FLAGS_target_type);
+      TargetType target_type =
+          TargetTypeFromString(absl::GetFlag(FLAGS_target_type));
       std::unique_ptr<aos::EventLoop> constants_event_loop =
           factory->MakeEventLoop("constants_fetcher", pi_event_loop->node());
-      if (FLAGS_base_calibration.empty()) {
+      if (absl::GetFlag(FLAGS_base_calibration).empty()) {
         frc971::constants::ConstantsFetcher<y2023::Constants> constants_fetcher(
             constants_event_loop.get());
         *intrinsics =
@@ -63,11 +65,12 @@
                 pi_event_loop->node()->name()->string_view()));
       } else {
         *intrinsics = aos::JsonFileToFlatbuffer<calibration::CameraCalibration>(
-            FLAGS_base_calibration);
+            absl::GetFlag(FLAGS_base_calibration));
       }
       extractor = std::make_unique<Calibration>(
-          factory, pi_event_loop.get(), imu_event_loop.get(), FLAGS_pi,
-          &intrinsics->message(), target_type, FLAGS_image_channel, data);
+          factory, pi_event_loop.get(), imu_event_loop.get(),
+          absl::GetFlag(FLAGS_pi), &intrinsics->message(), target_type,
+          absl::GetFlag(FLAGS_image_channel), data);
     }
   }
 };
@@ -75,7 +78,7 @@
 void Main(int argc, char **argv) {
   CalibrationData data;
   std::optional<uint16_t> pi_number =
-      aos::network::ParsePiOrOrinNumber(FLAGS_pi);
+      aos::network::ParsePiOrOrinNumber(absl::GetFlag(FLAGS_pi));
   CHECK(pi_number);
   const std::string pi_name = absl::StrCat("pi", *pi_number);
 
@@ -122,7 +125,8 @@
           factory.MakeEventLoop("logger", pi_node);
       accumulator_state.logger = std::make_unique<aos::logger::Logger>(
           accumulator_state.logger_event_loop.get());
-      accumulator_state.logger->StartLoggingOnRun(FLAGS_output_logs);
+      accumulator_state.logger->StartLoggingOnRun(
+          absl::GetFlag(FLAGS_output_logs));
       accumulator_state.MaybeMakeExtractor();
     });
 
@@ -227,8 +231,9 @@
       merged_calibration = aos::MergeFlatBuffers(&calibration.message(),
                                                  &solved_extrinsics.message());
 
-  if (!FLAGS_output_calibration.empty()) {
-    aos::WriteFlatbufferToJson(FLAGS_output_calibration, merged_calibration);
+  if (!absl::GetFlag(FLAGS_output_calibration).empty()) {
+    aos::WriteFlatbufferToJson(absl::GetFlag(FLAGS_output_calibration),
+                               merged_calibration);
   } else {
     LOG(WARNING) << "Calibration filename not provided, so not saving it";
   }
@@ -296,12 +301,12 @@
                    nominal_board_to_world.inverse())
                    .transpose();
 
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     LOG(INFO) << "Showing visualization";
     Visualize(data, calibration_parameters);
   }
 
-  if (FLAGS_plot) {
+  if (absl::GetFlag(FLAGS_plot)) {
     Plot(data, calibration_parameters);
   }
 }  // namespace vision
diff --git a/y2023/vision/calibrate_multi_cameras.cc b/y2023/vision/calibrate_multi_cameras.cc
index 48dffb9..8032c764 100644
--- a/y2023/vision/calibrate_multi_cameras.cc
+++ b/y2023/vision/calibrate_multi_cameras.cc
@@ -1,5 +1,7 @@
 #include <numeric>
 
+#include "absl/flags/flag.h"
+
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
@@ -26,31 +28,30 @@
 #include "y2023/vision/aprilrobotics.h"
 #include "y2023/vision/vision_util.h"
 
-DEFINE_bool(alt_view, false,
-            "If true, show visualization from field level, rather than above");
-DEFINE_string(config, "",
-              "If set, override the log's config file with this one.");
-DEFINE_string(constants_path, "y2023/constants/constants.json",
-              "Path to the constant file");
-DEFINE_double(max_pose_error, 5e-5,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_string(output_folder, "/tmp",
-              "Directory in which to store the updated calibration files");
-DEFINE_string(target_type, "charuco_diamond",
-              "Type of target being used [aruco, charuco, charuco_diamond]");
-DEFINE_int32(team_number, 0,
-             "Required: Use the calibration for a node with this team number");
-DEFINE_bool(use_full_logs, false,
-            "If true, extract data from logs with images");
-DEFINE_uint64(
-    wait_key, 1,
+ABSL_FLAG(bool, alt_view, false,
+          "If true, show visualization from field level, rather than above");
+ABSL_FLAG(std::string, config, "",
+          "If set, override the log's config file with this one.");
+ABSL_FLAG(std::string, constants_path, "y2023/constants/constants.json",
+          "Path to the constant file");
+ABSL_FLAG(double, max_pose_error, 5e-5,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(std::string, output_folder, "/tmp",
+          "Directory in which to store the updated calibration files");
+ABSL_FLAG(std::string, target_type, "charuco_diamond",
+          "Type of target being used [aruco, charuco, charuco_diamond]");
+ABSL_FLAG(int32_t, team_number, 0,
+          "Required: Use the calibration for a node with this team number");
+ABSL_FLAG(bool, use_full_logs, false,
+          "If true, extract data from logs with images");
+ABSL_FLAG(
+    uint64_t, wait_key, 1,
     "Time in ms to wait between images (0 to wait indefinitely until click)");
 
-DECLARE_int32(min_target_id);
-DECLARE_int32(max_target_id);
+ABSL_DECLARE_FLAG(int32_t, min_target_id);
+ABSL_DECLARE_FLAG(int32_t, max_target_id);
 
 // Calibrate extrinsic relationship between cameras using two targets
 // seen jointly between cameras.  Uses two types of information: 1)
@@ -179,7 +180,7 @@
   Eigen::Affine3d H_world_board;
   H_world_board = Eigen::Translation3d::Identity() *
                   Eigen::AngleAxisd(M_PI / 2.0, Eigen::Vector3d::UnitX());
-  if (FLAGS_alt_view) {
+  if (absl::GetFlag(FLAGS_alt_view)) {
     // Don't rotate -- this is like viewing from the side
     H_world_board = Eigen::Translation3d(0.0, 0.0, 3.0);
   }
@@ -218,7 +219,7 @@
     // Store this observation of the transform between two boards
     two_board_extrinsics_list.push_back(boardA_boardB);
 
-    if (FLAGS_visualize) {
+    if (absl::GetFlag(FLAGS_visualize)) {
       vis_robot_.DrawFrameAxes(
           H_world_board,
           std::string("board ") + std::to_string(target_poses[from_index].id),
@@ -264,7 +265,8 @@
       // This bit is just for visualization and checking purposes-- use the
       // last two-board observation to figure out the current estimate
       // between the two cameras
-      if (FLAGS_visualize && two_board_extrinsics_list.size() > 0) {
+      if (absl::GetFlag(FLAGS_visualize) &&
+          two_board_extrinsics_list.size() > 0) {
         draw_vis = true;
         TimestampedPiDetection &last_two_board_ext =
             two_board_extrinsics_list[two_board_extrinsics_list.size() - 1];
@@ -309,18 +311,18 @@
     }
   }
 
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     if (!rgb_image.empty()) {
       std::string image_name = node_name + " Image";
       cv::Mat rgb_small;
       cv::resize(rgb_image, rgb_small, cv::Size(), 0.5, 0.5);
       cv::imshow(image_name, rgb_small);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
     }
 
     if (draw_vis) {
       cv::imshow("View", vis_robot_.image_);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
       vis_robot_.ClearImage();
     }
   }
@@ -337,21 +339,22 @@
   for (const auto *target_pose_fbs : *map.target_poses()) {
     // Skip detections with invalid ids
     if (static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) <
-            FLAGS_min_target_id ||
+            absl::GetFlag(FLAGS_min_target_id) ||
         static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) >
-            FLAGS_max_target_id) {
+            absl::GetFlag(FLAGS_max_target_id)) {
       LOG(INFO) << "Skipping tag with invalid id of " << target_pose_fbs->id();
       continue;
     }
 
     // Skip detections with high pose errors
-    if (target_pose_fbs->pose_error() > FLAGS_max_pose_error) {
+    if (target_pose_fbs->pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
       LOG(INFO) << "Skipping tag " << target_pose_fbs->id()
                 << " due to pose error of " << target_pose_fbs->pose_error();
       continue;
     }
     // Skip detections with high pose error ratios
-    if (target_pose_fbs->pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+    if (target_pose_fbs->pose_error_ratio() >
+        absl::GetFlag(FLAGS_max_pose_error_ratio)) {
       LOG(INFO) << "Skipping tag " << target_pose_fbs->id()
                 << " due to pose error ratio of "
                 << target_pose_fbs->pose_error_ratio();
@@ -415,9 +418,10 @@
   vis_robot_.SetDefaultViewpoint(kImageWidth, kFocalLength);
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config =
-      (FLAGS_config.empty()
+      (absl::GetFlag(FLAGS_config).empty()
            ? std::nullopt
-           : std::make_optional(aos::configuration::ReadConfig(FLAGS_config)));
+           : std::make_optional(
+                 aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config))));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -435,10 +439,11 @@
   reader.RemapLoggedChannel("/roborio/constants", "y2023.Constants");
   reader.Register();
 
-  SendSimulationConstants(reader.event_loop_factory(), FLAGS_team_number,
-                          FLAGS_constants_path);
+  SendSimulationConstants(reader.event_loop_factory(),
+                          absl::GetFlag(FLAGS_team_number),
+                          absl::GetFlag(FLAGS_constants_path));
 
-  VLOG(1) << "Using target type " << FLAGS_target_type;
+  VLOG(1) << "Using target type " << absl::GetFlag(FLAGS_target_type);
   std::vector<std::string> node_list;
   node_list.push_back("pi1");
   node_list.push_back("pi2");
@@ -468,7 +473,7 @@
     calibration_list.push_back(calibration);
 
     frc971::vision::TargetType target_type =
-        frc971::vision::TargetTypeFromString(FLAGS_target_type);
+        frc971::vision::TargetTypeFromString(absl::GetFlag(FLAGS_target_type));
     frc971::vision::CharucoExtractor *charuco_ext =
         new frc971::vision::CharucoExtractor(calibration, target_type);
     charuco_extractors.emplace_back(charuco_ext);
@@ -482,7 +487,7 @@
     VLOG(1) << "Got extrinsics for " << node << " as\n"
             << default_extrinsics.back().matrix();
 
-    if (FLAGS_use_full_logs) {
+    if (absl::GetFlag(FLAGS_use_full_logs)) {
       LOG(INFO) << "Set up image callback for node " << node_list[i];
       frc971::vision::ImageCallback *image_callback =
           new frc971::vision::ImageCallback(
@@ -597,7 +602,7 @@
         Eigen::Affine3d H_world_board;
         H_world_board = Eigen::Translation3d::Identity() *
                         Eigen::AngleAxisd(M_PI / 2.0, Eigen::Vector3d::UnitX());
-        if (FLAGS_alt_view) {
+        if (absl::GetFlag(FLAGS_alt_view)) {
           H_world_board = Eigen::Translation3d(0.0, 0.0, 3.0);
         }
 
@@ -676,11 +681,11 @@
 
       // Assumes node_list name is of form "pi#" to create camera id
       const std::string calibration_filename =
-          FLAGS_output_folder +
-          absl::StrFormat("/calibration_pi-%d-%s_cam-%s_%s.json",
-                          FLAGS_team_number, node_list[i + 1].substr(2, 3),
-                          calibration_list[i + 1]->camera_id()->data(),
-                          time_ss.str());
+          absl::GetFlag(FLAGS_output_folder) +
+          absl::StrFormat(
+              "/calibration_pi-%d-%s_cam-%s_%s.json",
+              absl::GetFlag(FLAGS_team_number), node_list[i + 1].substr(2, 3),
+              calibration_list[i + 1]->camera_id()->data(), time_ss.str());
 
       LOG(INFO) << calibration_filename << " -> "
                 << aos::FlatbufferToJson(merged_calibration,
diff --git a/y2023/vision/camera_monitor.cc b/y2023/vision/camera_monitor.cc
index e69fd7c..f5d8841 100644
--- a/y2023/vision/camera_monitor.cc
+++ b/y2023/vision/camera_monitor.cc
@@ -1,14 +1,17 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2023/vision/camera_monitor_lib.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
diff --git a/y2023/vision/camera_reader.cc b/y2023/vision/camera_reader.cc
index 668026a..ba3defe 100644
--- a/y2023/vision/camera_reader.cc
+++ b/y2023/vision/camera_reader.cc
@@ -1,6 +1,7 @@
 #include <linux/videodev2.h>
 #include <sys/ioctl.h>
 
+#include "absl/flags/flag.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_split.h"
 
@@ -11,16 +12,17 @@
 #include "frc971/vision/v4l2_reader.h"
 #include "y2023/vision/rkisp1-config.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_bool(lowlight_camera, true, "Switch to use imx462 image sensor.");
-DEFINE_int32(gain, 150, "analogue_gain");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(bool, lowlight_camera, true, "Switch to use imx462 image sensor.");
+ABSL_FLAG(int32_t, gain, 150, "analogue_gain");
 
-DEFINE_double(red, 1.252, "Red gain");
-DEFINE_double(green, 1, "Green gain");
-DEFINE_double(blue, 1.96, "Blue gain");
-DEFINE_double(exposure, 150, "Camera exposure");
-DEFINE_bool(send_downsized_images, false,
-            "Whether to send downsized image for driver cam streaming.");
+ABSL_FLAG(double, red, 1.252, "Red gain");
+ABSL_FLAG(double, green, 1, "Green gain");
+ABSL_FLAG(double, blue, 1.96, "Blue gain");
+ABSL_FLAG(double, exposure, 150, "Camera exposure");
+ABSL_FLAG(bool, send_downsized_images, false,
+          "Whether to send downsized image for driver cam streaming.");
 
 namespace y2023::vision {
 namespace {
@@ -34,13 +36,15 @@
     media_device->Log();
   }
 
-  const int kWidth = (FLAGS_lowlight_camera ? 1920 : 1296);
-  const int kHeight = (FLAGS_lowlight_camera ? 1080 : 972);
-  const int kColorFormat = (FLAGS_lowlight_camera ? MEDIA_BUS_FMT_SRGGB10_1X10
-                                                  : MEDIA_BUS_FMT_SBGGR10_1X10);
+  const int kWidth = (absl::GetFlag(FLAGS_lowlight_camera) ? 1920 : 1296);
+  const int kHeight = (absl::GetFlag(FLAGS_lowlight_camera) ? 1080 : 972);
+  const int kColorFormat =
+      (absl::GetFlag(FLAGS_lowlight_camera) ? MEDIA_BUS_FMT_SRGGB10_1X10
+                                            : MEDIA_BUS_FMT_SBGGR10_1X10);
 
   const std::string_view kCameraDeviceString =
-      (FLAGS_lowlight_camera ? "arducam-pivariety 4-000c" : "ov5647 4-0036");
+      (absl::GetFlag(FLAGS_lowlight_camera) ? "arducam-pivariety 4-000c"
+                                            : "ov5647 4-0036");
 
   // Scale down the selfpath images so we can log at 30 Hz (but still detect
   // april tags at a far enough distance)
@@ -106,7 +110,7 @@
       media_device->FindLink("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0));
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
@@ -117,17 +121,17 @@
   RockchipV4L2Reader v4l2_reader_selfpath(&event_loop, event_loop.epoll(),
                                           rkisp1_selfpath->device(),
                                           camera->device());
-  if (FLAGS_lowlight_camera) {
-    v4l2_reader_selfpath.SetGainExt(FLAGS_gain);
+  if (absl::GetFlag(FLAGS_lowlight_camera)) {
+    v4l2_reader_selfpath.SetGainExt(absl::GetFlag(FLAGS_gain));
     v4l2_reader_selfpath.SetVerticalBlanking(1000);
-    v4l2_reader_selfpath.SetExposure(FLAGS_exposure);
+    v4l2_reader_selfpath.SetExposure(absl::GetFlag(FLAGS_exposure));
   } else {
     v4l2_reader_selfpath.SetGainExt(1000);
     v4l2_reader_selfpath.SetExposure(1000);
   }
 
   std::unique_ptr<RockchipV4L2Reader> v4l2_reader_mainpath;
-  if (FLAGS_send_downsized_images) {
+  if (absl::GetFlag(FLAGS_send_downsized_images)) {
     // Reader for driver cam streaming on logger pi, sending lower res images
     v4l2_reader_mainpath = std::make_unique<RockchipV4L2Reader>(
         &event_loop, event_loop.epoll(), rkisp1_mainpath->device(),
@@ -171,10 +175,14 @@
 
     configuration.module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
 
-    configuration.others.awb_gain_config.gain_red = 256 * FLAGS_red;
-    configuration.others.awb_gain_config.gain_green_r = 256 * FLAGS_green;
-    configuration.others.awb_gain_config.gain_blue = 256 * FLAGS_blue;
-    configuration.others.awb_gain_config.gain_green_b = 256 * FLAGS_green;
+    configuration.others.awb_gain_config.gain_red =
+        256 * absl::GetFlag(FLAGS_red);
+    configuration.others.awb_gain_config.gain_green_r =
+        256 * absl::GetFlag(FLAGS_green);
+    configuration.others.awb_gain_config.gain_blue =
+        256 * absl::GetFlag(FLAGS_blue);
+    configuration.others.awb_gain_config.gain_green_b =
+        256 * absl::GetFlag(FLAGS_green);
 
     // Enable the AWB gains
     configuration.module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
diff --git a/y2023/vision/ccm.cc b/y2023/vision/ccm.cc
index d32cc2f..ecb9552 100644
--- a/y2023/vision/ccm.cc
+++ b/y2023/vision/ccm.cc
@@ -1,4 +1,5 @@
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc.hpp>
diff --git a/y2023/vision/foxglove_image_converter.cc b/y2023/vision/foxglove_image_converter.cc
index bfaafc8..3bd0143 100644
--- a/y2023/vision/foxglove_image_converter.cc
+++ b/y2023/vision/foxglove_image_converter.cc
@@ -1,14 +1,17 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/vision/foxglove_image_converter_lib.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
diff --git a/y2023/vision/game_pieces_main.cc b/y2023/vision/game_pieces_main.cc
index b4ceff5..ff3ec7c 100644
--- a/y2023/vision/game_pieces_main.cc
+++ b/y2023/vision/game_pieces_main.cc
@@ -1,15 +1,18 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "y2023/vision/game_pieces.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 namespace y2023::vision {
 namespace {
 
 void GamePiecesDetectorMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
   GamePiecesDetector game_pieces_detector(&event_loop);
   event_loop.Run();
diff --git a/y2023/vision/image_logger.cc b/y2023/vision/image_logger.cc
index 45e25f6..a7c233d 100644
--- a/y2023/vision/image_logger.cc
+++ b/y2023/vision/image_logger.cc
@@ -1,8 +1,10 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/usage.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_writer.h"
@@ -11,16 +13,16 @@
 #include "aos/logging/log_namer.h"
 #include "frc971/input/joystick_state_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
 
-DEFINE_double(rotate_every, 0.0,
-              "If set, rotate the logger after this many seconds");
-DECLARE_int32(flush_size);
-DEFINE_double(disabled_time, 5.0,
-              "Continue logging if disabled for this amount of time or less");
-DEFINE_bool(direct, false,
-            "If true, write using O_DIRECT and write 512 byte aligned blocks "
-            "whenever possible.");
+ABSL_FLAG(double, rotate_every, 0.0,
+          "If set, rotate the logger after this many seconds");
+ABSL_DECLARE_FLAG(int32_t, flush_size);
+ABSL_FLAG(double, disabled_time, 5.0,
+          "Continue logging if disabled for this amount of time or less");
+ABSL_FLAG(bool, direct, false,
+          "If true, write using O_DIRECT and write 512 byte aligned blocks "
+          "whenever possible.");
 
 std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
     aos::EventLoop *event_loop) {
@@ -32,19 +34,20 @@
   }
 
   return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
-      event_loop, std::make_unique<aos::logger::RenamableFileBackend>(
-                      absl::StrCat(log_name.value(), "/"), FLAGS_direct));
+      event_loop,
+      std::make_unique<aos::logger::RenamableFileBackend>(
+          absl::StrCat(log_name.value(), "/"), absl::GetFlag(FLAGS_direct)));
 }
 
 int main(int argc, char *argv[]) {
-  gflags::SetUsageMessage(
+  absl::SetProgramUsageMessage(
       "This program provides a simple logger binary that logs all SHMEM data "
       "directly to a file specified at the command line when the robot is "
       "enabled and for a bit of time after.");
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
@@ -56,11 +59,12 @@
       event_loop.monotonic_now();
   aos::logger::Logger logger(&event_loop);
 
-  if (FLAGS_rotate_every != 0.0) {
+  if (absl::GetFlag(FLAGS_rotate_every) != 0.0) {
     logger.set_on_logged_period([&](aos::monotonic_clock::time_point) {
       const auto now = event_loop.monotonic_now();
-      if (logging && now > last_rotation_time + std::chrono::duration<double>(
-                                                    FLAGS_rotate_every)) {
+      if (logging &&
+          now > last_rotation_time + std::chrono::duration<double>(
+                                         absl::GetFlag(FLAGS_rotate_every))) {
         logger.Rotate();
         last_rotation_time = now;
       }
@@ -95,7 +99,8 @@
           last_rotation_time = event_loop.monotonic_now();
         } else if (logging && !enabled &&
                    (timestamp - last_disable_time) >
-                       std::chrono::duration<double>(FLAGS_disabled_time)) {
+                       std::chrono::duration<double>(
+                           absl::GetFlag(FLAGS_disabled_time))) {
           // Stop logging if we've been disabled for a non-negligible amount of
           // time
           LOG(INFO) << "Stopping logging";
diff --git a/y2023/vision/localization_verifier.cc b/y2023/vision/localization_verifier.cc
index 01ef9fe..fd24ffe 100644
--- a/y2023/vision/localization_verifier.cc
+++ b/y2023/vision/localization_verifier.cc
@@ -1,4 +1,6 @@
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/init.h"
 #include "frc971/constants/constants_sender_lib.h"
@@ -7,12 +9,13 @@
 #include "frc971/vision/vision_generated.h"
 #include "y2023/localizer/localizer.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
-DEFINE_uint64(min_april_id, 1,
-              "Minimum april id to consider as part of the field and ignore");
-DEFINE_uint64(max_april_id, 8,
-              "Maximum april id to consider as part of the field and ignore");
+ABSL_FLAG(uint64_t, min_april_id, 1,
+          "Minimum april id to consider as part of the field and ignore");
+ABSL_FLAG(uint64_t, max_april_id, 8,
+          "Maximum april id to consider as part of the field and ignore");
 
 // This binary allows us to place extra april tags on the field and verify
 // that we can compute their field pose correctly
@@ -43,8 +46,8 @@
 
   for (const auto *target_pose : *detections.target_poses()) {
     // Only look at april tags not part of the field
-    if (target_pose->id() >= FLAGS_min_april_id &&
-        target_pose->id() <= FLAGS_max_april_id) {
+    if (target_pose->id() >= absl::GetFlag(FLAGS_min_april_id) &&
+        target_pose->id() <= absl::GetFlag(FLAGS_max_april_id)) {
       continue;
     }
 
@@ -71,7 +74,7 @@
 
 void LocalizationVerifierMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<Constants>(&config.message());
 
diff --git a/y2023/vision/target_mapping.cc b/y2023/vision/target_mapping.cc
index af4c36c..f33a83a 100644
--- a/y2023/vision/target_mapping.cc
+++ b/y2023/vision/target_mapping.cc
@@ -20,43 +20,43 @@
 #include "y2023/vision/aprilrobotics.h"
 #include "y2023/vision/vision_util.h"
 
-DEFINE_string(config, "",
-              "If set, override the log's config file with this one.");
-DEFINE_string(constants_path, "y2023/constants/constants.json",
-              "Path to the constant file");
-DEFINE_string(dump_constraints_to, "/tmp/mapping_constraints.txt",
-              "Write the target constraints to this path");
-DEFINE_string(dump_stats_to, "/tmp/mapping_stats.txt",
-              "Write the mapping stats to this path");
-DEFINE_string(field_name, "charged_up",
-              "Field name, for the output json filename and flatbuffer field");
-DEFINE_string(json_path, "y2023/vision/maps/target_map.json",
-              "Specify path for json with initial pose guesses.");
-DEFINE_double(max_pose_error, 1e-6,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_string(mcap_output_path, "", "Log to output.");
-DEFINE_string(output_dir, "y2023/vision/maps",
-              "Directory to write solved target map to");
-DEFINE_double(pause_on_distance, 1.0,
-              "Pause if two consecutive implied robot positions differ by more "
-              "than this many meters");
-DEFINE_string(pi, "pi1", "Pi name to generate mcap log for; defaults to pi1.");
-DEFINE_uint64(skip_to, 1,
-              "Start at combined image of this number (1 is the first image)");
-DEFINE_bool(solve, true, "Whether to solve for the field's target map.");
-DEFINE_int32(team_number, 0,
-             "Required: Use the calibration for a node with this team number");
-DEFINE_uint64(wait_key, 1,
-              "Time in ms to wait between images, if no click (0 to wait "
-              "indefinitely until click).");
+ABSL_FLAG(std::string, config, "",
+          "If set, override the log's config file with this one.");
+ABSL_FLAG(std::string, constants_path, "y2023/constants/constants.json",
+          "Path to the constant file");
+ABSL_FLAG(std::string, dump_constraints_to, "/tmp/mapping_constraints.txt",
+          "Write the target constraints to this path");
+ABSL_FLAG(std::string, dump_stats_to, "/tmp/mapping_stats.txt",
+          "Write the mapping stats to this path");
+ABSL_FLAG(std::string, field_name, "charged_up",
+          "Field name, for the output json filename and flatbuffer field");
+ABSL_FLAG(std::string, json_path, "y2023/vision/maps/target_map.json",
+          "Specify path for json with initial pose guesses.");
+ABSL_FLAG(double, max_pose_error, 1e-6,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(std::string, mcap_output_path, "", "Log to output.");
+ABSL_FLAG(std::string, output_dir, "y2023/vision/maps",
+          "Directory to write solved target map to");
+ABSL_FLAG(double, pause_on_distance, 1.0,
+          "Pause if two consecutive implied robot positions differ by more "
+          "than this many meters");
+ABSL_FLAG(std::string, pi, "pi1",
+          "Pi name to generate mcap log for; defaults to pi1.");
+ABSL_FLAG(uint64_t, skip_to, 1,
+          "Start at combined image of this number (1 is the first image)");
+ABSL_FLAG(bool, solve, true, "Whether to solve for the field's target map.");
+ABSL_FLAG(int32_t, team_number, 0,
+          "Required: Use the calibration for a node with this team number");
+ABSL_FLAG(uint64_t, wait_key, 1,
+          "Time in ms to wait between images, if no click (0 to wait "
+          "indefinitely until click).");
 
-DECLARE_int32(frozen_target_id);
-DECLARE_int32(min_target_id);
-DECLARE_int32(max_target_id);
-DECLARE_bool(visualize_solver);
+ABSL_DECLARE_FLAG(int32_t, frozen_target_id);
+ABSL_DECLARE_FLAG(int32_t, min_target_id);
+ABSL_DECLARE_FLAG(int32_t, max_target_id);
+ABSL_DECLARE_FLAG(bool, visualize_solver);
 
 namespace y2023::vision {
 using frc971::vision::DataAdapter;
@@ -131,8 +131,8 @@
     {"pi4", cv::Scalar(255, 165, 0)},
 };
 
-const auto TargetMapperReplay::kFixedTargetMapper =
-    TargetMapper(FLAGS_json_path, ceres::examples::VectorOfConstraints{});
+const auto TargetMapperReplay::kFixedTargetMapper = TargetMapper(
+    absl::GetFlag(FLAGS_json_path), ceres::examples::VectorOfConstraints{});
 
 Eigen::Affine3d TargetMapperReplay::CameraToRobotDetection(
     Eigen::Affine3d H_camera_target, Eigen::Affine3d extrinsics) {
@@ -164,8 +164,9 @@
 
   reader_->Register();
 
-  SendSimulationConstants(reader_->event_loop_factory(), FLAGS_team_number,
-                          FLAGS_constants_path);
+  SendSimulationConstants(reader_->event_loop_factory(),
+                          absl::GetFlag(FLAGS_team_number),
+                          absl::GetFlag(FLAGS_constants_path));
 
   for (size_t i = 1; i < kNumPis; i++) {
     std::string node_name = "pi" + std::to_string(i);
@@ -178,23 +179,24 @@
         mapping_event_loops_[mapping_event_loops_.size() - 1].get());
   }
 
-  if (!FLAGS_mcap_output_path.empty()) {
-    LOG(INFO) << "Writing out mcap file to " << FLAGS_mcap_output_path;
-    const aos::Node *node =
-        aos::configuration::GetNode(reader_->configuration(), FLAGS_pi);
+  if (!absl::GetFlag(FLAGS_mcap_output_path).empty()) {
+    LOG(INFO) << "Writing out mcap file to "
+              << absl::GetFlag(FLAGS_mcap_output_path);
+    const aos::Node *node = aos::configuration::GetNode(
+        reader_->configuration(), absl::GetFlag(FLAGS_pi));
     reader_->event_loop_factory()->GetNodeEventLoopFactory(node)->OnStartup(
         [this, node]() {
           mcap_event_loop_ =
               reader_->event_loop_factory()->MakeEventLoop("mcap", node);
           relogger_ = std::make_unique<aos::McapLogger>(
-              mcap_event_loop_.get(), FLAGS_mcap_output_path,
+              mcap_event_loop_.get(), absl::GetFlag(FLAGS_mcap_output_path),
               aos::McapLogger::Serialization::kFlatbuffer,
               aos::McapLogger::CanonicalChannelNames::kShortened,
               aos::McapLogger::Compression::kLz4);
         });
   }
 
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     vis_robot_.ClearImage();
     const double kFocalLength = 500.0;
     vis_robot_.SetDefaultViewpoint(kImageWidth, kFocalLength);
@@ -214,21 +216,22 @@
   for (const auto *target_pose_fbs : *map.target_poses()) {
     // Skip detections with invalid ids
     if (static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) <
-            FLAGS_min_target_id ||
+            absl::GetFlag(FLAGS_min_target_id) ||
         static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) >
-            FLAGS_max_target_id) {
+            absl::GetFlag(FLAGS_max_target_id)) {
       VLOG(1) << "Skipping tag with invalid id of " << target_pose_fbs->id();
       continue;
     }
 
     // Skip detections with high pose errors
-    if (target_pose_fbs->pose_error() > FLAGS_max_pose_error) {
+    if (target_pose_fbs->pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
       VLOG(1) << "Skipping tag " << target_pose_fbs->id()
               << " due to pose error of " << target_pose_fbs->pose_error();
       continue;
     }
     // Skip detections with high pose error ratios
-    if (target_pose_fbs->pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+    if (target_pose_fbs->pose_error_ratio() >
+        absl::GetFlag(FLAGS_max_pose_error_ratio)) {
       VLOG(1) << "Skipping tag " << target_pose_fbs->id()
               << " due to pose error ratio of "
               << target_pose_fbs->pose_error_ratio();
@@ -259,7 +262,7 @@
             .distortion_factor = distortion_factor,
             .id = static_cast<TargetMapper::TargetId>(target_pose.id)});
 
-    if (FLAGS_visualize_solver) {
+    if (absl::GetFlag(FLAGS_visualize_solver)) {
       // If we've already drawn this node_name in the current image,
       // display the image before clearing and adding the new poses
       if (drawn_nodes_.count(node_name) != 0) {
@@ -269,20 +272,21 @@
                     cv::Point(600, 10), cv::FONT_HERSHEY_PLAIN, 1.0,
                     cv::Scalar(255, 255, 255));
 
-        if (display_count_ >= FLAGS_skip_to) {
+        if (display_count_ >= absl::GetFlag(FLAGS_skip_to)) {
           VLOG(1) << "Showing image for node " << node_name
                   << " since we've drawn it already";
           cv::imshow("View", vis_robot_.image_);
           // Pause if delta_T is too large, but only after first image (to make
           // sure the delta's are correct
-          if (max_delta_T_world_robot_ > FLAGS_pause_on_distance &&
+          if (max_delta_T_world_robot_ >
+                  absl::GetFlag(FLAGS_pause_on_distance) &&
               display_count_ > 1) {
             LOG(INFO) << "Pausing since the delta between robot estimates is "
                       << max_delta_T_world_robot_ << " which is > threshold of "
-                      << FLAGS_pause_on_distance;
+                      << absl::GetFlag(FLAGS_pause_on_distance);
             cv::waitKey(0);
           } else {
-            cv::waitKey(FLAGS_wait_key);
+            cv::waitKey(absl::GetFlag(FLAGS_wait_key));
           }
           max_delta_T_world_robot_ = 0.0;
         } else {
@@ -303,7 +307,8 @@
               << H_world_robot.translation().transpose();
 
       label << "id " << target_pose_fbs->id() << ": err (% of max): "
-            << (target_pose_fbs->pose_error() / FLAGS_max_pose_error)
+            << (target_pose_fbs->pose_error() /
+                absl::GetFlag(FLAGS_max_pose_error))
             << " err_ratio: " << target_pose_fbs->pose_error_ratio() << " ";
 
       vis_robot_.DrawRobotOutline(H_world_robot, node_name,
@@ -326,7 +331,7 @@
     }
   }
 
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     if (drew) {
       // Collect all the labels from a given node, and add the text
       size_t pi_number =
@@ -338,13 +343,13 @@
       drawn_nodes_.emplace(node_name);
     } else if (pi_distributed_time - last_draw_time_ >
                    std::chrono::milliseconds(30) &&
-               display_count_ >= FLAGS_skip_to) {
+               display_count_ >= absl::GetFlag(FLAGS_skip_to)) {
       cv::putText(vis_robot_.image_, "No detections", cv::Point(10, 0),
                   cv::FONT_HERSHEY_PLAIN, 1.0, kPiColors.at(node_name));
       // Display and clear the image if we haven't draw in a while
       VLOG(1) << "Displaying image due to time lapse";
       cv::imshow("View", vis_robot_.image_);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
       vis_robot_.ClearImage();
       max_delta_T_world_robot_ = 0.0;
       drawn_nodes_.clear();
@@ -378,7 +383,7 @@
 }
 
 void TargetMapperReplay::MaybeSolve() {
-  if (FLAGS_solve) {
+  if (absl::GetFlag(FLAGS_solve)) {
     auto target_constraints =
         DataAdapter::MatchTargetDetections(timestamped_target_detections_);
 
@@ -399,14 +404,15 @@
 
     LOG(INFO) << "Solving for locations of tags with "
               << target_constraints.size() << " constraints";
-    TargetMapper mapper(FLAGS_json_path, target_constraints);
-    mapper.Solve(FLAGS_field_name, FLAGS_output_dir);
+    TargetMapper mapper(absl::GetFlag(FLAGS_json_path), target_constraints);
+    mapper.Solve(absl::GetFlag(FLAGS_field_name),
+                 absl::GetFlag(FLAGS_output_dir));
 
-    if (!FLAGS_dump_constraints_to.empty()) {
-      mapper.DumpConstraints(FLAGS_dump_constraints_to);
+    if (!absl::GetFlag(FLAGS_dump_constraints_to).empty()) {
+      mapper.DumpConstraints(absl::GetFlag(FLAGS_dump_constraints_to));
     }
-    if (!FLAGS_dump_stats_to.empty()) {
-      mapper.DumpStats(FLAGS_dump_stats_to);
+    if (!absl::GetFlag(FLAGS_dump_stats_to).empty()) {
+      mapper.DumpStats(absl::GetFlag(FLAGS_dump_stats_to));
     }
   }
 }
@@ -415,9 +421,10 @@
   std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections;
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config =
-      (FLAGS_config.empty()
+      (absl::GetFlag(FLAGS_config).empty()
            ? std::nullopt
-           : std::make_optional(aos::configuration::ReadConfig(FLAGS_config)));
+           : std::make_optional(
+                 aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config))));
 
   // Open logfiles
   aos::logger::LogReader reader(
diff --git a/y2023/vision/video_ripper.cc b/y2023/vision/video_ripper.cc
index 3c93139..ac24d68 100644
--- a/y2023/vision/video_ripper.cc
+++ b/y2023/vision/video_ripper.cc
@@ -2,8 +2,9 @@
 
 #include <cstdlib>
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
@@ -11,14 +12,14 @@
 #include "aos/scoped/scoped_fd.h"
 #include "frc971/vision/vision_generated.h"
 
-DEFINE_string(channel, "/camera", "Channel name for the image.");
-DEFINE_int32(width, 1280, "Width of the image");
-DEFINE_int32(height, 720, "Height of the image");
-DEFINE_string(ffmpeg_binary, "external/ffmpeg/ffmpeg",
-              "The path to the ffmpeg binary");
-DEFINE_string(output_path, "video_ripper_output.mp4",
-              "The path to output the mp4 video");
-DEFINE_bool(flip, true, "If true, rotate the video 180 deg.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(int32_t, width, 1280, "Width of the image");
+ABSL_FLAG(int32_t, height, 720, "Height of the image");
+ABSL_FLAG(std::string, ffmpeg_binary, "external/ffmpeg/ffmpeg",
+          "The path to the ffmpeg binary");
+ABSL_FLAG(std::string, output_path, "video_ripper_output.mp4",
+          "The path to output the mp4 video");
+ABSL_FLAG(bool, flip, true, "If true, rotate the video 180 deg.");
 
 // Replays a log and dumps the contents of /camera frc971.vision.CameraImage
 // directly to stdout.
@@ -30,15 +31,16 @@
 
   // Start ffmpeg
   std::stringstream command;
-  command << FLAGS_ffmpeg_binary;
+  command << absl::GetFlag(FLAGS_ffmpeg_binary);
   command << " -framerate 30 -f rawvideo -pix_fmt yuyv422";
-  command << " -s " << FLAGS_width << "x" << FLAGS_height;
+  command << " -s " << absl::GetFlag(FLAGS_width) << "x"
+          << absl::GetFlag(FLAGS_height);
   command << " -i pipe:";
   command << " -c:v libx264 -f mp4";
-  if (FLAGS_flip) {
+  if (absl::GetFlag(FLAGS_flip)) {
     command << " -vf rotate=PI";
   }
-  command << " \"" << FLAGS_output_path << "\"";
+  command << " \"" << absl::GetFlag(FLAGS_output_path) << "\"";
 
   FILE *stream = popen(command.str().c_str(), "w");
 
@@ -61,10 +63,11 @@
     event_loop =
         reader.event_loop_factory()->MakeEventLoop("video_ripper", node);
     event_loop->MakeWatcher(
-        FLAGS_channel, [&stream](const frc971::vision::CameraImage &image) {
-          CHECK_EQ(FLAGS_width, image.cols())
+        absl::GetFlag(FLAGS_channel),
+        [&stream](const frc971::vision::CameraImage &image) {
+          CHECK_EQ(absl::GetFlag(FLAGS_width), image.cols())
               << "Image width needs to match the images in the logfile";
-          CHECK_EQ(FLAGS_height, image.rows())
+          CHECK_EQ(absl::GetFlag(FLAGS_height), image.rows())
               << "Image width needs to match the images in the logfile";
 
           const size_t bytes_written =
diff --git a/y2023/vision/viewer.cc b/y2023/vision/viewer.cc
index 78731e5..83ef483 100644
--- a/y2023/vision/viewer.cc
+++ b/y2023/vision/viewer.cc
@@ -1,3 +1,4 @@
+#include "absl/flags/flag.h"
 #include "absl/strings/match.h"
 #include <opencv2/calib3d.hpp>
 #include <opencv2/highgui/highgui.hpp>
@@ -11,12 +12,13 @@
 #include "frc971/vision/vision_generated.h"
 #include "y2023/vision/vision_util.h"
 
-DEFINE_string(capture, "",
-              "If set, capture a single image and save it to this filename.");
-DEFINE_string(channel, "/camera", "Channel name for the image.");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_int32(rate, 100, "Time in milliseconds to wait between images");
-DEFINE_double(scale, 1.0, "Scale factor for images being displayed");
+ABSL_FLAG(std::string, capture, "",
+          "If set, capture a single image and save it to this filename.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(int32_t, rate, 100, "Time in milliseconds to wait between images");
+ABSL_FLAG(double, scale, 1.0, "Scale factor for images being displayed");
 
 namespace y2023::vision {
 namespace {
@@ -41,12 +43,12 @@
   cv::Mat bgr_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
   cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
 
-  if (!FLAGS_capture.empty()) {
-    if (absl::EndsWith(FLAGS_capture, ".bfbs")) {
-      aos::WriteFlatbufferToFile(FLAGS_capture,
+  if (!absl::GetFlag(FLAGS_capture).empty()) {
+    if (absl::EndsWith(absl::GetFlag(FLAGS_capture), ".bfbs")) {
+      aos::WriteFlatbufferToFile(absl::GetFlag(FLAGS_capture),
                                  image_fetcher->CopyFlatBuffer());
     } else {
-      cv::imwrite(FLAGS_capture, bgr_image);
+      cv::imwrite(absl::GetFlag(FLAGS_capture), bgr_image);
     }
 
     return false;
@@ -54,9 +56,9 @@
 
   cv::Mat undistorted_image;
   cv::undistort(bgr_image, undistorted_image, intrinsics, dist_coeffs);
-  if (FLAGS_scale != 1.0) {
-    cv::resize(undistorted_image, undistorted_image, cv::Size(), FLAGS_scale,
-               FLAGS_scale);
+  if (absl::GetFlag(FLAGS_scale) != 1.0) {
+    cv::resize(undistorted_image, undistorted_image, cv::Size(),
+               absl::GetFlag(FLAGS_scale), absl::GetFlag(FLAGS_scale));
   }
   cv::imshow("Display", undistorted_image);
 
@@ -76,7 +78,7 @@
 
 void ViewerMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<Constants>(&config.message());
 
@@ -89,7 +91,7 @@
   const cv::Mat dist_coeffs = CameraDistCoeffs(calibration_data);
 
   aos::Fetcher<CameraImage> image_fetcher =
-      event_loop.MakeFetcher<CameraImage>(FLAGS_channel);
+      event_loop.MakeFetcher<CameraImage>(absl::GetFlag(FLAGS_channel));
 
   // Run the display loop
   event_loop.AddPhasedLoop(
@@ -99,7 +101,7 @@
           event_loop.Exit();
         };
       },
-      ::std::chrono::milliseconds(FLAGS_rate));
+      ::std::chrono::milliseconds(absl::GetFlag(FLAGS_rate)));
 
   event_loop.Run();
 
diff --git a/y2023/vision/vision_util.cc b/y2023/vision/vision_util.cc
index ca5ad89..276341a 100644
--- a/y2023/vision/vision_util.cc
+++ b/y2023/vision/vision_util.cc
@@ -1,6 +1,7 @@
 #include "y2023/vision/vision_util.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace y2023::vision {
 
diff --git a/y2023/vision/yolov5.cc b/y2023/vision/yolov5.cc
index e62b106..f4c2e39 100644
--- a/y2023/vision/yolov5.cc
+++ b/y2023/vision/yolov5.cc
@@ -12,23 +12,23 @@
 #include <chrono>
 #include <string>
 
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 #include "absl/types/span.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
 #include <opencv2/dnn.hpp>
 
-DEFINE_double(conf_threshold, 0.9,
-              "Threshold value for confidence scores. Detections with a "
-              "confidence score below this value will be ignored.");
+ABSL_FLAG(double, conf_threshold, 0.9,
+          "Threshold value for confidence scores. Detections with a "
+          "confidence score below this value will be ignored.");
 
-DEFINE_double(
-    nms_threshold, 0.5,
-    "Threshold value for non-maximum suppression. Detections with an "
-    "intersection-over-union value below this value will be removed.");
+ABSL_FLAG(double, nms_threshold, 0.5,
+          "Threshold value for non-maximum suppression. Detections with an "
+          "intersection-over-union value below this value will be removed.");
 
-DEFINE_int32(nthreads, 6, "Number of threads to use during inference.");
+ABSL_FLAG(int32_t, nthreads, 6, "Number of threads to use during inference.");
 
-DEFINE_bool(visualize_detections, false, "Display inference output");
+ABSL_FLAG(bool, visualize_detections, false, "Display inference output");
 
 namespace y2023::vision {
 
@@ -134,7 +134,7 @@
   input_8_ =
       absl::Span(interpreter_->typed_tensor<uint8_t>(input_), tensor_size);
 
-  interpreter_->SetNumThreads(FLAGS_nthreads);
+  interpreter_->SetNumThreads(absl::GetFlag(FLAGS_nthreads));
 
   VLOG(1) << "Load model: Done";
 }
@@ -184,7 +184,7 @@
   cv::Point class_id;
 
   for (int i = 0; i < rows; i++) {
-    if (orig_preds[i][4] > FLAGS_conf_threshold) {
+    if (orig_preds[i][4] > absl::GetFlag(FLAGS_conf_threshold)) {
       float x = orig_preds[i][0];
       float y = orig_preds[i][1];
       float w = orig_preds[i][2];
@@ -200,7 +200,7 @@
 
       cv::minMaxLoc(scores, nullptr, &confidence, nullptr, &class_id);
       scores.clear();
-      if (confidence > FLAGS_conf_threshold) {
+      if (confidence > absl::GetFlag(FLAGS_conf_threshold)) {
         Detection detection{cv::Rect(left, top, width, height), confidence,
                             class_id.x};
         detections->push_back(detection);
@@ -216,8 +216,8 @@
     confidences.push_back(d.confidence);
   }
 
-  cv::dnn::NMSBoxes(boxes, confidences, FLAGS_conf_threshold,
-                    FLAGS_nms_threshold, *indices);
+  cv::dnn::NMSBoxes(boxes, confidences, absl::GetFlag(FLAGS_conf_threshold),
+                    absl::GetFlag(FLAGS_nms_threshold), *indices);
 
   std::vector<Detection> filtered_detections;
   for (size_t i = 0; i < indices->size(); i++) {
@@ -277,7 +277,7 @@
           << std::chrono::duration_cast<std::chrono::milliseconds>(stop - start)
                  .count();
 
-  if (FLAGS_visualize_detections) {
+  if (absl::GetFlag(FLAGS_visualize_detections)) {
     cv::resize(frame, frame, cv::Size(img_width_, img_height_), 0, 0, true);
     for (size_t i = 0; i < filtered_detections.size(); i++) {
       VLOG(1) << "Bounding Box | X: " << filtered_detections[i].box.x
diff --git a/y2023/wpilib_interface.cc b/y2023/wpilib_interface.cc
index d0d952c..bc14311 100644
--- a/y2023/wpilib_interface.cc
+++ b/y2023/wpilib_interface.cc
@@ -62,9 +62,9 @@
 #include "y2023/control_loops/superstructure/superstructure_output_generated.h"
 #include "y2023/control_loops/superstructure/superstructure_position_static.h"
 
-DEFINE_bool(ctre_diag_server, false,
-            "If true, enable the diagnostics server for interacting with "
-            "devices on the CAN bus using Phoenix Tuner");
+ABSL_FLAG(bool, ctre_diag_server, false,
+          "If true, enable the diagnostics server for interacting with "
+          "devices on the CAN bus using Phoenix Tuner");
 
 using ::aos::monotonic_clock;
 using ::frc971::CANConfiguration;
@@ -1002,7 +1002,7 @@
 
     // Thread 5.
     // Set up CAN.
-    if (!FLAGS_ctre_diag_server) {
+    if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
       c_Phoenix_Diagnostics_SetSecondsToStart(-1);
       c_Phoenix_Diagnostics_Dispose();
     }
diff --git a/y2023_bot3/BUILD b/y2023_bot3/BUILD
index e1c8d06..e3d8ec0 100644
--- a/y2023_bot3/BUILD
+++ b/y2023_bot3/BUILD
@@ -158,8 +158,9 @@
         "//frc971/shooter_interpolation:interpolation",
         "//frc971/zeroing:pot_and_absolute_encoder",
         "//y2023_bot3/control_loops/drivetrain:polydrivetrain_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2023_bot3/autonomous/autonomous_actor.cc b/y2023_bot3/autonomous/autonomous_actor.cc
index 61811d7..5166ac8 100644
--- a/y2023_bot3/autonomous/autonomous_actor.cc
+++ b/y2023_bot3/autonomous/autonomous_actor.cc
@@ -4,6 +4,8 @@
 #include <cinttypes>
 #include <cmath>
 
+#include "absl/flags/flag.h"
+
 #include "aos/logging/logging.h"
 #include "aos/util/math.h"
 #include "frc971/control_loops/drivetrain/localizer_generated.h"
@@ -11,14 +13,14 @@
 #include "y2023_bot3/constants.h"
 #include "y2023_bot3/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
-DEFINE_bool(charged_up, true,
-            "If true run charged up autonomous mode. 2 Piece non-cable side");
-DEFINE_bool(charged_up_middle, false,
-            "If true run charged up middle autonomous mode. Starts middle, "
-            "places cube mid, mobility");
-DEFINE_bool(one_piece, false,
-            "End charged_up autonomous after first cube is placed.");
+ABSL_FLAG(bool, spline_auto, false, "Run simple test S-spline auto mode.");
+ABSL_FLAG(bool, charged_up, true,
+          "If true run charged up autonomous mode. 2 Piece non-cable side");
+ABSL_FLAG(bool, charged_up_middle, false,
+          "If true run charged up middle autonomous mode. Starts middle, "
+          "places cube mid, mobility");
+ABSL_FLAG(bool, one_piece, false,
+          "End charged_up autonomous after first cube is placed.");
 
 namespace y2023_bot3::autonomous {
 
@@ -109,14 +111,14 @@
     return;
   }
   sent_starting_position_ = false;
-  if (FLAGS_spline_auto) {
+  if (absl::GetFlag(FLAGS_spline_auto)) {
     test_spline_ =
         PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
                              std::placeholders::_1, alliance_),
                    SplineDirection::kForward);
 
     starting_position_ = test_spline_->starting_position();
-  } else if (FLAGS_charged_up) {
+  } else if (absl::GetFlag(FLAGS_charged_up)) {
     charged_up_splines_ = {
         PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
                              std::placeholders::_1, alliance_),
@@ -132,7 +134,7 @@
                    SplineDirection::kForward)};
     starting_position_ = charged_up_splines_.value()[0].starting_position();
     CHECK(starting_position_);
-  } else if (FLAGS_charged_up_middle) {
+  } else if (absl::GetFlag(FLAGS_charged_up_middle)) {
     charged_up_middle_splines_ = {
         PlanSpline(std::bind(&AutonomousSplines::SplineMiddle1, &auto_splines_,
                              std::placeholders::_1, alliance_),
@@ -186,7 +188,7 @@
     return false;
   }
 
-  if (FLAGS_charged_up) {
+  if (absl::GetFlag(FLAGS_charged_up)) {
     ChargedUp();
   } else {
     AOS_LOG(INFO, "No autonomous mode selected.");
diff --git a/y2023_bot3/constants.cc b/y2023_bot3/constants.cc
index be9ddbf..625e233 100644
--- a/y2023_bot3/constants.cc
+++ b/y2023_bot3/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2023_bot3/constants/constants_sender.cc b/y2023_bot3/constants/constants_sender.cc
index d6e5c28..12dd748 100644
--- a/y2023_bot3/constants/constants_sender.cc
+++ b/y2023_bot3/constants/constants_sender.cc
@@ -1,5 +1,6 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,17 +10,18 @@
 #include "y2023_bot3/constants/constants_generated.h"
 #include "y2023_bot3/constants/constants_list_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the AOS config.");
-DEFINE_string(constants_path, "constants.json", "Path to the constant file");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the AOS config.");
+ABSL_FLAG(std::string, constants_path, "constants.json",
+          "Path to the constant file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
   frc971::constants::ConstantSender<y2023_bot3::Constants,
                                     y2023_bot3::ConstantsList>
-      constants_sender(&event_loop, FLAGS_constants_path);
+      constants_sender(&event_loop, absl::GetFlag(FLAGS_constants_path));
   // Don't need to call Run().
   return 0;
 }
diff --git a/y2023_bot3/control_loops/drivetrain/trajectory_generator_main.cc b/y2023_bot3/control_loops/drivetrain/trajectory_generator_main.cc
index 7d6d5f2..a58d2b2 100644
--- a/y2023_bot3/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2023_bot3/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
@@ -8,8 +10,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -23,7 +25,7 @@
       ::y2023_bot3::control_loops::drivetrain::GetDrivetrainConfig());
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2023_bot3/control_loops/superstructure/superstructure.cc b/y2023_bot3/control_loops/superstructure/superstructure.cc
index b730ffa..7f68ab9 100644
--- a/y2023_bot3/control_loops/superstructure/superstructure.cc
+++ b/y2023_bot3/control_loops/superstructure/superstructure.cc
@@ -6,8 +6,8 @@
 #include "frc971/shooter_interpolation/interpolation.h"
 #include "frc971/zeroing/wrap.h"
 
-DEFINE_bool(ignore_distance, false,
-            "If true, ignore distance when shooting and obay joystick_reader");
+ABSL_FLAG(bool, ignore_distance, false,
+          "If true, ignore distance when shooting and obay joystick_reader");
 
 namespace y2023_bot3::control_loops::superstructure {
 
diff --git a/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc b/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc
index d9c9d15..964e5d1 100644
--- a/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc
@@ -1,6 +1,7 @@
 #include <chrono>
 #include <memory>
 
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -13,8 +14,8 @@
 #include "y2023_bot3/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2023_bot3/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace y2023_bot3::control_loops::superstructure::testing {
 namespace {}  // namespace
@@ -114,11 +115,11 @@
 
     SetEnabled(true);
 
-    if (!FLAGS_output_folder.empty()) {
-      unlink(FLAGS_output_folder.c_str());
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_folder).c_str());
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
diff --git a/y2023_bot3/control_loops/superstructure/superstructure_replay.cc b/y2023_bot3/control_loops/superstructure/superstructure_replay.cc
index ed39461..c1edafd 100644
--- a/y2023_bot3/control_loops/superstructure/superstructure_replay.cc
+++ b/y2023_bot3/control_loops/superstructure/superstructure_replay.cc
@@ -3,7 +3,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original superstructure status data will be on the
 // /original/superstructure channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/log_writer.h"
@@ -15,14 +15,14 @@
 #include "y2023_bot3/constants.h"
 #include "y2023_bot3/control_loops/superstructure/superstructure.h"
 
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/superstructure_replay/",
-              "Logs all channels to the provided logfile.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/superstructure_replay/",
+          "Logs all channels to the provided logfile.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -38,11 +38,11 @@
   aos::NodeEventLoopFactory *roborio =
       factory.GetNodeEventLoopFactory("roborio");
 
-  unlink(FLAGS_output_folder.c_str());
+  unlink(absl::GetFlag(FLAGS_output_folder).c_str());
   std::unique_ptr<aos::EventLoop> logger_event_loop =
       roborio->MakeEventLoop("logger");
   auto logger = std::make_unique<aos::logger::Logger>(logger_event_loop.get());
-  logger->StartLoggingOnRun(FLAGS_output_folder);
+  logger->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
 
   roborio->OnStartup([roborio]() {
     roborio->AlwaysStart<
diff --git a/y2023_bot3/rockpi/imu_main.cc b/y2023_bot3/rockpi/imu_main.cc
index cd443f2..ab5b263 100644
--- a/y2023_bot3/rockpi/imu_main.cc
+++ b/y2023_bot3/rockpi/imu_main.cc
@@ -1,16 +1,19 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/realtime.h"
 #include "frc971/imu_reader/imu.h"
 #include "y2023_bot3/constants.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   frc971::imu::Imu imu(
diff --git a/y2023_bot3/wpilib_interface.cc b/y2023_bot3/wpilib_interface.cc
index 1f0c003..d8813be 100644
--- a/y2023_bot3/wpilib_interface.cc
+++ b/y2023_bot3/wpilib_interface.cc
@@ -11,6 +11,7 @@
 #include <mutex>
 #include <thread>
 
+#include "absl/flags/flag.h"
 #include "ctre/phoenix/CANifier.h"
 
 #include "frc971/wpilib/ahal/AnalogInput.h"
@@ -60,9 +61,9 @@
 #include "y2023_bot3/control_loops/superstructure/superstructure_output_generated.h"
 #include "y2023_bot3/control_loops/superstructure/superstructure_position_generated.h"
 
-DEFINE_bool(ctre_diag_server, false,
-            "If true, enable the diagnostics server for interacting with "
-            "devices on the CAN bus using Phoenix Tuner");
+ABSL_FLAG(bool, ctre_diag_server, false,
+          "If true, enable the diagnostics server for interacting with "
+          "devices on the CAN bus using Phoenix Tuner");
 
 using ::aos::monotonic_clock;
 using ::y2023_bot3::constants::Values;
@@ -642,7 +643,7 @@
 
     // Thread 6.
     // Set up CAN.
-    if (!FLAGS_ctre_diag_server) {
+    if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
       c_Phoenix_Diagnostics_SetSecondsToStart(-1);
       c_Phoenix_Diagnostics_Dispose();
     }
diff --git a/y2024/BUILD b/y2024/BUILD
index 9ec03d0..baba07b 100644
--- a/y2024/BUILD
+++ b/y2024/BUILD
@@ -228,8 +228,9 @@
         "//y2024/control_loops/superstructure/extend:extend_plants",
         "//y2024/control_loops/superstructure/intake_pivot:intake_pivot_plants",
         "//y2024/control_loops/superstructure/turret:turret_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024/autonomous/autonomous_actor.cc b/y2024/autonomous/autonomous_actor.cc
index 83cf5b1..4afb9e4 100644
--- a/y2024/autonomous/autonomous_actor.cc
+++ b/y2024/autonomous/autonomous_actor.cc
@@ -4,6 +4,8 @@
 #include <cinttypes>
 #include <cmath>
 
+#include "absl/flags/flag.h"
+
 #include "aos/logging/logging.h"
 #include "aos/util/math.h"
 #include "frc971/control_loops/drivetrain/localizer_generated.h"
@@ -11,8 +13,8 @@
 #include "y2024/constants.h"
 #include "y2024/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
-DEFINE_bool(do_fifth_piece, true, "");
+ABSL_FLAG(bool, spline_auto, false, "Run simple test S-spline auto mode.");
+ABSL_FLAG(bool, do_fifth_piece, true, "");
 
 namespace y2024::autonomous {
 
@@ -344,7 +346,7 @@
       INFO, "Finished 4 notes at %lfs\n",
       aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
 
-  if (!FLAGS_do_fifth_piece) {
+  if (!absl::GetFlag(FLAGS_do_fifth_piece)) {
     AOS_LOG(INFO, "Exitting early due to --nodo_fifth_piece");
     return;
   }
diff --git a/y2024/constants.cc b/y2024/constants.cc
index a5194e2..1f4c0bc 100644
--- a/y2024/constants.cc
+++ b/y2024/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2024/constants/BUILD b/y2024/constants/BUILD
index 7e5a41a..f41492e 100644
--- a/y2024/constants/BUILD
+++ b/y2024/constants/BUILD
@@ -105,7 +105,8 @@
         ":constants_list_fbs",
         "//aos:init",
         "//aos:json_to_flatbuffer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024/constants/constants_formatter.cc b/y2024/constants/constants_formatter.cc
index d857407..0af18a9 100644
--- a/y2024/constants/constants_formatter.cc
+++ b/y2024/constants/constants_formatter.cc
@@ -1,4 +1,5 @@
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/flatbuffers.h"
 #include "aos/init.h"
diff --git a/y2024/constants/constants_sender.cc b/y2024/constants/constants_sender.cc
index bc442a2..e36d32c 100644
--- a/y2024/constants/constants_sender.cc
+++ b/y2024/constants/constants_sender.cc
@@ -1,5 +1,4 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,16 +8,17 @@
 #include "y2024/constants/constants_generated.h"
 #include "y2024/constants/constants_list_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the AOS config.");
-DEFINE_string(constants_path, "constants.json", "Path to the constant file");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the AOS config.");
+ABSL_FLAG(std::string, constants_path, "constants.json",
+          "Path to the constant file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
   frc971::constants::ConstantSender<y2024::Constants, y2024::ConstantsList>
-      constants_sender(&event_loop, FLAGS_constants_path);
+      constants_sender(&event_loop, absl::GetFlag(FLAGS_constants_path));
   // Don't need to call Run().
   return 0;
 }
diff --git a/y2024/control_loops/drivetrain/drivetrain_replay.cc b/y2024/control_loops/drivetrain/drivetrain_replay.cc
index d43b2af..73c2f87 100644
--- a/y2024/control_loops/drivetrain/drivetrain_replay.cc
+++ b/y2024/control_loops/drivetrain/drivetrain_replay.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -17,31 +17,32 @@
 #include "y2024/constants/simulated_constants_sender.h"
 #include "y2024/control_loops/drivetrain/drivetrain_base.h"
 
-DEFINE_string(config, "y2024/aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_bool(override_config, false,
-            "If set, override the logged config with --config.");
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/replayed",
-              "Name of the folder to write replayed logs to.");
-DEFINE_string(constants_path, "y2024/constants/constants.json",
-              "Path to the constant file");
+ABSL_FLAG(std::string, config, "y2024/aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(bool, override_config, false,
+          "If set, override the logged config with --config.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/replayed",
+          "Name of the folder to write replayed logs to.");
+ABSL_FLAG(std::string, constants_path, "y2024/constants/constants.json",
+          "Path to the constant file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   // sort logfiles
   const std::vector<aos::logger::LogFile> logfiles =
       aos::logger::SortParts(aos::logger::FindLogs(argc, argv));
 
   // open logfiles
-  aos::logger::LogReader reader(
-      logfiles, FLAGS_override_config ? &config.message() : nullptr);
+  aos::logger::LogReader reader(logfiles, absl::GetFlag(FLAGS_override_config)
+                                              ? &config.message()
+                                              : nullptr);
 
   reader.RemapLoggedChannel("/imu/constants", "y2024.Constants");
   reader.RemapLoggedChannel("/roborio/constants", "y2024.Constants");
@@ -58,8 +59,9 @@
 
   reader.RegisterWithoutStarting(factory.get());
 
-  y2024::SendSimulationConstants(reader.event_loop_factory(), FLAGS_team,
-                                 FLAGS_constants_path, {"roborio"});
+  y2024::SendSimulationConstants(
+      reader.event_loop_factory(), absl::GetFlag(FLAGS_team),
+      absl::GetFlag(FLAGS_constants_path), {"roborio"});
 
   const aos::Node *node = nullptr;
   if (aos::configuration::MultiNode(reader.configuration())) {
@@ -86,7 +88,7 @@
         std::make_unique<frc971::control_loops::drivetrain::DrivetrainLoop>(
             drivetrain_config, drivetrain_event_loop.get(), localizer.get());
     loggers.push_back(std::make_unique<aos::util::LoggerState>(
-        factory.get(), node, FLAGS_output_folder));
+        factory.get(), node, absl::GetFlag(FLAGS_output_folder)));
     // The Trajectory information is NOT_LOGGED, so we need to rerun it against
     // the SplineGoals that we have in the log.
     node_factory
diff --git a/y2024/control_loops/drivetrain/trajectory_generator_main.cc b/y2024/control_loops/drivetrain/trajectory_generator_main.cc
index f53f79a..b01bea0 100644
--- a/y2024/control_loops/drivetrain/trajectory_generator_main.cc
+++ b/y2024/control_loops/drivetrain/trajectory_generator_main.cc
@@ -1,6 +1,8 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/constants/constants_sender_lib.h"
@@ -10,8 +12,8 @@
 
 using ::frc971::control_loops::drivetrain::TrajectoryGenerator;
 
-DEFINE_bool(skip_renicing, false,
-            "If true, skip renicing the trajectory generator.");
+ABSL_FLAG(bool, skip_renicing, false,
+          "If true, skip renicing the trajectory generator.");
 
 int main(int argc, char *argv[]) {
   ::aos::InitGoogle(&argc, &argv);
@@ -27,7 +29,7 @@
       ::y2024::control_loops::drivetrain::GetDrivetrainConfig(&event_loop));
 
   event_loop.OnRun([]() {
-    if (FLAGS_skip_renicing) {
+    if (absl::GetFlag(FLAGS_skip_renicing)) {
       LOG(WARNING) << "Ignoring request to renice to -20 due to "
                       "--skip_renicing.";
     } else {
diff --git a/y2024/control_loops/superstructure/BUILD b/y2024/control_loops/superstructure/BUILD
index 6c1075a..f175d19 100644
--- a/y2024/control_loops/superstructure/BUILD
+++ b/y2024/control_loops/superstructure/BUILD
@@ -136,8 +136,9 @@
         "//frc971/control_loops:control_loops_fbs",
         "//frc971/control_loops:profiled_subsystem_fbs",
         "//frc971/control_loops:static_zeroing_single_dof_profiled_subsystem",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/functional:bind_front",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024/control_loops/superstructure/collision_avoidance.cc b/y2024/control_loops/superstructure/collision_avoidance.cc
index bd82fe0..a4f3a35 100644
--- a/y2024/control_loops/superstructure/collision_avoidance.cc
+++ b/y2024/control_loops/superstructure/collision_avoidance.cc
@@ -3,7 +3,8 @@
 #include <cmath>
 
 #include "absl/functional/bind_front.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace y2024::control_loops::superstructure {
 
diff --git a/y2024/control_loops/superstructure/superstructure.cc b/y2024/control_loops/superstructure/superstructure.cc
index 7f7da4f..a33fc87 100644
--- a/y2024/control_loops/superstructure/superstructure.cc
+++ b/y2024/control_loops/superstructure/superstructure.cc
@@ -9,8 +9,8 @@
 #include "frc971/shooter_interpolation/interpolation.h"
 #include "frc971/zeroing/wrap.h"
 
-DEFINE_bool(ignore_distance, false,
-            "If true, ignore distance when shooting and obey joystick_reader");
+ABSL_FLAG(bool, ignore_distance, false,
+          "If true, ignore distance when shooting and obey joystick_reader");
 
 // The threshold used when decided if the extend is close enough to a goal to
 // continue.
diff --git a/y2024/control_loops/superstructure/superstructure_lib_test.cc b/y2024/control_loops/superstructure/superstructure_lib_test.cc
index 719a29b..cf518e7 100644
--- a/y2024/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2024/control_loops/superstructure/superstructure_lib_test.cc
@@ -1,6 +1,7 @@
 #include <chrono>
 #include <memory>
 
+#include "absl/flags/flag.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -20,8 +21,8 @@
 #include "y2024/control_loops/superstructure/superstructure.h"
 #include "y2024/control_loops/superstructure/turret/turret_plant.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
 
 namespace y2024::control_loops::superstructure::testing {
 
@@ -336,11 +337,11 @@
 
     SetEnabled(true);
 
-    if (!FLAGS_output_folder.empty()) {
-      unlink(FLAGS_output_folder.c_str());
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
+      unlink(absl::GetFlag(FLAGS_output_folder).c_str());
       logger_event_loop_ = MakeEventLoop("logger", roborio_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
diff --git a/y2024/control_loops/superstructure/superstructure_main.cc b/y2024/control_loops/superstructure/superstructure_main.cc
index a5ab8ed..90c5eb4 100644
--- a/y2024/control_loops/superstructure/superstructure_main.cc
+++ b/y2024/control_loops/superstructure/superstructure_main.cc
@@ -2,8 +2,8 @@
 #include "aos/init.h"
 #include "y2024/control_loops/superstructure/superstructure.h"
 
-DEFINE_string(arm_trajectories, "arm_trajectories_generated.bfbs",
-              "The path to the generated arm trajectories bfbs file.");
+ABSL_FLAG(std::string, arm_trajectories, "arm_trajectories_generated.bfbs",
+          "The path to the generated arm trajectories bfbs file.");
 
 using y2024::control_loops::superstructure::Superstructure;
 
diff --git a/y2024/control_loops/superstructure/superstructure_replay.cc b/y2024/control_loops/superstructure/superstructure_replay.cc
index ab88a46..37ab08f 100644
--- a/y2024/control_loops/superstructure/superstructure_replay.cc
+++ b/y2024/control_loops/superstructure/superstructure_replay.cc
@@ -3,7 +3,7 @@
 // replayed, so that it can then be run through the plotting tool or analyzed
 // in some other way. The original superstructure status data will be on the
 // /original/superstructure channel.
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/logging/log_writer.h"
@@ -15,14 +15,14 @@
 #include "y2024/constants.h"
 #include "y2024/control_loops/superstructure/superstructure.h"
 
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/superstructure_replay/",
-              "Logs all channels to the provided logfile.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/superstructure_replay/",
+          "Logs all channels to the provided logfile.");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -40,11 +40,11 @@
   aos::NodeEventLoopFactory *roborio =
       factory.GetNodeEventLoopFactory("roborio");
 
-  unlink(FLAGS_output_folder.c_str());
+  unlink(absl::GetFlag(FLAGS_output_folder).c_str());
   std::unique_ptr<aos::EventLoop> logger_event_loop =
       roborio->MakeEventLoop("logger");
   auto logger = std::make_unique<aos::logger::Logger>(logger_event_loop.get());
-  logger->StartLoggingOnRun(FLAGS_output_folder);
+  logger->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
 
   roborio->OnStartup([roborio]() {
     roborio->AlwaysStart<y2024::control_loops::superstructure::Superstructure>(
diff --git a/y2024/joystick_reader.cc b/y2024/joystick_reader.cc
index 88bf441..4b0bec9 100644
--- a/y2024/joystick_reader.cc
+++ b/y2024/joystick_reader.cc
@@ -4,6 +4,8 @@
 #include <cstdio>
 #include <cstring>
 
+#include "absl/flags/flag.h"
+
 #include "aos/actions/actions.h"
 #include "aos/init.h"
 #include "aos/logging/logging.h"
@@ -32,10 +34,10 @@
 using frc971::input::driver_station::POVLocation;
 using Side = frc971::control_loops::drivetrain::RobotSide;
 
-DEFINE_double(speaker_altitude_position_override, -1,
-              "If set, use this as the altitude angle for the fixed shot.");
-DEFINE_bool(allow_force_preload, false,
-            "If set, enable the kForcePreload button.");
+ABSL_FLAG(double, speaker_altitude_position_override, -1,
+          "If set, use this as the altitude angle for the fixed shot.");
+ABSL_FLAG(bool, allow_force_preload, false,
+          "If set, enable the kForcePreload button.");
 
 namespace y2024::input::joysticks {
 
@@ -140,7 +142,7 @@
           superstructure::NoteGoal::NONE);
     }
     auto shooter_goal = superstructure_goal_builder->add_shooter_goal();
-    shooter_goal->set_preloaded(FLAGS_allow_force_preload &&
+    shooter_goal->set_preloaded(absl::GetFlag(FLAGS_allow_force_preload) &&
                                 data.IsPressed(kForceLoad));
     if (data.IsPressed(kAutoAim)) {
       shooter_goal->set_auto_aim(
@@ -160,10 +162,10 @@
       catapult_goal->set_shot_velocity(robot_constants_->common()
                                            ->shooter_speaker_set_point()
                                            ->shot_velocity());
-      if (FLAGS_speaker_altitude_position_override > 0) {
+      if (absl::GetFlag(FLAGS_speaker_altitude_position_override) > 0) {
         PopulateStaticZeroingSingleDOFProfiledSubsystemGoal(
             shooter_goal->add_altitude_position(),
-            FLAGS_speaker_altitude_position_override);
+            absl::GetFlag(FLAGS_speaker_altitude_position_override));
       } else {
         PopulateStaticZeroingSingleDOFProfiledSubsystemGoal(
             shooter_goal->add_altitude_position(),
diff --git a/y2024/localizer/localizer.cc b/y2024/localizer/localizer.cc
index 90423ca..cb11c44 100644
--- a/y2024/localizer/localizer.cc
+++ b/y2024/localizer/localizer.cc
@@ -1,6 +1,6 @@
 #include "y2024/localizer/localizer.h"
 
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/containers/sized_array.h"
 #include "frc971/control_loops/drivetrain/localizer_generated.h"
@@ -9,38 +9,36 @@
 #include "frc971/vision/target_map_utils.h"
 #include "y2024/constants.h"
 
-DEFINE_double(max_pose_error, 1e-5,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(max_distortion, 1000.0, "");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_double(distortion_noise_scalar, 4.0,
-              "Scale the target pose distortion factor by this when computing "
-              "the noise.");
-DEFINE_double(
-    max_implied_yaw_error, 5.0,
+ABSL_FLAG(double, max_pose_error, 1e-5,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_distortion, 1000.0, "");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(double, distortion_noise_scalar, 4.0,
+          "Scale the target pose distortion factor by this when computing "
+          "the noise.");
+ABSL_FLAG(
+    double, max_implied_yaw_error, 5.0,
     "Reject target poses that imply a robot yaw of more than this many degrees "
     "off from our estimate.");
-DEFINE_double(
-    max_implied_teleop_yaw_error, 30.0,
+ABSL_FLAG(
+    double, max_implied_teleop_yaw_error, 30.0,
     "Reject target poses that imply a robot yaw of more than this many degrees "
     "off from our estimate.");
-DEFINE_double(max_distance_to_target, 5.0,
-              "Reject target poses that have a 3d distance of more than this "
-              "many meters.");
-DEFINE_double(max_auto_image_robot_speed, 5.0,
-              "Reject target poses when the robot is travelling faster than "
-              "this speed in auto.");
-DEFINE_bool(
-    do_xytheta_corrections, false,
+ABSL_FLAG(double, max_distance_to_target, 5.0,
+          "Reject target poses that have a 3d distance of more than this "
+          "many meters.");
+ABSL_FLAG(double, max_auto_image_robot_speed, 5.0,
+          "Reject target poses when the robot is travelling faster than "
+          "this speed in auto.");
+ABSL_FLAG(
+    bool, do_xytheta_corrections, false,
     "If set, uses the x/y/theta corrector rather than a heading/distance/skew "
     "one. This is better conditioned currently, but is theoretically worse due "
     "to not capturing noise effectively.");
-DEFINE_bool(
-    always_use_extra_tags, true,
-    "If set, we will use the \"deweighted\" tags even in auto mode (this "
-    "affects april tags whose field positions we do not trust as much).");
+ABSL_FLAG(bool, always_use_extra_tags, true,
+          "If set, we will use the \"deweighted\" tags even in auto mode (this "
+          "affects april tags whose field positions we do not trust as much).");
 
 namespace y2024::localizer {
 namespace {
@@ -380,8 +378,8 @@
 }
 
 namespace {
-// Converts a camera transformation matrix from treating the +Z axis from
-// pointing straight out the lens to having the +X pointing straight out the
+// converts a camera transformation matrix from treating the +z axis from
+// pointing straight out the lens to having the +x pointing straight out the
 // lens, with +Z going "up" (i.e., -Y in the normal convention) and +Y going
 // leftwards (i.e., -X in the normal convention).
 Localizer::Transform ZToXCamera(const Localizer::Transform &transform) {
@@ -419,7 +417,8 @@
   }
   double april_tag_noise_scalar = 1.0;
   if (DeweightAprilTag(target_id)) {
-    if (!FLAGS_always_use_extra_tags && utils_.MaybeInAutonomous()) {
+    if (!absl::GetFlag(FLAGS_always_use_extra_tags) &&
+        utils_.MaybeInAutonomous()) {
       VLOG(1) << "Rejecting target due to auto invalid ID " << target_id;
       RejectImage(camera_index, RejectionReason::NO_SUCH_TARGET, debug_builder);
       return;
@@ -454,12 +453,13 @@
     VLOG(1) << "Rejecting image due to being too old.";
     return RejectImage(camera_index, RejectionReason::IMAGE_TOO_OLD,
                        debug_builder);
-  } else if (target.pose_error() > FLAGS_max_pose_error) {
+  } else if (target.pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
     VLOG(1) << "Rejecting target due to high pose error "
             << target.pose_error();
     return RejectImage(camera_index, RejectionReason::HIGH_POSE_ERROR,
                        debug_builder);
-  } else if (target.pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+  } else if (target.pose_error_ratio() >
+             absl::GetFlag(FLAGS_max_pose_error_ratio)) {
     VLOG(1) << "Rejecting target due to high pose error ratio "
             << target.pose_error_ratio();
     return RejectImage(camera_index, RejectionReason::HIGH_POSE_ERROR_RATIO,
@@ -484,7 +484,8 @@
   noises(Corrector::kSkew) *= distance_noise_scalar;
   // TODO(james): This is leftover from last year; figure out if we want it.
   // Scale noise by the distortion factor for this detection
-  noises *= (1.0 + FLAGS_distortion_noise_scalar * target.distortion_factor());
+  noises *= (1.0 + absl::GetFlag(FLAGS_distortion_noise_scalar) *
+                       target.distortion_factor());
   noises *= april_tag_noise_scalar;
   noises *= (1.0 + std::abs(robot_speed));
 
@@ -522,22 +523,24 @@
                                 corrector.observed_camera_pose().abs_theta());
   constexpr double kDegToRad = M_PI / 180.0;
   const double yaw_threshold =
-      (utils_.MaybeInAutonomous() ? FLAGS_max_implied_yaw_error
-                                  : FLAGS_max_implied_teleop_yaw_error) *
+      (utils_.MaybeInAutonomous()
+           ? absl::GetFlag(FLAGS_max_implied_yaw_error)
+           : absl::GetFlag(FLAGS_max_implied_teleop_yaw_error)) *
       kDegToRad;
 
-  if (target.distortion_factor() > FLAGS_max_distortion) {
+  if (target.distortion_factor() > absl::GetFlag(FLAGS_max_distortion)) {
     VLOG(1) << "Rejecting target due to high distortion.";
     return RejectImage(camera_index, RejectionReason::HIGH_DISTORTION,
                        debug_builder);
   } else if (utils_.MaybeInAutonomous() &&
-             (std::abs(robot_speed) > FLAGS_max_auto_image_robot_speed)) {
+             (std::abs(robot_speed) >
+              absl::GetFlag(FLAGS_max_auto_image_robot_speed))) {
     return RejectImage(camera_index, RejectionReason::ROBOT_TOO_FAST,
                        debug_builder);
   } else if (std::abs(camera_yaw_error) > yaw_threshold) {
     return RejectImage(camera_index, RejectionReason::HIGH_IMPLIED_YAW_ERROR,
                        debug_builder);
-  } else if (distance_to_target > FLAGS_max_distance_to_target) {
+  } else if (distance_to_target > absl::GetFlag(FLAGS_max_distance_to_target)) {
     return RejectImage(camera_index, RejectionReason::HIGH_DISTANCE_TO_TARGET,
                        debug_builder);
   }
@@ -551,15 +554,15 @@
   // the camera measurement and the current estimate of the
   // pose. This doesn't affect any of the math, it just makes the code a bit
   // more convenient to write given the Correct() interface we already have.
-  if (FLAGS_do_xytheta_corrections) {
+  if (absl::GetFlag(FLAGS_do_xytheta_corrections)) {
     Eigen::Vector3d Z(measured_pose.rel_pos().x(), measured_pose.rel_pos().y(),
                       measured_pose.rel_theta());
     Eigen::Matrix<double, 3, 1> xyz_noises(0.2, 0.2, 0.5);
     xyz_noises *= distance_noise_scalar;
     xyz_noises *= april_tag_noise_scalar;
     // Scale noise by the distortion factor for this detection
-    xyz_noises *=
-        (1.0 + FLAGS_distortion_noise_scalar * target.distortion_factor());
+    xyz_noises *= (1.0 + absl::GetFlag(FLAGS_distortion_noise_scalar) *
+                             target.distortion_factor());
 
     Eigen::Matrix3d R_xyz = Eigen::Matrix3d::Zero();
     R_xyz.diagonal() = xyz_noises.cwiseAbs2();
diff --git a/y2024/localizer/localizer_main.cc b/y2024/localizer/localizer_main.cc
index 25466d2..1da4ac9 100644
--- a/y2024/localizer/localizer_main.cc
+++ b/y2024/localizer/localizer_main.cc
@@ -1,16 +1,19 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/constants/constants_sender_lib.h"
 #include "y2024/control_loops/drivetrain/drivetrain_base.h"
 #include "y2024/localizer/localizer.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<y2024::Constants>(&config.message());
 
diff --git a/y2024/localizer/localizer_replay.cc b/y2024/localizer/localizer_replay.cc
index ad0caae..52fd917 100644
--- a/y2024/localizer/localizer_replay.cc
+++ b/y2024/localizer/localizer_replay.cc
@@ -1,4 +1,4 @@
-#include "gflags/gflags.h"
+#include "absl/flags/flag.h"
 
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
@@ -14,31 +14,32 @@
 #include "y2024/control_loops/drivetrain/drivetrain_base.h"
 #include "y2024/localizer/localizer.h"
 
-DEFINE_string(config, "y2024/aos_config.json",
-              "Name of the config file to replay using.");
-DEFINE_bool(override_config, false,
-            "If set, override the logged config with --config.");
-DEFINE_int32(team, 971, "Team number to use for logfile replay.");
-DEFINE_string(output_folder, "/tmp/replayed",
-              "Name of the folder to write replayed logs to.");
-DEFINE_string(constants_path, "y2024/constants/constants.json",
-              "Path to the constant file");
+ABSL_FLAG(std::string, config, "y2024/aos_config.json",
+          "Name of the config file to replay using.");
+ABSL_FLAG(bool, override_config, false,
+          "If set, override the logged config with --config.");
+ABSL_FLAG(int32_t, team, 971, "Team number to use for logfile replay.");
+ABSL_FLAG(std::string, output_folder, "/tmp/replayed",
+          "Name of the folder to write replayed logs to.");
+ABSL_FLAG(std::string, constants_path, "y2024/constants/constants.json",
+          "Path to the constant file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
-  aos::network::OverrideTeamNumber(FLAGS_team);
+  aos::network::OverrideTeamNumber(absl::GetFlag(FLAGS_team));
 
   const aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   // sort logfiles
   const std::vector<aos::logger::LogFile> logfiles =
       aos::logger::SortParts(aos::logger::FindLogs(argc, argv));
 
   // open logfiles
-  aos::logger::LogReader reader(
-      logfiles, FLAGS_override_config ? &config.message() : nullptr);
+  aos::logger::LogReader reader(logfiles, absl::GetFlag(FLAGS_override_config)
+                                              ? &config.message()
+                                              : nullptr);
 
   reader.RemapLoggedChannel("/localizer", "y2024.localizer.Status");
   for (const auto orin : {"orin1", "imu"}) {
@@ -59,8 +60,9 @@
 
   reader.RegisterWithoutStarting(factory.get());
 
-  y2024::SendSimulationConstants(reader.event_loop_factory(), FLAGS_team,
-                                 FLAGS_constants_path);
+  y2024::SendSimulationConstants(reader.event_loop_factory(),
+                                 absl::GetFlag(FLAGS_team),
+                                 absl::GetFlag(FLAGS_constants_path));
 
   const aos::Node *node = nullptr;
   if (aos::configuration::MultiNode(reader.configuration())) {
@@ -75,7 +77,7 @@
     node_factory->AlwaysStart<frc971::imu_fdcan::DualImuBlender>(
         "dual_imu_blender");
     loggers.push_back(std::make_unique<aos::util::LoggerState>(
-        factory.get(), node, FLAGS_output_folder));
+        factory.get(), node, absl::GetFlag(FLAGS_output_folder)));
   });
 
   reader.event_loop_factory()->Run();
diff --git a/y2024/localizer/localizer_test.cc b/y2024/localizer/localizer_test.cc
index e5815e0..d02807f 100644
--- a/y2024/localizer/localizer_test.cc
+++ b/y2024/localizer/localizer_test.cc
@@ -1,5 +1,8 @@
 #include "y2024/localizer/localizer.h"
 
+#include "absl/flags/declare.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/reflection.h"
 #include "gtest/gtest.h"
 
 #include "aos/events/logging/log_writer.h"
@@ -14,9 +17,9 @@
 #include "y2024/control_loops/drivetrain/drivetrain_base.h"
 #include "y2024/localizer/status_generated.h"
 
-DEFINE_string(output_folder, "",
-              "If set, logs all channels to the provided logfile.");
-DECLARE_double(max_distance_to_target);
+ABSL_FLAG(std::string, output_folder, "",
+          "If set, logs all channels to the provided logfile.");
+ABSL_DECLARE_FLAG(double, max_distance_to_target);
 
 namespace y2024::localizer::testing {
 
@@ -76,7 +79,7 @@
                 ->MakeFetcher<frc971::controls::LocalizerOutput>("/localizer")),
         status_fetcher_(
             imu_test_event_loop_->MakeFetcher<Status>("/localizer")) {
-    FLAGS_max_distance_to_target = 100.0;
+    absl::SetFlag(&FLAGS_max_distance_to_target, 100.0);
     {
       aos::TimerHandler *timer = roborio_test_event_loop_->AddTimer([this]() {
         {
@@ -222,11 +225,11 @@
     CHECK(status_fetcher_.Fetch());
     CHECK(status_fetcher_->imu()->zeroed());
 
-    if (!FLAGS_output_folder.empty()) {
+    if (!absl::GetFlag(FLAGS_output_folder).empty()) {
       logger_event_loop_ =
           event_loop_factory_.MakeEventLoop("logger", imu_node_);
       logger_ = std::make_unique<aos::logger::Logger>(logger_event_loop_.get());
-      logger_->StartLoggingOnRun(FLAGS_output_folder);
+      logger_->StartLoggingOnRun(absl::GetFlag(FLAGS_output_folder));
     }
   }
 
@@ -313,7 +316,7 @@
   double pose_error_ratio_ = 0.1;
   double implied_yaw_error_ = 0.0;
 
-  gflags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
 };
 
 // Test a simple scenario with no errors where the robot should just drive
diff --git a/y2024/orin/BUILD b/y2024/orin/BUILD
index b8ee2bc..c8b899b 100644
--- a/y2024/orin/BUILD
+++ b/y2024/orin/BUILD
@@ -10,6 +10,7 @@
         "//aos/events:shm_event_loop",
         "//aos/time",
         "//frc971/can_logger:can_logger_lib",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
diff --git a/y2024/vision/BUILD b/y2024/vision/BUILD
index 500cad6..fb73392 100644
--- a/y2024/vision/BUILD
+++ b/y2024/vision/BUILD
@@ -54,9 +54,10 @@
         "//third_party:cudart",
         "//third_party/apriltag",
         "//y2024/constants:constants_fbs",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
         "@com_github_nvidia_cccl//:cccl",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024/vision/apriltag_detector.cc b/y2024/vision/apriltag_detector.cc
index 5edcf36..998625c 100644
--- a/y2024/vision/apriltag_detector.cc
+++ b/y2024/vision/apriltag_detector.cc
@@ -1,17 +1,20 @@
 
 #include <string>
 
+#include "absl/flags/flag.h"
+
 #include "aos/init.h"
 #include "frc971/orin/gpu_apriltag.h"
 #include "y2024/constants/constants_generated.h"
 #include "y2024/vision/vision_util.h"
 
-DEFINE_string(channel, "/camera", "Channel name");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 void GpuApriltagDetector() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<y2024::Constants>(&config.message());
 
@@ -20,15 +23,15 @@
   const frc971::constants::ConstantsFetcher<y2024::Constants> calibration_data(
       &event_loop);
 
-  CHECK(FLAGS_channel.length() == 8);
-  int camera_id = std::stoi(FLAGS_channel.substr(7, 1));
+  CHECK(absl::GetFlag(FLAGS_channel).length() == 8);
+  int camera_id = std::stoi(absl::GetFlag(FLAGS_channel).substr(7, 1));
   const frc971::vision::calibration::CameraCalibration *calibration =
       y2024::vision::FindCameraCalibration(
           calibration_data.constants(),
           event_loop.node()->name()->string_view(), camera_id);
 
-  frc971::apriltag::ApriltagDetector detector(&event_loop, FLAGS_channel,
-                                              calibration);
+  frc971::apriltag::ApriltagDetector detector(
+      &event_loop, absl::GetFlag(FLAGS_channel), calibration);
 
   // TODO(austin): Figure out our core pinning strategy.
   // event_loop.SetRuntimeAffinity(aos::MakeCpusetFromCpus({5}));
diff --git a/y2024/vision/calibrate_multi_cameras.cc b/y2024/vision/calibrate_multi_cameras.cc
index 979c0d4..7a9f412 100644
--- a/y2024/vision/calibrate_multi_cameras.cc
+++ b/y2024/vision/calibrate_multi_cameras.cc
@@ -1,5 +1,7 @@
 #include <numeric>
 
+#include "absl/flags/flag.h"
+
 #include "aos/configuration.h"
 #include "aos/events/logging/log_reader.h"
 #include "aos/events/simulated_event_loop.h"
@@ -28,32 +30,31 @@
 #include "y2024/constants/simulated_constants_sender.h"
 #include "y2024/vision/vision_util.h"
 
-DEFINE_bool(alt_view, false,
-            "If true, show visualization from field level, rather than above");
-DEFINE_string(config, "",
-              "If set, override the log's config file with this one.");
-DEFINE_string(constants_path, "y2024/constants/constants.json",
-              "Path to the constant file");
-DEFINE_double(max_pose_error, 5e-5,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_string(output_folder, "/tmp",
-              "Directory in which to store the updated calibration files");
-DEFINE_string(target_type, "charuco_diamond",
-              "Type of target being used [aruco, charuco, charuco_diamond]");
-DEFINE_int32(team_number, 0,
-             "Required: Use the calibration for a node with this team number");
-DEFINE_uint64(
-    wait_key, 1,
+ABSL_FLAG(bool, alt_view, false,
+          "If true, show visualization from field level, rather than above");
+ABSL_FLAG(std::string, config, "",
+          "If set, override the log's config file with this one.");
+ABSL_FLAG(std::string, constants_path, "y2024/constants/constants.json",
+          "Path to the constant file");
+ABSL_FLAG(double, max_pose_error, 5e-5,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(std::string, output_folder, "/tmp",
+          "Directory in which to store the updated calibration files");
+ABSL_FLAG(std::string, target_type, "charuco_diamond",
+          "Type of target being used [aruco, charuco, charuco_diamond]");
+ABSL_FLAG(int32_t, team_number, 0,
+          "Required: Use the calibration for a node with this team number");
+ABSL_FLAG(
+    uint64_t, wait_key, 1,
     "Time in ms to wait between images (0 to wait indefinitely until click)");
-DEFINE_bool(robot, false,
-            "If true we're calibrating extrinsics for the robot, use the "
-            "correct node path for the robot.");
+ABSL_FLAG(bool, robot, false,
+          "If true we're calibrating extrinsics for the robot, use the "
+          "correct node path for the robot.");
 
-DECLARE_int32(min_target_id);
-DECLARE_int32(max_target_id);
+ABSL_DECLARE_FLAG(int32_t, min_target_id);
+ABSL_DECLARE_FLAG(int32_t, max_target_id);
 
 // Calibrate extrinsic relationship between cameras using two targets
 // seen jointly between cameras.  Uses two types of information: 1)
@@ -187,7 +188,7 @@
   Eigen::Affine3d H_world_board;
   H_world_board = Eigen::Translation3d::Identity() *
                   Eigen::AngleAxisd(M_PI / 2.0, Eigen::Vector3d::UnitX());
-  if (FLAGS_alt_view) {
+  if (absl::GetFlag(FLAGS_alt_view)) {
     // Don't rotate -- this is like viewing from the side
     H_world_board = Eigen::Translation3d(0.0, 0.0, 3.0);
   }
@@ -228,7 +229,7 @@
     // Store this observation of the transform between two boards
     two_board_extrinsics_list.push_back(boardA_boardB);
 
-    if (FLAGS_visualize) {
+    if (absl::GetFlag(FLAGS_visualize)) {
       vis_robot_.DrawFrameAxes(
           H_world_board,
           std::string("Board ") + std::to_string(target_poses[from_index].id),
@@ -272,7 +273,8 @@
       // This bit is just for visualization and checking purposes-- use the
       // last two-board observation to figure out the current estimate
       // between the two cameras
-      if (FLAGS_visualize && two_board_extrinsics_list.size() > 0) {
+      if (absl::GetFlag(FLAGS_visualize) &&
+          two_board_extrinsics_list.size() > 0) {
         draw_vis = true;
         TimestampedCameraDetection &last_two_board_ext =
             two_board_extrinsics_list.back();
@@ -329,18 +331,18 @@
     }
   }
 
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     if (!rgb_image.empty()) {
       std::string image_name = camera_name + " Image";
       cv::Mat rgb_small;
       cv::resize(rgb_image, rgb_small, cv::Size(), 0.5, 0.5);
       cv::imshow(image_name, rgb_small);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
     }
 
     if (draw_vis) {
       cv::imshow("Overhead View", vis_robot_.image_);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
       vis_robot_.ClearImage();
     }
   }
@@ -357,23 +359,24 @@
   for (const auto *target_pose_fbs : *map.target_poses()) {
     // Skip detections with invalid ids
     if (static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) <
-            FLAGS_min_target_id ||
+            absl::GetFlag(FLAGS_min_target_id) ||
         static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) >
-            FLAGS_max_target_id) {
+            absl::GetFlag(FLAGS_max_target_id)) {
       VLOG(1) << "Skipping tag from " << camera_name << " with invalid id of "
               << target_pose_fbs->id();
       continue;
     }
 
     // Skip detections with high pose errors
-    if (target_pose_fbs->pose_error() > FLAGS_max_pose_error) {
+    if (target_pose_fbs->pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
       LOG(INFO) << "Skipping tag from " << camera_name << " with id "
                 << target_pose_fbs->id() << " due to pose error of "
                 << target_pose_fbs->pose_error();
       continue;
     }
     // Skip detections with high pose error ratios
-    if (target_pose_fbs->pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+    if (target_pose_fbs->pose_error_ratio() >
+        absl::GetFlag(FLAGS_max_pose_error_ratio)) {
       LOG(INFO) << "Skipping tag from " << camera_name << " with id "
                 << target_pose_fbs->id() << " due to pose error ratio of "
                 << target_pose_fbs->pose_error_ratio();
@@ -437,9 +440,10 @@
   vis_robot_.SetDefaultViewpoint(kImageWidth, kFocalLength);
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config =
-      (FLAGS_config.empty()
+      (absl::GetFlag(FLAGS_config).empty()
            ? std::nullopt
-           : std::make_optional(aos::configuration::ReadConfig(FLAGS_config)));
+           : std::make_optional(
+                 aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config))));
 
   // open logfiles
   aos::logger::LogReader reader(
@@ -448,15 +452,16 @@
 
   reader.RemapLoggedChannel("/imu/constants", "y2024.Constants");
   reader.RemapLoggedChannel("/orin1/constants", "y2024.Constants");
-  if (FLAGS_robot) {
+  if (absl::GetFlag(FLAGS_robot)) {
     reader.RemapLoggedChannel("/roborio/constants", "y2024.Constants");
   }
   reader.Register();
 
-  y2024::SendSimulationConstants(reader.event_loop_factory(), FLAGS_team_number,
-                                 FLAGS_constants_path);
+  y2024::SendSimulationConstants(reader.event_loop_factory(),
+                                 absl::GetFlag(FLAGS_team_number),
+                                 absl::GetFlag(FLAGS_constants_path));
 
-  VLOG(1) << "Using target type " << FLAGS_target_type;
+  VLOG(1) << "Using target type " << absl::GetFlag(FLAGS_target_type);
 
   std::vector<const calibration::CameraCalibration *> calibration_list;
 
@@ -591,7 +596,7 @@
         Eigen::Affine3d H_world_board;
         H_world_board = Eigen::Translation3d::Identity() *
                         Eigen::AngleAxisd(M_PI / 2.0, Eigen::Vector3d::UnitX());
-        if (FLAGS_alt_view) {
+        if (absl::GetFlag(FLAGS_alt_view)) {
           H_world_board = Eigen::Translation3d(0.0, 0.0, 3.0);
         }
 
@@ -675,9 +680,9 @@
       CameraNode &camera_node = node_list[i + 1];
       const std::string calibration_filename =
           frc971::vision::CalibrationFilename(
-              FLAGS_output_folder, camera_node.node_name, FLAGS_team_number,
-              camera_node.camera_number, cal_copy.message().camera_id()->data(),
-              time_ss.str());
+              absl::GetFlag(FLAGS_output_folder), camera_node.node_name,
+              absl::GetFlag(FLAGS_team_number), camera_node.camera_number,
+              cal_copy.message().camera_id()->data(), time_ss.str());
       LOG(INFO) << calibration_filename << " -> "
                 << aos::FlatbufferToJson(merged_calibration,
                                          {.multi_line = true});
@@ -686,7 +691,7 @@
           calibration_filename,
           aos::FlatbufferToJson(merged_calibration, {.multi_line = true}));
 
-      if (FLAGS_visualize) {
+      if (absl::GetFlag(FLAGS_visualize)) {
         // Draw each of the updated extrinsic camera locations
         vis_robot_.SetDefaultViewpoint(1000.0, 1500.0);
         vis_robot_.DrawFrameAxes(
@@ -695,7 +700,7 @@
       }
     }
   }
-  if (FLAGS_visualize) {
+  if (absl::GetFlag(FLAGS_visualize)) {
     // And don't forget to draw the base camera location
     vis_robot_.DrawFrameAxes(updated_extrinsics[0],
                              node_list.at(0).camera_name(),
diff --git a/y2024/vision/target_mapping.cc b/y2024/vision/target_mapping.cc
index 5681580..f5fa34c 100644
--- a/y2024/vision/target_mapping.cc
+++ b/y2024/vision/target_mapping.cc
@@ -1,6 +1,7 @@
 #include <string>
 
 #include "Eigen/Dense"
+#include "absl/flags/flag.h"
 #include "opencv2/aruco.hpp"
 #include "opencv2/calib3d.hpp"
 #include "opencv2/core/eigen.hpp"
@@ -25,46 +26,45 @@
 #include "y2024/constants/simulated_constants_sender.h"
 #include "y2024/vision/vision_util.h"
 
-DEFINE_string(config, "",
-              "If set, override the log's config file with this one.");
-DEFINE_string(constants_path, "y2024/constants/constants.json",
-              "Path to the constant file");
-DEFINE_string(dump_constraints_to, "/tmp/mapping_constraints.txt",
-              "Write the target constraints to this path");
-DEFINE_string(dump_stats_to, "/tmp/mapping_stats.txt",
-              "Write the mapping stats to this path");
-DEFINE_string(field_name, "crescendo",
-              "Field name, for the output json filename and flatbuffer field");
-DEFINE_string(json_path, "y2024/vision/maps/target_map.json",
-              "Specify path for json with initial pose guesses.");
-DEFINE_double(max_pose_error, 1e-6,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_string(mcap_output_path, "", "Log to output.");
-DEFINE_string(output_dir, "y2024/vision/maps",
-              "Directory to write solved target map to");
-DEFINE_double(pause_on_distance, 2.0,
-              "Pause if two consecutive implied robot positions differ by more "
-              "than this many meters");
-DEFINE_string(orin, "orin1",
-              "Orin name to generate mcap log for; defaults to orin1.");
-DEFINE_uint64(skip_to, 1,
-              "Start at combined image of this number (1 is the first image)");
-DEFINE_bool(solve, true, "Whether to solve for the field's target map.");
-DEFINE_bool(split_field, false,
-            "Whether to break solve into two sides of field");
-DEFINE_int32(team_number, 0,
-             "Required: Use the calibration for a node with this team number");
-DEFINE_uint64(wait_key, 1,
-              "Time in ms to wait between images, if no click (0 to wait "
-              "indefinitely until click).");
+ABSL_FLAG(std::string, config, "",
+          "If set, override the log's config file with this one.");
+ABSL_FLAG(std::string, constants_path, "y2024/constants/constants.json",
+          "Path to the constant file");
+ABSL_FLAG(std::string, dump_constraints_to, "/tmp/mapping_constraints.txt",
+          "Write the target constraints to this path");
+ABSL_FLAG(std::string, dump_stats_to, "/tmp/mapping_stats.txt",
+          "Write the mapping stats to this path");
+ABSL_FLAG(std::string, field_name, "crescendo",
+          "Field name, for the output json filename and flatbuffer field");
+ABSL_FLAG(std::string, json_path, "y2024/vision/maps/target_map.json",
+          "Specify path for json with initial pose guesses.");
+ABSL_FLAG(double, max_pose_error, 1e-6,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(std::string, mcap_output_path, "", "Log to output.");
+ABSL_FLAG(std::string, output_dir, "y2024/vision/maps",
+          "Directory to write solved target map to");
+ABSL_FLAG(double, pause_on_distance, 2.0,
+          "Pause if two consecutive implied robot positions differ by more "
+          "than this many meters");
+ABSL_FLAG(std::string, orin, "orin1",
+          "Orin name to generate mcap log for; defaults to orin1.");
+ABSL_FLAG(uint64_t, skip_to, 1,
+          "Start at combined image of this number (1 is the first image)");
+ABSL_FLAG(bool, solve, true, "Whether to solve for the field's target map.");
+ABSL_FLAG(bool, split_field, false,
+          "Whether to break solve into two sides of field");
+ABSL_FLAG(int32_t, team_number, 0,
+          "Required: Use the calibration for a node with this team number");
+ABSL_FLAG(uint64_t, wait_key, 1,
+          "Time in ms to wait between images, if no click (0 to wait "
+          "indefinitely until click).");
 
-DECLARE_int32(frozen_target_id);
-DECLARE_int32(min_target_id);
-DECLARE_int32(max_target_id);
-DECLARE_bool(visualize_solver);
+ABSL_DECLARE_FLAG(int32_t, frozen_target_id);
+ABSL_DECLARE_FLAG(int32_t, min_target_id);
+ABSL_DECLARE_FLAG(int32_t, max_target_id);
+ABSL_DECLARE_FLAG(bool, visualize_solver);
 
 namespace y2024::vision {
 using frc971::vision::DataAdapter;
@@ -148,8 +148,8 @@
     {9, "blue"}, {10, "blue"}, {11, "red"},  {12, "red"},
     {13, "red"}, {14, "blue"}, {15, "blue"}, {16, "blue"}};
 
-const auto TargetMapperReplay::kFixedTargetMapper =
-    TargetMapper(FLAGS_json_path, ceres::examples::VectorOfConstraints{});
+const auto TargetMapperReplay::kFixedTargetMapper = TargetMapper(
+    absl::GetFlag(FLAGS_json_path), ceres::examples::VectorOfConstraints{});
 
 Eigen::Affine3d TargetMapperReplay::CameraToRobotDetection(
     Eigen::Affine3d H_camera_target, Eigen::Affine3d extrinsics) {
@@ -173,10 +173,11 @@
   reader_->MaybeRemapLoggedChannel<Constants>("/roborio/constants");
   reader_->Register();
 
-  SendSimulationConstants(reader_->event_loop_factory(), FLAGS_team_number,
-                          FLAGS_constants_path);
+  SendSimulationConstants(reader_->event_loop_factory(),
+                          absl::GetFlag(FLAGS_team_number),
+                          absl::GetFlag(FLAGS_constants_path));
 
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     vis_robot_.ClearImage();
     // Set focal length to zoomed in, to view extrinsics
     const double kFocalLength = 1500.0;
@@ -197,7 +198,7 @@
         mapping_event_loops_[mapping_event_loops_.size() - 1].get(),
         &constants_fetcher, camera_node.camera_number);
 
-    if (FLAGS_visualize_solver) {
+    if (absl::GetFlag(FLAGS_visualize_solver)) {
       // Show the extrinsics calibration to start, for reference to confirm
       const auto *calibration = FindCameraCalibration(
           constants_fetcher.constants(),
@@ -214,7 +215,7 @@
     }
   }
 
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     cv::imshow("Extrinsics", vis_robot_.image_);
     cv::waitKey(0);
     vis_robot_.ClearImage();
@@ -242,21 +243,22 @@
   for (const auto *target_pose_fbs : *map.target_poses()) {
     // Skip detections with invalid ids
     if (static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) <
-            FLAGS_min_target_id ||
+            absl::GetFlag(FLAGS_min_target_id) ||
         static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) >
-            FLAGS_max_target_id) {
+            absl::GetFlag(FLAGS_max_target_id)) {
       VLOG(1) << "Skipping tag with invalid id of " << target_pose_fbs->id();
       continue;
     }
 
     // Skip detections with high pose errors
-    if (target_pose_fbs->pose_error() > FLAGS_max_pose_error) {
+    if (target_pose_fbs->pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
       VLOG(1) << "Skipping tag " << target_pose_fbs->id()
               << " due to pose error of " << target_pose_fbs->pose_error();
       continue;
     }
     // Skip detections with high pose error ratios
-    if (target_pose_fbs->pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+    if (target_pose_fbs->pose_error_ratio() >
+        absl::GetFlag(FLAGS_max_pose_error_ratio)) {
       VLOG(1) << "Skipping tag " << target_pose_fbs->id()
               << " due to pose error ratio of "
               << target_pose_fbs->pose_error_ratio();
@@ -296,7 +298,7 @@
             .distortion_factor = distortion_factor,
             .id = static_cast<TargetMapper::TargetId>(target_pose.id)});
 
-    if (FLAGS_visualize_solver) {
+    if (absl::GetFlag(FLAGS_visualize_solver)) {
       // If we've already drawn this camera_name in the current image,
       // display the image before clearing and adding the new poses
       if (drawn_cameras_.count(camera_name) != 0) {
@@ -306,20 +308,21 @@
                     cv::Point(600, 10), cv::FONT_HERSHEY_PLAIN, 1.0,
                     cv::Scalar(255, 255, 255));
 
-        if (display_count_ >= FLAGS_skip_to) {
+        if (display_count_ >= absl::GetFlag(FLAGS_skip_to)) {
           VLOG(1) << "Showing image for camera " << camera_name
                   << " since we've drawn it already";
           cv::imshow("View", vis_robot_.image_);
           // Pause if delta_T is too large, but only after first image (to make
           // sure the delta's are correct)
-          if (max_delta_T_world_robot_ > FLAGS_pause_on_distance &&
+          if (max_delta_T_world_robot_ >
+                  absl::GetFlag(FLAGS_pause_on_distance) &&
               display_count_ > 1) {
             LOG(INFO) << "Pausing since the delta between robot estimates is "
                       << max_delta_T_world_robot_ << " which is > threshold of "
-                      << FLAGS_pause_on_distance;
+                      << absl::GetFlag(FLAGS_pause_on_distance);
             cv::waitKey(0);
           } else {
-            cv::waitKey(FLAGS_wait_key);
+            cv::waitKey(absl::GetFlag(FLAGS_wait_key));
           }
           max_delta_T_world_robot_ = 0.0;
         } else {
@@ -341,7 +344,8 @@
 
       label << "id " << target_pose_fbs->id()
             << ": err (% of max): " << target_pose_fbs->pose_error() << " ("
-            << (target_pose_fbs->pose_error() / FLAGS_max_pose_error)
+            << (target_pose_fbs->pose_error() /
+                absl::GetFlag(FLAGS_max_pose_error))
             << ") err_ratio: " << target_pose_fbs->pose_error_ratio() << " ";
 
       vis_robot_.DrawRobotOutline(H_world_robot, camera_name,
@@ -363,7 +367,7 @@
       last_H_world_robot_ = H_world_robot;
     }
   }
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     if (drew) {
       // Collect all the labels from a given camera, and add the text
       // TODO: Need to fix this one
@@ -374,7 +378,7 @@
       drawn_cameras_.emplace(camera_name);
     } else if (node_distributed_time - last_draw_time_ >
                    std::chrono::milliseconds(30) &&
-               display_count_ >= FLAGS_skip_to && drew) {
+               display_count_ >= absl::GetFlag(FLAGS_skip_to) && drew) {
       // TODO: Check on 30ms value-- does this make sense?
       double delta_t = (node_distributed_time - last_draw_time_).count() / 1e6;
       VLOG(1) << "Last result was " << delta_t << "ms ago";
@@ -384,7 +388,7 @@
       // Display and clear the image if we haven't draw in a while
       VLOG(1) << "Displaying image due to time lapse";
       cv::imshow("View", vis_robot_.image_);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
       max_delta_T_world_robot_ = 0.0;
       drawn_cameras_.clear();
     }
@@ -422,11 +426,11 @@
 }
 
 void TargetMapperReplay::MaybeSolve() {
-  if (FLAGS_solve) {
+  if (absl::GetFlag(FLAGS_solve)) {
     auto target_constraints =
         DataAdapter::MatchTargetDetections(timestamped_target_detections_);
 
-    if (FLAGS_split_field) {
+    if (absl::GetFlag(FLAGS_split_field)) {
       // Remove constraints between the two sides of the field - these are
       // basically garbage because of how far the camera is. We will use seeding
       // below to connect the two sides
@@ -443,14 +447,15 @@
 
     LOG(INFO) << "Solving for locations of tags with "
               << target_constraints.size() << " constraints";
-    TargetMapper mapper(FLAGS_json_path, target_constraints);
-    mapper.Solve(FLAGS_field_name, FLAGS_output_dir);
+    TargetMapper mapper(absl::GetFlag(FLAGS_json_path), target_constraints);
+    mapper.Solve(absl::GetFlag(FLAGS_field_name),
+                 absl::GetFlag(FLAGS_output_dir));
 
-    if (!FLAGS_dump_constraints_to.empty()) {
-      mapper.DumpConstraints(FLAGS_dump_constraints_to);
+    if (!absl::GetFlag(FLAGS_dump_constraints_to).empty()) {
+      mapper.DumpConstraints(absl::GetFlag(FLAGS_dump_constraints_to));
     }
-    if (!FLAGS_dump_stats_to.empty()) {
-      mapper.DumpStats(FLAGS_dump_stats_to);
+    if (!absl::GetFlag(FLAGS_dump_stats_to).empty()) {
+      mapper.DumpStats(absl::GetFlag(FLAGS_dump_stats_to));
     }
     mapper.PrintDiffs();
   }
@@ -460,9 +465,10 @@
   std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections;
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config =
-      (FLAGS_config.empty()
+      (absl::GetFlag(FLAGS_config).empty()
            ? std::nullopt
-           : std::make_optional(aos::configuration::ReadConfig(FLAGS_config)));
+           : std::make_optional(
+                 aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config))));
 
   // Open logfiles
   aos::logger::LogReader reader(
diff --git a/y2024/vision/viewer.cc b/y2024/vision/viewer.cc
index d5ada14..c72c08e 100644
--- a/y2024/vision/viewer.cc
+++ b/y2024/vision/viewer.cc
@@ -12,12 +12,13 @@
 #include "frc971/vision/vision_util_lib.h"
 #include "y2024/vision/vision_util.h"
 
-DEFINE_string(capture, "",
-              "If set, capture a single image and save it to this filename.");
-DEFINE_string(channel, "/camera", "Channel name for the image.");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_int32(rate, 100, "Time in milliseconds to wait between images");
-DEFINE_double(scale, 1.0, "Scale factor for images being displayed");
+ABSL_FLAG(std::string, capture, "",
+          "If set, capture a single image and save it to this filename.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(int32_t, rate, 100, "Time in milliseconds to wait between images");
+ABSL_FLAG(double, scale, 1.0, "Scale factor for images being displayed");
 
 namespace y2024::vision {
 namespace {
@@ -42,12 +43,12 @@
   cv::Mat bgr_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
   cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
 
-  if (!FLAGS_capture.empty()) {
-    if (absl::EndsWith(FLAGS_capture, ".bfbs")) {
-      aos::WriteFlatbufferToFile(FLAGS_capture,
+  if (!absl::GetFlag(FLAGS_capture).empty()) {
+    if (absl::EndsWith(absl::GetFlag(FLAGS_capture), ".bfbs")) {
+      aos::WriteFlatbufferToFile(absl::GetFlag(FLAGS_capture),
                                  image_fetcher->CopyFlatBuffer());
     } else {
-      cv::imwrite(FLAGS_capture, bgr_image);
+      cv::imwrite(absl::GetFlag(FLAGS_capture), bgr_image);
     }
 
     return false;
@@ -55,9 +56,9 @@
 
   cv::Mat undistorted_image;
   cv::undistort(bgr_image, undistorted_image, intrinsics, dist_coeffs);
-  if (FLAGS_scale != 1.0) {
-    cv::resize(undistorted_image, undistorted_image, cv::Size(), FLAGS_scale,
-               FLAGS_scale);
+  if (absl::GetFlag(FLAGS_scale) != 1.0) {
+    cv::resize(undistorted_image, undistorted_image, cv::Size(),
+               absl::GetFlag(FLAGS_scale), absl::GetFlag(FLAGS_scale));
   }
   cv::imshow("Display", undistorted_image);
 
@@ -77,7 +78,7 @@
 
 void ViewerMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<y2024::Constants>(&config.message());
 
@@ -85,8 +86,8 @@
 
   frc971::constants::ConstantsFetcher<y2024::Constants> constants_fetcher(
       &event_loop);
-  CHECK(FLAGS_channel.length() == 8);
-  int camera_id = std::stoi(FLAGS_channel.substr(7, 1));
+  CHECK(absl::GetFlag(FLAGS_channel).length() == 8);
+  int camera_id = std::stoi(absl::GetFlag(FLAGS_channel).substr(7, 1));
   const auto *calibration_data = FindCameraCalibration(
       constants_fetcher.constants(), event_loop.node()->name()->string_view(),
       camera_id);
@@ -95,7 +96,7 @@
       frc971::vision::CameraDistCoeffs(calibration_data);
 
   aos::Fetcher<CameraImage> image_fetcher =
-      event_loop.MakeFetcher<CameraImage>(FLAGS_channel);
+      event_loop.MakeFetcher<CameraImage>(absl::GetFlag(FLAGS_channel));
 
   // Run the display loop
   event_loop.AddPhasedLoop(
@@ -105,7 +106,7 @@
           event_loop.Exit();
         };
       },
-      ::std::chrono::milliseconds(FLAGS_rate));
+      ::std::chrono::milliseconds(absl::GetFlag(FLAGS_rate)));
 
   event_loop.Run();
 
diff --git a/y2024/vision/vision_util.cc b/y2024/vision/vision_util.cc
index becb1cf..034ecdb 100644
--- a/y2024/vision/vision_util.cc
+++ b/y2024/vision/vision_util.cc
@@ -1,6 +1,7 @@
 #include "y2024/vision/vision_util.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace y2024::vision {
 
diff --git a/y2024/wpilib_interface.cc b/y2024/wpilib_interface.cc
index c8328da..aaacdd1 100644
--- a/y2024/wpilib_interface.cc
+++ b/y2024/wpilib_interface.cc
@@ -10,6 +10,8 @@
 #include <mutex>
 #include <thread>
 
+#include "absl/flags/flag.h"
+
 #include "frc971/wpilib/ahal/AnalogInput.h"
 #include "frc971/wpilib/ahal/DriverStation.h"
 #include "frc971/wpilib/ahal/Encoder.h"
@@ -59,9 +61,9 @@
 #include "y2024/control_loops/superstructure/superstructure_position_generated.h"
 #include "y2024/control_loops/superstructure/superstructure_position_static.h"
 
-DEFINE_bool(ctre_diag_server, false,
-            "If true, enable the diagnostics server for interacting with "
-            "devices on the CAN bus using Phoenix Tuner");
+ABSL_FLAG(bool, ctre_diag_server, false,
+          "If true, enable the diagnostics server for interacting with "
+          "devices on the CAN bus using Phoenix Tuner");
 
 using ::aos::monotonic_clock;
 using ::frc971::CANConfiguration;
@@ -450,7 +452,7 @@
     if (team_number == 9971) {
       std::vector<ctre::phoenix6::BaseStatusSignal *> signal_registry;
 
-      if (!FLAGS_ctre_diag_server) {
+      if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
         c_Phoenix_Diagnostics_SetSecondsToStart(-1);
         c_Phoenix_Diagnostics_Dispose();
       }
@@ -542,7 +544,7 @@
     }
     // Thread 4.
     // Set up CAN.
-    if (!FLAGS_ctre_diag_server) {
+    if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
       c_Phoenix_Diagnostics_SetSecondsToStart(-1);
       c_Phoenix_Diagnostics_Dispose();
     }
diff --git a/y2024_defense/BUILD b/y2024_defense/BUILD
index 8f888a5..c639d70 100644
--- a/y2024_defense/BUILD
+++ b/y2024_defense/BUILD
@@ -145,8 +145,9 @@
         "//frc971/zeroing:absolute_encoder",
         "//frc971/zeroing:pot_and_absolute_encoder",
         "//y2024_defense/control_loops/drivetrain:polydrivetrain_plants",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024_defense/constants.cc b/y2024_defense/constants.cc
index 31b3ae3..00f74b9 100644
--- a/y2024_defense/constants.cc
+++ b/y2024_defense/constants.cc
@@ -8,7 +8,8 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
diff --git a/y2024_defense/rockpi/imu_main.cc b/y2024_defense/rockpi/imu_main.cc
index 8ab51fe..4f85551 100644
--- a/y2024_defense/rockpi/imu_main.cc
+++ b/y2024_defense/rockpi/imu_main.cc
@@ -1,16 +1,19 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "aos/realtime.h"
 #include "frc971/imu_reader/imu.h"
 #include "y2024_defense/constants.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 int main(int argc, char *argv[]) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
   frc971::imu::Imu imu(
diff --git a/y2024_defense/wpilib_interface.cc b/y2024_defense/wpilib_interface.cc
index 175f238..03ca275 100644
--- a/y2024_defense/wpilib_interface.cc
+++ b/y2024_defense/wpilib_interface.cc
@@ -11,6 +11,7 @@
 #include <mutex>
 #include <thread>
 
+#include "absl/flags/flag.h"
 #include "ctre/phoenix/CANifier.h"
 
 #include "frc971/wpilib/ahal/AnalogInput.h"
@@ -61,9 +62,9 @@
 #include "frc971/wpilib/wpilib_robot_base.h"
 #include "y2024_defense/constants.h"
 
-DEFINE_bool(ctre_diag_server, false,
-            "If true, enable the diagnostics server for interacting with "
-            "devices on the CAN bus using Phoenix Tuner");
+ABSL_FLAG(bool, ctre_diag_server, false,
+          "If true, enable the diagnostics server for interacting with "
+          "devices on the CAN bus using Phoenix Tuner");
 
 using ::aos::monotonic_clock;
 using ::frc971::CANConfiguration;
@@ -292,7 +293,7 @@
         constants::Values::kDrivetrainSupplyCurrentLimit());
 
     // Setting up CAN.
-    if (!FLAGS_ctre_diag_server) {
+    if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
       c_Phoenix_Diagnostics_SetSecondsToStart(-1);
       c_Phoenix_Diagnostics_Dispose();
     }
diff --git a/y2024_swerve/BUILD b/y2024_swerve/BUILD
index cbdb79b..acc300d 100644
--- a/y2024_swerve/BUILD
+++ b/y2024_swerve/BUILD
@@ -103,8 +103,9 @@
         "//aos/network:team_number",
         "//frc971:constants",
         "//y2024_swerve/constants:constants_fbs",
-        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
@@ -114,7 +115,7 @@
     deps = [
         ":swerve_publisher_lib",
         "//aos/events:shm_event_loop",
-        "@com_github_gflags_gflags//:gflags",
+        "@com_google_absl//absl/flags:flag",
     ],
 )
 
@@ -126,7 +127,8 @@
         "//aos:init",
         "//aos/events:event_loop",
         "//frc971/control_loops/swerve:swerve_drivetrain_output_fbs",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024_swerve/constants.cc b/y2024_swerve/constants.cc
index 4f938a3..676c6b7 100644
--- a/y2024_swerve/constants.cc
+++ b/y2024_swerve/constants.cc
@@ -2,7 +2,8 @@
 
 #include <cstdint>
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/network/team_number.h"
 
diff --git a/y2024_swerve/constants/BUILD b/y2024_swerve/constants/BUILD
index 6de0fb0..416b10c 100644
--- a/y2024_swerve/constants/BUILD
+++ b/y2024_swerve/constants/BUILD
@@ -90,7 +90,8 @@
         ":constants_list_fbs",
         "//aos:init",
         "//aos:json_to_flatbuffer",
-        "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024_swerve/constants/constants_formatter.cc b/y2024_swerve/constants/constants_formatter.cc
index 2ebb9b5..afeb12d 100644
--- a/y2024_swerve/constants/constants_formatter.cc
+++ b/y2024_swerve/constants/constants_formatter.cc
@@ -1,4 +1,5 @@
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/flatbuffers.h"
 #include "aos/init.h"
diff --git a/y2024_swerve/constants/constants_sender.cc b/y2024_swerve/constants/constants_sender.cc
index c624572..74f1020 100644
--- a/y2024_swerve/constants/constants_sender.cc
+++ b/y2024_swerve/constants/constants_sender.cc
@@ -1,5 +1,6 @@
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/configuration.h"
 #include "aos/events/shm_event_loop.h"
@@ -9,17 +10,18 @@
 #include "y2024_swerve/constants/constants_generated.h"
 #include "y2024_swerve/constants/constants_list_generated.h"
 
-DEFINE_string(config, "aos_config.json", "Path to the AOS config.");
-DEFINE_string(constants_path, "constants.json", "Path to the constant file");
+ABSL_FLAG(std::string, config, "aos_config.json", "Path to the AOS config.");
+ABSL_FLAG(std::string, constants_path, "constants.json",
+          "Path to the constant file");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
   aos::ShmEventLoop event_loop(&config.message());
   frc971::constants::ConstantSender<y2024_swerve::Constants,
                                     y2024_swerve::ConstantsList>
-      constants_sender(&event_loop, FLAGS_constants_path);
+      constants_sender(&event_loop, absl::GetFlag(FLAGS_constants_path));
   // Don't need to call Run().
   return 0;
 }
diff --git a/y2024_swerve/swerve_publisher_lib.h b/y2024_swerve/swerve_publisher_lib.h
index e577455..e490738 100644
--- a/y2024_swerve/swerve_publisher_lib.h
+++ b/y2024_swerve/swerve_publisher_lib.h
@@ -1,8 +1,9 @@
 #ifndef Y2024_SWERVE_SWERVE_PUBLISHER_H_
 #define Y2024_SWERVE_SWERVE_PUBLISHER_H_
 
-#include "gflags/gflags.h"
-#include "glog/logging.h"
+#include "absl/flags/flag.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 #include "aos/events/event_loop.h"
 #include "aos/flatbuffer_merge.h"
diff --git a/y2024_swerve/swerve_publisher_main.cc b/y2024_swerve/swerve_publisher_main.cc
index 5409da3..da7a99f 100644
--- a/y2024_swerve/swerve_publisher_main.cc
+++ b/y2024_swerve/swerve_publisher_main.cc
@@ -1,24 +1,27 @@
+#include "absl/flags/flag.h"
+
 #include "aos/events/shm_event_loop.h"
 #include "y2024_swerve/swerve_publisher_lib.h"
 
-DEFINE_double(duration, 100.0, "Length of time in Ms to apply current for");
-DEFINE_string(drivetrain_position, "swerve_drivetrain_output.json",
-              "The path to the json drivetrain position to apply");
-DEFINE_string(config, "aos_config.json", "The path to aos_config.json");
+ABSL_FLAG(double, duration, 100.0, "Length of time in Ms to apply current for");
+ABSL_FLAG(std::string, drivetrain_position, "swerve_drivetrain_output.json",
+          "The path to the json drivetrain position to apply");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "The path to aos_config.json");
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
 
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   aos::ShmEventLoop event_loop(&config.message());
 
   std::unique_ptr<aos::ExitHandle> exit_handle = event_loop.MakeExitHandle();
 
-  y2024_swerve::SwervePublisher publisher(&event_loop, exit_handle.get(),
-                                          FLAGS_drivetrain_position,
-                                          FLAGS_duration);
+  y2024_swerve::SwervePublisher publisher(
+      &event_loop, exit_handle.get(), absl::GetFlag(FLAGS_drivetrain_position),
+      absl::GetFlag(FLAGS_duration));
 
   event_loop.Run();
 }
diff --git a/y2024_swerve/vision/BUILD b/y2024_swerve/vision/BUILD
index 7bbfef9..6342b07 100644
--- a/y2024_swerve/vision/BUILD
+++ b/y2024_swerve/vision/BUILD
@@ -54,9 +54,10 @@
         "//third_party:cudart",
         "//third_party/apriltag",
         "//y2024_swerve/constants:constants_fbs",
-        "@com_github_gflags_gflags//:gflags",
-        "@com_github_google_glog//:glog",
         "@com_github_nvidia_cccl//:cccl",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:check",
     ],
 )
 
diff --git a/y2024_swerve/vision/apriltag_detector.cc b/y2024_swerve/vision/apriltag_detector.cc
index 4d4025e..2032e2e 100644
--- a/y2024_swerve/vision/apriltag_detector.cc
+++ b/y2024_swerve/vision/apriltag_detector.cc
@@ -6,12 +6,13 @@
 #include "y2024_swerve/constants/constants_generated.h"
 #include "y2024_swerve/vision/vision_util.h"
 
-DEFINE_string(channel, "/camera", "Channel name");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
 
 void GpuApriltagDetector() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<y2024_swerve::Constants>(
       &config.message());
@@ -21,15 +22,15 @@
   const frc971::constants::ConstantsFetcher<y2024_swerve::Constants>
       calibration_data(&event_loop);
 
-  CHECK(FLAGS_channel.length() == 8);
-  int camera_id = std::stoi(FLAGS_channel.substr(7, 1));
+  CHECK(absl::GetFlag(FLAGS_channel).length() == 8);
+  int camera_id = std::stoi(absl::GetFlag(FLAGS_channel).substr(7, 1));
   const frc971::vision::calibration::CameraCalibration *calibration =
       y2024_swerve::vision::FindCameraCalibration(
           calibration_data.constants(),
           event_loop.node()->name()->string_view(), camera_id);
 
-  frc971::apriltag::ApriltagDetector detector(&event_loop, FLAGS_channel,
-                                              calibration);
+  frc971::apriltag::ApriltagDetector detector(
+      &event_loop, absl::GetFlag(FLAGS_channel), calibration);
 
   // TODO(austin): Figure out our core pinning strategy.
   // event_loop.SetRuntimeAffinity(aos::MakeCpusetFromCpus({5}));
diff --git a/y2024_swerve/vision/target_mapping.cc b/y2024_swerve/vision/target_mapping.cc
index c540654..b8b1f62 100644
--- a/y2024_swerve/vision/target_mapping.cc
+++ b/y2024_swerve/vision/target_mapping.cc
@@ -1,6 +1,7 @@
 #include <string>
 
 #include "Eigen/Dense"
+#include "absl/flags/flag.h"
 #include "opencv2/aruco.hpp"
 #include "opencv2/calib3d.hpp"
 #include "opencv2/core/eigen.hpp"
@@ -25,46 +26,45 @@
 #include "y2024_swerve/constants/simulated_constants_sender.h"
 #include "y2024_swerve/vision/vision_util.h"
 
-DEFINE_string(config, "",
-              "If set, override the log's config file with this one.");
-DEFINE_string(constants_path, "y2024_swerve/constants/constants.json",
-              "Path to the constant file");
-DEFINE_string(dump_constraints_to, "/tmp/mapping_constraints.txt",
-              "Write the target constraints to this path");
-DEFINE_string(dump_stats_to, "/tmp/mapping_stats.txt",
-              "Write the mapping stats to this path");
-DEFINE_string(field_name, "crescendo",
-              "Field name, for the output json filename and flatbuffer field");
-DEFINE_string(json_path, "y2024_swerve/vision/maps/target_map.json",
-              "Specify path for json with initial pose guesses.");
-DEFINE_double(max_pose_error, 1e-6,
-              "Throw out target poses with a higher pose error than this");
-DEFINE_double(
-    max_pose_error_ratio, 0.4,
-    "Throw out target poses with a higher pose error ratio than this");
-DEFINE_string(mcap_output_path, "", "Log to output.");
-DEFINE_string(output_dir, "y2024_swerve/vision/maps",
-              "Directory to write solved target map to");
-DEFINE_double(pause_on_distance, 2.0,
-              "Pause if two consecutive implied robot positions differ by more "
-              "than this many meters");
-DEFINE_string(orin, "orin1",
-              "Orin name to generate mcap log for; defaults to orin1.");
-DEFINE_uint64(skip_to, 1,
-              "Start at combined image of this number (1 is the first image)");
-DEFINE_bool(solve, true, "Whether to solve for the field's target map.");
-DEFINE_bool(split_field, false,
-            "Whether to break solve into two sides of field");
-DEFINE_int32(team_number, 0,
-             "Required: Use the calibration for a node with this team number");
-DEFINE_uint64(wait_key, 1,
-              "Time in ms to wait between images, if no click (0 to wait "
-              "indefinitely until click).");
+ABSL_FLAG(std::string, config, "",
+          "If set, override the log's config file with this one.");
+ABSL_FLAG(std::string, constants_path, "y2024_swerve/constants/constants.json",
+          "Path to the constant file");
+ABSL_FLAG(std::string, dump_constraints_to, "/tmp/mapping_constraints.txt",
+          "Write the target constraints to this path");
+ABSL_FLAG(std::string, dump_stats_to, "/tmp/mapping_stats.txt",
+          "Write the mapping stats to this path");
+ABSL_FLAG(std::string, field_name, "crescendo",
+          "Field name, for the output json filename and flatbuffer field");
+ABSL_FLAG(std::string, json_path, "y2024_swerve/vision/maps/target_map.json",
+          "Specify path for json with initial pose guesses.");
+ABSL_FLAG(double, max_pose_error, 1e-6,
+          "Throw out target poses with a higher pose error than this");
+ABSL_FLAG(double, max_pose_error_ratio, 0.4,
+          "Throw out target poses with a higher pose error ratio than this");
+ABSL_FLAG(std::string, mcap_output_path, "", "Log to output.");
+ABSL_FLAG(std::string, output_dir, "y2024_swerve/vision/maps",
+          "Directory to write solved target map to");
+ABSL_FLAG(double, pause_on_distance, 2.0,
+          "Pause if two consecutive implied robot positions differ by more "
+          "than this many meters");
+ABSL_FLAG(std::string, orin, "orin1",
+          "Orin name to generate mcap log for; defaults to orin1.");
+ABSL_FLAG(uint64_t, skip_to, 1,
+          "Start at combined image of this number (1 is the first image)");
+ABSL_FLAG(bool, solve, true, "Whether to solve for the field's target map.");
+ABSL_FLAG(bool, split_field, false,
+          "Whether to break solve into two sides of field");
+ABSL_FLAG(int32_t, team_number, 0,
+          "Required: Use the calibration for a node with this team number");
+ABSL_FLAG(uint64_t, wait_key, 1,
+          "Time in ms to wait between images, if no click (0 to wait "
+          "indefinitely until click).");
 
-DECLARE_int32(frozen_target_id);
-DECLARE_int32(min_target_id);
-DECLARE_int32(max_target_id);
-DECLARE_bool(visualize_solver);
+ABSL_DECLARE_FLAG(int32_t, frozen_target_id);
+ABSL_DECLARE_FLAG(int32_t, min_target_id);
+ABSL_DECLARE_FLAG(int32_t, max_target_id);
+ABSL_DECLARE_FLAG(bool, visualize_solver);
 
 namespace y2024_swerve::vision {
 using frc971::vision::DataAdapter;
@@ -149,8 +149,8 @@
     {9, "blue"}, {10, "blue"}, {11, "red"},  {12, "red"},
     {13, "red"}, {14, "blue"}, {15, "blue"}, {16, "blue"}};
 
-const auto TargetMapperReplay::kFixedTargetMapper =
-    TargetMapper(FLAGS_json_path, ceres::examples::VectorOfConstraints{});
+const auto TargetMapperReplay::kFixedTargetMapper = TargetMapper(
+    absl::GetFlag(FLAGS_json_path), ceres::examples::VectorOfConstraints{});
 
 Eigen::Affine3d TargetMapperReplay::CameraToRobotDetection(
     Eigen::Affine3d H_camera_target, Eigen::Affine3d extrinsics) {
@@ -174,10 +174,11 @@
   reader_->MaybeRemapLoggedChannel<Constants>("/roborio/constants");
   reader_->Register();
 
-  SendSimulationConstants(reader_->event_loop_factory(), FLAGS_team_number,
-                          FLAGS_constants_path);
+  SendSimulationConstants(reader_->event_loop_factory(),
+                          absl::GetFlag(FLAGS_team_number),
+                          absl::GetFlag(FLAGS_constants_path));
 
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     vis_robot_.ClearImage();
     // Set focal length to zoomed in, to view extrinsics
     const double kFocalLength = 1500.0;
@@ -199,7 +200,7 @@
         mapping_event_loops_[mapping_event_loops_.size() - 1].get(),
         &constants_fetcher, camera_node.camera_number);
 
-    if (FLAGS_visualize_solver) {
+    if (absl::GetFlag(FLAGS_visualize_solver)) {
       // Show the extrinsics calibration to start, for reference to confirm
       const auto *calibration = FindCameraCalibration(
           constants_fetcher.constants(),
@@ -216,7 +217,7 @@
     }
   }
 
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     cv::imshow("Extrinsics", vis_robot_.image_);
     cv::waitKey(0);
     vis_robot_.ClearImage();
@@ -244,21 +245,22 @@
   for (const auto *target_pose_fbs : *map.target_poses()) {
     // Skip detections with invalid ids
     if (static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) <
-            FLAGS_min_target_id ||
+            absl::GetFlag(FLAGS_min_target_id) ||
         static_cast<TargetMapper::TargetId>(target_pose_fbs->id()) >
-            FLAGS_max_target_id) {
+            absl::GetFlag(FLAGS_max_target_id)) {
       VLOG(1) << "Skipping tag with invalid id of " << target_pose_fbs->id();
       continue;
     }
 
     // Skip detections with high pose errors
-    if (target_pose_fbs->pose_error() > FLAGS_max_pose_error) {
+    if (target_pose_fbs->pose_error() > absl::GetFlag(FLAGS_max_pose_error)) {
       VLOG(1) << "Skipping tag " << target_pose_fbs->id()
               << " due to pose error of " << target_pose_fbs->pose_error();
       continue;
     }
     // Skip detections with high pose error ratios
-    if (target_pose_fbs->pose_error_ratio() > FLAGS_max_pose_error_ratio) {
+    if (target_pose_fbs->pose_error_ratio() >
+        absl::GetFlag(FLAGS_max_pose_error_ratio)) {
       VLOG(1) << "Skipping tag " << target_pose_fbs->id()
               << " due to pose error ratio of "
               << target_pose_fbs->pose_error_ratio();
@@ -298,7 +300,7 @@
             .distortion_factor = distortion_factor,
             .id = static_cast<TargetMapper::TargetId>(target_pose.id)});
 
-    if (FLAGS_visualize_solver) {
+    if (absl::GetFlag(FLAGS_visualize_solver)) {
       // If we've already drawn this camera_name in the current image,
       // display the image before clearing and adding the new poses
       if (drawn_cameras_.count(camera_name) != 0) {
@@ -308,20 +310,21 @@
                     cv::Point(600, 10), cv::FONT_HERSHEY_PLAIN, 1.0,
                     cv::Scalar(255, 255, 255));
 
-        if (display_count_ >= FLAGS_skip_to) {
+        if (display_count_ >= absl::GetFlag(FLAGS_skip_to)) {
           VLOG(1) << "Showing image for camera " << camera_name
                   << " since we've drawn it already";
           cv::imshow("View", vis_robot_.image_);
           // Pause if delta_T is too large, but only after first image (to make
           // sure the delta's are correct)
-          if (max_delta_T_world_robot_ > FLAGS_pause_on_distance &&
+          if (max_delta_T_world_robot_ >
+                  absl::GetFlag(FLAGS_pause_on_distance) &&
               display_count_ > 1) {
             LOG(INFO) << "Pausing since the delta between robot estimates is "
                       << max_delta_T_world_robot_ << " which is > threshold of "
-                      << FLAGS_pause_on_distance;
+                      << absl::GetFlag(FLAGS_pause_on_distance);
             cv::waitKey(0);
           } else {
-            cv::waitKey(FLAGS_wait_key);
+            cv::waitKey(absl::GetFlag(FLAGS_wait_key));
           }
           max_delta_T_world_robot_ = 0.0;
         } else {
@@ -343,7 +346,8 @@
 
       label << "id " << target_pose_fbs->id()
             << ": err (% of max): " << target_pose_fbs->pose_error() << " ("
-            << (target_pose_fbs->pose_error() / FLAGS_max_pose_error)
+            << (target_pose_fbs->pose_error() /
+                absl::GetFlag(FLAGS_max_pose_error))
             << ") err_ratio: " << target_pose_fbs->pose_error_ratio() << " ";
 
       vis_robot_.DrawRobotOutline(H_world_robot, camera_name,
@@ -365,7 +369,7 @@
       last_H_world_robot_ = H_world_robot;
     }
   }
-  if (FLAGS_visualize_solver) {
+  if (absl::GetFlag(FLAGS_visualize_solver)) {
     if (drew) {
       // Collect all the labels from a given camera, and add the text
       // TODO: Need to fix this one
@@ -376,7 +380,7 @@
       drawn_cameras_.emplace(camera_name);
     } else if (node_distributed_time - last_draw_time_ >
                    std::chrono::milliseconds(30) &&
-               display_count_ >= FLAGS_skip_to && drew) {
+               display_count_ >= absl::GetFlag(FLAGS_skip_to) && drew) {
       // TODO: Check on 30ms value-- does this make sense?
       double delta_t = (node_distributed_time - last_draw_time_).count() / 1e6;
       VLOG(1) << "Last result was " << delta_t << "ms ago";
@@ -386,7 +390,7 @@
       // Display and clear the image if we haven't draw in a while
       VLOG(1) << "Displaying image due to time lapse";
       cv::imshow("View", vis_robot_.image_);
-      cv::waitKey(FLAGS_wait_key);
+      cv::waitKey(absl::GetFlag(FLAGS_wait_key));
       max_delta_T_world_robot_ = 0.0;
       drawn_cameras_.clear();
     }
@@ -425,11 +429,11 @@
 }
 
 void TargetMapperReplay::MaybeSolve() {
-  if (FLAGS_solve) {
+  if (absl::GetFlag(FLAGS_solve)) {
     auto target_constraints =
         DataAdapter::MatchTargetDetections(timestamped_target_detections_);
 
-    if (FLAGS_split_field) {
+    if (absl::GetFlag(FLAGS_split_field)) {
       // Remove constraints between the two sides of the field - these are
       // basically garbage because of how far the camera is. We will use seeding
       // below to connect the two sides
@@ -446,14 +450,15 @@
 
     LOG(INFO) << "Solving for locations of tags with "
               << target_constraints.size() << " constraints";
-    TargetMapper mapper(FLAGS_json_path, target_constraints);
-    mapper.Solve(FLAGS_field_name, FLAGS_output_dir);
+    TargetMapper mapper(absl::GetFlag(FLAGS_json_path), target_constraints);
+    mapper.Solve(absl::GetFlag(FLAGS_field_name),
+                 absl::GetFlag(FLAGS_output_dir));
 
-    if (!FLAGS_dump_constraints_to.empty()) {
-      mapper.DumpConstraints(FLAGS_dump_constraints_to);
+    if (!absl::GetFlag(FLAGS_dump_constraints_to).empty()) {
+      mapper.DumpConstraints(absl::GetFlag(FLAGS_dump_constraints_to));
     }
-    if (!FLAGS_dump_stats_to.empty()) {
-      mapper.DumpStats(FLAGS_dump_stats_to);
+    if (!absl::GetFlag(FLAGS_dump_stats_to).empty()) {
+      mapper.DumpStats(absl::GetFlag(FLAGS_dump_stats_to));
     }
     mapper.PrintDiffs();
   }
@@ -463,9 +468,10 @@
   std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections;
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config =
-      (FLAGS_config.empty()
+      (absl::GetFlag(FLAGS_config).empty()
            ? std::nullopt
-           : std::make_optional(aos::configuration::ReadConfig(FLAGS_config)));
+           : std::make_optional(
+                 aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config))));
 
   // Open logfiles
   aos::logger::LogReader reader(
diff --git a/y2024_swerve/vision/viewer.cc b/y2024_swerve/vision/viewer.cc
index 143868d..d857cb6 100644
--- a/y2024_swerve/vision/viewer.cc
+++ b/y2024_swerve/vision/viewer.cc
@@ -1,3 +1,4 @@
+#include "absl/flags/flag.h"
 #include "absl/strings/match.h"
 #include "opencv2/calib3d.hpp"
 #include "opencv2/highgui/highgui.hpp"
@@ -12,12 +13,13 @@
 #include "frc971/vision/vision_util_lib.h"
 #include "y2024_swerve/vision/vision_util.h"
 
-DEFINE_string(capture, "",
-              "If set, capture a single image and save it to this filename.");
-DEFINE_string(channel, "/camera", "Channel name for the image.");
-DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_int32(rate, 100, "Time in milliseconds to wait between images");
-DEFINE_double(scale, 1.0, "Scale factor for images being displayed");
+ABSL_FLAG(std::string, capture, "",
+          "If set, capture a single image and save it to this filename.");
+ABSL_FLAG(std::string, channel, "/camera", "Channel name for the image.");
+ABSL_FLAG(std::string, config, "aos_config.json",
+          "Path to the config file to use.");
+ABSL_FLAG(int32_t, rate, 100, "Time in milliseconds to wait between images");
+ABSL_FLAG(double, scale, 1.0, "Scale factor for images being displayed");
 
 namespace y2024_swerve::vision {
 namespace {
@@ -42,12 +44,12 @@
   cv::Mat bgr_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
   cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
 
-  if (!FLAGS_capture.empty()) {
-    if (absl::EndsWith(FLAGS_capture, ".bfbs")) {
-      aos::WriteFlatbufferToFile(FLAGS_capture,
+  if (!absl::GetFlag(FLAGS_capture).empty()) {
+    if (absl::EndsWith(absl::GetFlag(FLAGS_capture), ".bfbs")) {
+      aos::WriteFlatbufferToFile(absl::GetFlag(FLAGS_capture),
                                  image_fetcher->CopyFlatBuffer());
     } else {
-      cv::imwrite(FLAGS_capture, bgr_image);
+      cv::imwrite(absl::GetFlag(FLAGS_capture), bgr_image);
     }
 
     return false;
@@ -55,9 +57,9 @@
 
   cv::Mat undistorted_image;
   cv::undistort(bgr_image, undistorted_image, intrinsics, dist_coeffs);
-  if (FLAGS_scale != 1.0) {
-    cv::resize(undistorted_image, undistorted_image, cv::Size(), FLAGS_scale,
-               FLAGS_scale);
+  if (absl::GetFlag(FLAGS_scale) != 1.0) {
+    cv::resize(undistorted_image, undistorted_image, cv::Size(),
+               absl::GetFlag(FLAGS_scale), absl::GetFlag(FLAGS_scale));
   }
   cv::imshow("Display", undistorted_image);
 
@@ -77,7 +79,7 @@
 
 void ViewerMain() {
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
-      aos::configuration::ReadConfig(FLAGS_config);
+      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
 
   frc971::constants::WaitForConstants<y2024_swerve::Constants>(
       &config.message());
@@ -86,8 +88,8 @@
 
   frc971::constants::ConstantsFetcher<y2024_swerve::Constants>
       constants_fetcher(&event_loop);
-  CHECK(FLAGS_channel.length() == 8);
-  int camera_id = std::stoi(FLAGS_channel.substr(7, 1));
+  CHECK(absl::GetFlag(FLAGS_channel).length() == 8);
+  int camera_id = std::stoi(absl::GetFlag(FLAGS_channel).substr(7, 1));
   const auto *calibration_data = FindCameraCalibration(
       constants_fetcher.constants(), event_loop.node()->name()->string_view(),
       camera_id);
@@ -96,7 +98,7 @@
       frc971::vision::CameraDistCoeffs(calibration_data);
 
   aos::Fetcher<CameraImage> image_fetcher =
-      event_loop.MakeFetcher<CameraImage>(FLAGS_channel);
+      event_loop.MakeFetcher<CameraImage>(absl::GetFlag(FLAGS_channel));
 
   // Run the display loop
   event_loop.AddPhasedLoop(
@@ -106,7 +108,7 @@
           event_loop.Exit();
         };
       },
-      ::std::chrono::milliseconds(FLAGS_rate));
+      ::std::chrono::milliseconds(absl::GetFlag(FLAGS_rate)));
 
   event_loop.Run();
 
diff --git a/y2024_swerve/vision/vision_util.cc b/y2024_swerve/vision/vision_util.cc
index e08bfaa..60ba82a 100644
--- a/y2024_swerve/vision/vision_util.cc
+++ b/y2024_swerve/vision/vision_util.cc
@@ -1,6 +1,7 @@
 #include "y2024_swerve/vision/vision_util.h"
 
-#include "glog/logging.h"
+#include "absl/log/check.h"
+#include "absl/log/log.h"
 
 namespace y2024_swerve::vision {
 
diff --git a/y2024_swerve/wpilib_interface.cc b/y2024_swerve/wpilib_interface.cc
index 579f075..e6863b9 100644
--- a/y2024_swerve/wpilib_interface.cc
+++ b/y2024_swerve/wpilib_interface.cc
@@ -1,3 +1,4 @@
+#include "absl/flags/flag.h"
 #include "ctre/phoenix/cci/Diagnostics_CCI.h"
 #include "ctre/phoenix6/TalonFX.hpp"
 
@@ -13,9 +14,9 @@
 #include "frc971/wpilib/wpilib_robot_base.h"
 #include "y2024_swerve/constants.h"
 
-DEFINE_bool(ctre_diag_server, false,
-            "If true, enable the diagnostics server for interacting with "
-            "devices on the CAN bus using Phoenix Tuner");
+ABSL_FLAG(bool, ctre_diag_server, false,
+          "If true, enable the diagnostics server for interacting with "
+          "devices on the CAN bus using Phoenix Tuner");
 
 using frc971::wpilib::CANSensorReader;
 using frc971::wpilib::TalonFX;
@@ -188,7 +189,7 @@
 
     // Thread 2
     // Setup CAN
-    if (!FLAGS_ctre_diag_server) {
+    if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
       c_Phoenix_Diagnostics_SetSecondsToStart(-1);
       c_Phoenix_Diagnostics_Dispose();
     }