Hook up tcmalloc

Change-Id: I11c8dd2a2bd67f54bdce3ca6eb5bc97d02c9fae9
diff --git a/third_party/gperftools/.gitignore b/third_party/gperftools/.gitignore
index 055a09d..081c50a 100644
--- a/third_party/gperftools/.gitignore
+++ b/third_party/gperftools/.gitignore
@@ -107,7 +107,7 @@
 /src/base/.dirstamp
 /src/config.h
 /src/config.h.in
-/src/gperftools/tcmalloc.h
+#/src/gperftools/tcmalloc.h
 /src/stamp-h1
 /src/stamp-h1
 /src/tests/.deps
diff --git a/third_party/gperftools/BUILD b/third_party/gperftools/BUILD
new file mode 100644
index 0000000..51953b4
--- /dev/null
+++ b/third_party/gperftools/BUILD
@@ -0,0 +1,516 @@
+licenses(['notice'])
+
+load('/tools/build_rules/select', 'cpu_select', 'compiler_select')
+load('/tools/build_rules/empty_main', 'empty_main_if_asan')
+
+common_copts = [
+  # Stuff from their Makefile.
+  '-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',
+
+  # 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',
+
+  # Stuff pulled out of config.h.
+  '-DHAVE_BUILTIN_EXPECT=1',
+  '-DHAVE_DECL_CFREE=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.4\\"',
+  '-DPACKAGE_BUGREPORT=\\"http://frc971.org/contact\\"',
+  '-DPACKAGE_VERSION=\\"2.4\\"',
+] + 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\\"',
+  ],
+  'roborio': [
+    '-DPC_FROM_UCONTEXT=uc_mcontext.arm_pc',
+    '-DPRIdS=\\"d\\"',
+    '-DPRIuS=\\"u\\"',
+    '-DPRIxS=\\"x\\"',
+  ],
+}) + compiler_select({
+  'clang': [
+    '-Wno-unused-const-variable',
+    '-Wno-gnu-alignof-expression',
+    '-Wno-unused-private-field',
+  ],
+  'gcc': [],
+})
+
+cc_library(
+  name = 'tcmalloc',
+  visibility = ['//visibility:public'],
+  hdrs = glob([
+    'src/*.h',
+    'src/base/*.h',
+    'src/gperftools/*.h',
+  ]) + [
+    'src/third_party/valgrind.h',
+  ],
+  srcs = glob(include = [
+    'src/*.cc',
+    'src/*.c',
+    'src/base/*.cc',
+    'src/base/*.c',
+  ], exclude = [
+    '**/*_unittest.cc',
+    '**/*_test.cc',
+    'src/debugallocation.cc',
+  ]),
+  deps = [
+    '//debian:librt',
+    '//third_party/empty_config_h',
+  ],
+  copts = common_copts,
+  nocopts = '-std=gnu\+\+1y',
+)
+
+cc_library(
+  name = 'testutil',
+  srcs = [
+    'src/tests/testutil.cc',
+  ],
+  hdrs = [
+    'src/tests/testutil.h',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+)
+
+cc_test(
+  name = 'low_level_alloc_unittest',
+  srcs = [
+    'src/tests/low_level_alloc_unittest.cc',
+  ],
+  defines = [
+    'NO_TCMALLOC_SAMPLES',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'medium',
+)
+
+cc_test(
+  name = 'atomicops_unittest',
+  srcs = [
+    'src/tests/atomicops_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'stacktrace_unittest',
+  srcs = [
+    'src/tests/stacktrace_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'tcmalloc_unittest',
+  srcs = empty_main_if_asan([
+    'src/tests/tcmalloc_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+    ':testutil',
+  ],
+  copts = common_copts + [
+    '-fno-builtin',
+  ],
+  size = 'small',
+)
+
+cc_test(
+  name = 'tcmalloc_large_unittest',
+  srcs = empty_main_if_asan([
+    'src/tests/tcmalloc_large_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts + [
+    '-fno-builtin',
+  ],
+  size = 'small',
+)
+
+cc_test(
+  name = 'addressmap_unittest',
+  srcs = [
+    'src/tests/addressmap_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'system_alloc_unittest',
+  srcs = empty_main_if_asan([
+    'src/tests/system-alloc_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts + [
+    '-fno-builtin',
+  ],
+  size = 'small',
+)
+
+cc_test(
+  name = 'packed_cache_test',
+  srcs = [
+    'src/tests/packed-cache_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'frag_unittest',
+  srcs = [
+    'src/tests/frag_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'markidle_unittest',
+  srcs = empty_main_if_asan([
+    'src/tests/markidle_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+    ':testutil',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'current_allocated_bytes_test',
+  srcs = [
+    'src/tests/current_allocated_bytes_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'malloc_hook_test',
+  srcs = [
+    'src/tests/malloc_hook_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+    ':testutil',
+  ],
+  copts = common_copts + compiler_select({
+    'gcc': [
+      '-Wno-maybe-uninitialized',
+    ],
+    'clang': [],
+  }),
+  size = 'small',
+)
+
+cc_test(
+  name = 'malloc_extension_test',
+  srcs = empty_main_if_asan([
+    'src/tests/malloc_extension_test.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'malloc_extension_c_test',
+  srcs = empty_main_if_asan([
+    'src/tests/malloc_extension_c_test.c',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'memalign_unittest',
+  srcs = empty_main_if_asan([
+    'src/tests/memalign_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+    ':testutil',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'page_heap_test',
+  srcs = [
+    'src/tests/page_heap_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'pagemap_unittest',
+  srcs = empty_main_if_asan([
+    'src/tests/pagemap_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'realloc_unittest',
+  srcs = [
+    'src/tests/realloc_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'stack_trace_table_test',
+  srcs = [
+    'src/tests/stack_trace_table_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'thread_dealloc_unittest',
+  srcs = [
+    'src/tests/thread_dealloc_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+    ':testutil',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+'''
+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',
+  srcs = empty_main_if_asan([
+    'src/tests/large_heap_fragmentation_unittest.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'raw_printer_test',
+  srcs = [
+    'src/tests/raw_printer_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'getpc_test',
+  srcs = empty_main_if_asan([
+    'src/tests/getpc_test.cc',
+  ]),
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'profiledata_unittest',
+  srcs = [
+    'src/tests/profiledata_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'profile_handler_unittest',
+  srcs = [
+    'src/tests/profile-handler_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  flaky = True,
+  size = 'small',
+)
+
+cc_test(
+  name = 'heap_profiler_unittest',
+  srcs = [
+    'src/tests/heap-profiler_unittest.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts,
+  size = 'small',
+)
+
+cc_test(
+  name = 'sampler_test',
+  srcs = [
+    'src/tests/sampler_test.cc',
+  ],
+  deps = [
+    ':tcmalloc',
+  ],
+  copts = common_copts + [
+    '-Wno-type-limits',
+  ],
+  size = 'small',
+)
diff --git a/third_party/gperftools/src/base/sysinfo.cc b/third_party/gperftools/src/base/sysinfo.cc
index cad751b..8183494 100644
--- a/third_party/gperftools/src/base/sysinfo.cc
+++ b/third_party/gperftools/src/base/sysinfo.cc
@@ -160,7 +160,7 @@
   const char* p = envbuf;
   while (*p != '\0') {    // will happen at the \0\0 that terminates the buffer
     // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
-    const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf));
+    const char* endp = (const char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf));
     if (endp == NULL)            // this entry isn't NUL terminated
       return NULL;
     else if (!memcmp(p, name, namelen) && p[namelen] == '=')    // it's a match
diff --git a/third_party/gperftools/src/base/thread_lister.c b/third_party/gperftools/src/base/thread_lister.c
index ca1b2de..e837c3e 100644
--- a/third_party/gperftools/src/base/thread_lister.c
+++ b/third_party/gperftools/src/base/thread_lister.c
@@ -36,6 +36,9 @@
 #ifdef HAVE_SYS_PRCTL
 # include <sys/prctl.h>
 #endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 #include "base/thread_lister.h"
 #include "base/linuxthreads.h"
 /* Include other thread listers here that define THREADS macro
diff --git a/third_party/gperftools/src/gperftools/tcmalloc.h b/third_party/gperftools/src/gperftools/tcmalloc.h
new file mode 100644
index 0000000..8fc5554
--- /dev/null
+++ b/third_party/gperftools/src/gperftools/tcmalloc.h
@@ -0,0 +1,135 @@
+// -*- 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 HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>   // where glibc defines __THROW
+#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
+
+// Define the version number so folks can check against it
+#define TC_VERSION_MAJOR  2
+#define TC_VERSION_MINOR  4
+#define TC_VERSION_PATCH  ""
+#define TC_VERSION_STRING "gperftools 2.4"
+
+// For struct mallinfo, if it's defined.
+#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_SYS_MALLOC_H)
+# include <sys/malloc.h>
+# elif defined(HAVE_MALLOC_MALLOC_H)
+# include <malloc/malloc.h>
+# endif
+#endif
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef PERFTOOLS_DLL_DECL
+# ifdef _WIN32
+#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
+# else
+#   define PERFTOOLS_DLL_DECL
+# endif
+#endif
+
+#ifdef __cplusplus
+namespace std {
+struct nothrow_t;
+}
+
+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) __THROW;
+
+  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW;
+  PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;
+  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW;
+
+  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
+                                       size_t __size) __THROW;
+  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
+                                           size_t align, size_t size) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) __THROW;
+
+  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW;
+  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW;
+#if 1
+  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW;
+#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) __THROW;
+
+#ifdef __cplusplus
+  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_new(size_t size);
+  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
+                                          const std::nothrow_t&) __THROW;
+  PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;
+  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
+                                            const std::nothrow_t&) __THROW;
+  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
+  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
+                                               const std::nothrow_t&) __THROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
+                                                 const std::nothrow_t&) __THROW;
+}
+#endif
+
+#endif  // #ifndef TCMALLOC_TCMALLOC_H_
diff --git a/tools/build_rules/empty_main.bzl b/tools/build_rules/empty_main.bzl
new file mode 100644
index 0000000..050907c
--- /dev/null
+++ b/tools/build_rules/empty_main.bzl
@@ -0,0 +1,5 @@
+'''Returns a select which is either srcs or an empty main function.'''
+def empty_main_if_asan(srcs):
+  return select({
+    '//conditions:default': srcs,
+  })
diff --git a/tools/cpp/BUILD b/tools/cpp/BUILD
index 3a33e0e..9196d44 100644
--- a/tools/cpp/BUILD
+++ b/tools/cpp/BUILD
@@ -1,21 +1,24 @@
-package(default_visibility = ["//visibility:public"])
+package(default_visibility = ['//visibility:public'])
 
 cc_library(
-    name = "malloc",
+  name = 'malloc',
+  deps = [
+    '//third_party/gperftools:tcmalloc',
+  ],
 )
 
 cc_library(
-    name = "stl",
+  name = 'stl',
 )
 
 filegroup(
-    name = "empty",
-    srcs = [],
+  name = 'empty',
+  srcs = [],
 )
 
 # This is the entry point for --crosstool_top.  Toolchains are found
 # by lopping off the name of --crosstool_top and searching for
-# "cc-compiler-${CPU}" in this BUILD file, where CPU is the target CPU
+# 'cc-compiler-${CPU}' in this BUILD file, where CPU is the target CPU
 # specified in --cpu.
 #
 # This file group should include
@@ -24,57 +27,57 @@
 # including the default_grte_top setting in the CROSSTOOL
 # protobuf.
 filegroup(
-    name = "toolchain",
-    srcs = [
-        ":cc-compiler-armeabi-v7a",
-        ":cc-compiler-local",
-        ":cc-compiler-k8",
-        ":cc-compiler-roborio",
-        '@arm-frc-linux-gnueabi-repo//:compiler_components',
-        ':roborio-compiler-files',
-    ],
+  name = 'toolchain',
+  srcs = [
+    ':cc-compiler-armeabi-v7a',
+    ':cc-compiler-local',
+    ':cc-compiler-k8',
+    ':cc-compiler-roborio',
+    '@arm-frc-linux-gnueabi-repo//:compiler_components',
+    ':roborio-compiler-files',
+  ],
 )
 
 cc_toolchain(
-    name = "cc-compiler-local",
-    all_files = ":empty",
-    compiler_files = ":empty",
-    cpu = "local",
-    dwp_files = ":empty",
-    dynamic_runtime_libs = [":empty"],
-    linker_files = ":empty",
-    objcopy_files = ":empty",
-    static_runtime_libs = [":empty"],
-    strip_files = ":empty",
-    supports_param_files = 1,
+  name = 'cc-compiler-local',
+  all_files = ':empty',
+  compiler_files = ':empty',
+  cpu = 'local',
+  dwp_files = ':empty',
+  dynamic_runtime_libs = [':empty'],
+  linker_files = ':empty',
+  objcopy_files = ':empty',
+  static_runtime_libs = [':empty'],
+  strip_files = ':empty',
+  supports_param_files = 1,
 )
 
 cc_toolchain(
-    name = "cc-compiler-armeabi-v7a",
-    all_files = ":empty",
-    compiler_files = ":empty",
-    cpu = "local",
-    dwp_files = ":empty",
-    dynamic_runtime_libs = [":empty"],
-    linker_files = ":empty",
-    objcopy_files = ":empty",
-    static_runtime_libs = [":empty"],
-    strip_files = ":empty",
-    supports_param_files = 1,
+  name = 'cc-compiler-armeabi-v7a',
+  all_files = ':empty',
+  compiler_files = ':empty',
+  cpu = 'local',
+  dwp_files = ':empty',
+  dynamic_runtime_libs = [':empty'],
+  linker_files = ':empty',
+  objcopy_files = ':empty',
+  static_runtime_libs = [':empty'],
+  strip_files = ':empty',
+  supports_param_files = 1,
 )
 
 cc_toolchain(
-    name = "cc-compiler-k8",
-    all_files = ":empty",
-    compiler_files = ":empty",
-    cpu = "local",
-    dwp_files = ":empty",
-    dynamic_runtime_libs = [":empty"],
-    linker_files = ":empty",
-    objcopy_files = ":empty",
-    static_runtime_libs = [":empty"],
-    strip_files = ":empty",
-    supports_param_files = 1,
+  name = 'cc-compiler-k8',
+  all_files = ':empty',
+  compiler_files = ':empty',
+  cpu = 'local',
+  dwp_files = ':empty',
+  dynamic_runtime_libs = [':empty'],
+  linker_files = ':empty',
+  objcopy_files = ':empty',
+  static_runtime_libs = [':empty'],
+  strip_files = ':empty',
+  supports_param_files = 1,
 )
 
 filegroup(
@@ -104,15 +107,15 @@
 )
 
 cc_toolchain(
-    name = "cc-compiler-roborio",
-    all_files = ":roborio-compiler-files",
-    compiler_files = ':roborio_compiler_files',
-    cpu = "roborio",
-    dwp_files = ':empty',
-    dynamic_runtime_libs = [":empty"],
-    linker_files = ":roborio_linker_files",
-    objcopy_files = '//tools/cpp/arm-frc-linux-gnueabi:objcopy',
-    static_runtime_libs = [":empty"],
-    strip_files = '//tools/cpp/arm-frc-linux-gnueabi:strip',
-    supports_param_files = 1,
+  name = 'cc-compiler-roborio',
+  all_files = ':roborio-compiler-files',
+  compiler_files = ':roborio_compiler_files',
+  cpu = 'roborio',
+  dwp_files = ':empty',
+  dynamic_runtime_libs = [':empty'],
+  linker_files = ':roborio_linker_files',
+  objcopy_files = '//tools/cpp/arm-frc-linux-gnueabi:objcopy',
+  static_runtime_libs = [':empty'],
+  strip_files = '//tools/cpp/arm-frc-linux-gnueabi:strip',
+  supports_param_files = 1,
 )