Bug 1014341 (part 1) - Remove trace-malloc. r=dbaron,glandium.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 07 Jan 2015 16:13:03 -0800
changeset 248556 94bd476efa143f7d07844968a7f9c77f440d0672
parent 248555 8e30ec51f41bfe5c9fc3e1c811699cbf4a1e707d
child 248557 0933c1aef19729d4163d61f8962f11c473a26103
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, glandium
bugs1014341
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1014341 (part 1) - Remove trace-malloc. r=dbaron,glandium.
addon-sdk/source/python-lib/cuddlefish/runner.py
build/automation.py.in
build/automationutils.py
config/config.mk
configure.in
dom/base/nsJSEnvironment.cpp
gfx/thebes/gfxPlatform.cpp
js/src/configure.in
testing/xpcshell/runxpcshelltests.py
toolkit/components/aboutmemory/tests/test_aboutmemory.xul
toolkit/components/aboutmemory/tests/test_memoryReporters.xul
toolkit/toolkit.mozbuild
toolkit/xre/nsAppRunner.cpp
tools/trace-malloc/Makefile.in
tools/trace-malloc/README
tools/trace-malloc/TraceMalloc.pm
tools/trace-malloc/adreader.cpp
tools/trace-malloc/adreader.h
tools/trace-malloc/allocation-stacks.c
tools/trace-malloc/blame.css
tools/trace-malloc/blame.pl
tools/trace-malloc/bloatblame.cpp
tools/trace-malloc/diffbloatdump.pl
tools/trace-malloc/formdata.c
tools/trace-malloc/formdata.h
tools/trace-malloc/getopt.c
tools/trace-malloc/histogram-diff.sh
tools/trace-malloc/histogram-pretty.sh
tools/trace-malloc/histogram.pl
tools/trace-malloc/leak-soup.pl
tools/trace-malloc/leaksoup.cpp
tools/trace-malloc/leakstats.c
tools/trace-malloc/lib/moz.build
tools/trace-malloc/lib/nsDebugHelpWin32.cpp
tools/trace-malloc/lib/nsDebugHelpWin32.h
tools/trace-malloc/lib/nsTraceMalloc.c
tools/trace-malloc/lib/nsTraceMalloc.h
tools/trace-malloc/lib/nsTraceMallocCallbacks.h
tools/trace-malloc/lib/nsTypeInfo.cpp
tools/trace-malloc/lib/nsTypeInfo.h
tools/trace-malloc/lib/nsWinTraceMalloc.cpp
tools/trace-malloc/lib/tm.def
tools/trace-malloc/live-bloat.html
tools/trace-malloc/merge.pl
tools/trace-malloc/moz.build
tools/trace-malloc/rules.txt
tools/trace-malloc/spacecategory.c
tools/trace-malloc/spacetrace.c
tools/trace-malloc/spacetrace.css
tools/trace-malloc/spacetrace.h
tools/trace-malloc/stoptions.h
tools/trace-malloc/tmfrags.c
tools/trace-malloc/tmreader.c
tools/trace-malloc/tmreader.h
tools/trace-malloc/tmstats.c
tools/trace-malloc/types.dat
tools/trace-malloc/uncategorized.pl
xpcom/base/nsTraceRefcnt.cpp
xpcom/base/nscore.h
xpcom/glue/standalone/nsXPCOMGlue.cpp
--- a/addon-sdk/source/python-lib/cuddlefish/runner.py
+++ b/addon-sdk/source/python-lib/cuddlefish/runner.py
@@ -487,17 +487,16 @@ def run_app(harness_root_dir, manifest_r
     maybe_remove_logfile()
 
     env = {}
     env.update(os.environ)
     if no_connections:
       env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1'
     env['MOZ_NO_REMOTE'] = '1'
     env['XPCOM_DEBUG_BREAK'] = 'stack'
-    env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
     env.update(extra_environment)
     if norun:
         cmdargs.append("-no-remote")
 
     # Create the addon XPI so mozrunner will copy it to the profile it creates.
     # We delete it below after getting mozrunner to create the profile.
     from cuddlefish.xpi import build_xpi
     xpi_path = tempfile.mktemp(suffix='cfx-tmp.xpi')
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -499,17 +499,16 @@ class Automation(object):
     # Crash on non-local network connections by default.
     # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
     # enable non-local connections for the purposes of local testing.  Don't
     # override the user's choice here.  See bug 1049688.
     env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
 
     env['GNOME_DISABLE_CRASH_DIALOG'] = '1'
     env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1'
-    env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
 
     # Set WebRTC logging in case it is not set yet
     env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
     env.setdefault('R_LOG_LEVEL', '6')
     env.setdefault('R_LOG_DESTINATION', 'stderr')
     env.setdefault('R_LOG_VERBOSE', '1')
 
     # ASan specific environment stuff
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -325,17 +325,16 @@ def environment(xrePath, env=None, crash
     env[envVar] = os.path.pathsep.join([path for path in envValue if path])
 
   if dmdPath and dmdLibrary and preloadEnvVar:
     env[preloadEnvVar] = os.path.join(dmdPath, dmdLibrary)
 
   # crashreporter
   env['GNOME_DISABLE_CRASH_DIALOG'] = '1'
   env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1'
-  env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
 
   if crashreporter and not debugger:
     env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
     env['MOZ_CRASHREPORTER'] = '1'
   else:
     env['MOZ_CRASHREPORTER_DISABLE'] = '1'
 
   # Crash on non-local network connections by default.
--- a/config/config.mk
+++ b/config/config.mk
@@ -223,27 +223,27 @@ OS_CFLAGS += -UDEBUG -DNDEBUG
 ifdef HAVE_64BIT_BUILD
 OS_LDFLAGS += -DEBUG -OPT:REF,ICF
 else
 OS_LDFLAGS += -DEBUG -OPT:REF
 endif
 endif
 
 #
-# Handle trace-malloc and DMD in optimized builds.
+# Handle DMD in optimized builds.
 # No opt to give sane callstacks.
 #
-ifneq (,$(NS_TRACE_MALLOC)$(MOZ_DMD))
+ifdef MOZ_DMD
 MOZ_OPTIMIZE_FLAGS=-Zi -Od -UDEBUG -DNDEBUG
 ifdef HAVE_64BIT_BUILD
 OS_LDFLAGS = -DEBUG -OPT:REF,ICF
 else
 OS_LDFLAGS = -DEBUG -OPT:REF
 endif
-endif # NS_TRACE_MALLOC || MOZ_DMD
+endif # MOZ_DMD
 
 endif # MOZ_DEBUG
 
 endif # WINNT && !GNU_CC
 
 ifdef MOZ_GLUE_IN_PROGRAM
 DEFINES += -DMOZ_GLUE_IN_PROGRAM
 endif
@@ -416,30 +416,30 @@ endif # FAIL_ON_WARNINGS
 
 ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_)
 #// Currently, unless USE_STATIC_LIBS is defined, the multithreaded
 #// DLL version of the RTL is used...
 #//
 #//------------------------------------------------------------------------
 ifdef USE_STATIC_LIBS
 RTL_FLAGS=-MT          # Statically linked multithreaded RTL
-ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
+ifdef MOZ_DEBUG
 ifndef MOZ_NO_DEBUG_RTL
 RTL_FLAGS=-MTd         # Statically linked multithreaded MSVC4.0 debug RTL
 endif
-endif # MOZ_DEBUG || NS_TRACE_MALLOC
+endif # MOZ_DEBUG
 
 else # !USE_STATIC_LIBS
 
 RTL_FLAGS=-MD          # Dynamically linked, multithreaded RTL
-ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
+ifdef MOZ_DEBUG
 ifndef MOZ_NO_DEBUG_RTL
 RTL_FLAGS=-MDd         # Dynamically linked, multithreaded MSVC4.0 debug RTL
 endif
-endif # MOZ_DEBUG || NS_TRACE_MALLOC
+endif # MOZ_DEBUG
 endif # USE_STATIC_LIBS
 endif # WINNT && !GNU_CC
 
 ifeq ($(OS_ARCH),Darwin)
 # Compiling ObjC requires an Apple compiler anyway, so it's ok to set
 # host CMFLAGS here.
 HOST_CMFLAGS += -fobjc-exceptions
 HOST_CMMFLAGS += -fobjc-exceptions
--- a/configure.in
+++ b/configure.in
@@ -7042,44 +7042,24 @@ if test -n "$MOZ_DUMP_PAINTING"; then
     AC_DEFINE(MOZ_DUMP_PAINTING)
     AC_DEFINE(MOZ_LAYERS_HAVE_LOG)
 fi
 if test -n "$MOZ_DEBUG"; then
     AC_DEFINE(MOZ_DUMP_PAINTING)
 fi
 
 dnl ========================================================
-dnl = Enable trace malloc
-dnl ========================================================
-NS_TRACE_MALLOC=${MOZ_TRACE_MALLOC}
-MOZ_ARG_ENABLE_BOOL(trace-malloc,
-[  --enable-trace-malloc   Enable malloc tracing; also disables DMD and jemalloc],
-    NS_TRACE_MALLOC=1,
-    NS_TRACE_MALLOC= )
-if test "$NS_TRACE_MALLOC"; then
-  # Please, Mr. Linker Man, don't take away our symbol names
-  MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
-  AC_DEFINE(NS_TRACE_MALLOC)
-fi
-AC_SUBST(NS_TRACE_MALLOC)
-
-dnl ========================================================
 dnl = Enable DMD
 dnl ========================================================
 
 MOZ_ARG_ENABLE_BOOL(dmd,
 [  --enable-dmd            Enable DMD; also enables jemalloc and replace-malloc],
     MOZ_DMD=1,
     MOZ_DMD= )
 
-dnl The two options are conflicting. Fails the configure to alert the user.
-if test "$NS_TRACE_MALLOC" -a "$MOZ_DMD"; then
-    AC_MSG_ERROR([--enable-trace-malloc and --enable-dmd are conflicting options])
-fi
-
 if test "$MOZ_DMD"; then
     AC_DEFINE(MOZ_DMD)
 
     if test "${CPU_ARCH}" = "arm"; then
         CFLAGS="$CFLAGS -funwind-tables"
         CXXFLAGS="$CXXFLAGS -funwind-tables"
     fi
 
@@ -7091,20 +7071,16 @@ AC_SUBST(MOZ_DMD)
 dnl ========================================================
 dnl = Enable jemalloc
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(jemalloc,
 [  --enable-jemalloc       Replace memory allocator with jemalloc],
     MOZ_MEMORY=1,
     MOZ_MEMORY=)
 
-if test "$NS_TRACE_MALLOC"; then
-    MOZ_MEMORY=
-fi
-
 case "${OS_TARGET}" in
 Android|WINNT|Darwin)
   MOZ_GLUE_IN_PROGRAM=
   ;;
 *)
   dnl On !Android !Windows !OSX, we only want to link executables against mozglue
   MOZ_GLUE_IN_PROGRAM=1
   ;;
@@ -7117,21 +7093,16 @@ if test -n "$NIGHTLY_BUILD" -a -n "$MOZ_
   # Enable on central for the debugging opportunities it adds.
   MOZ_REPLACE_MALLOC=1
 fi
 MOZ_ARG_ENABLE_BOOL(replace-malloc,
 [  --enable-replace-malloc   Enable ability to dynamically replace the malloc implementation],
     MOZ_REPLACE_MALLOC=1,
     MOZ_REPLACE_MALLOC= )
 
-dnl The two options are conflicting. Fails the configure to alert the user.
-if test "$NS_TRACE_MALLOC" -a "$MOZ_REPLACE_MALLOC"; then
-    AC_MSG_ERROR([--enable-trace-malloc and --enable-replace-malloc are conflicting options])
-fi
-
 if test -n "$MOZ_REPLACE_MALLOC" -a -z "$MOZ_MEMORY"; then
     dnl We don't want to enable jemalloc unconditionally because it may be a
     dnl deliberate choice not to enable it (bug 702250, for instance)
     AC_MSG_ERROR([--enable-replace-malloc requires --enable-jemalloc])
 elif test -n "$MOZ_REPLACE_MALLOC"; then
     AC_DEFINE(MOZ_REPLACE_MALLOC)
     MOZ_NATIVE_JEMALLOC=
 
@@ -7596,19 +7567,19 @@ dnl = Support for demangling undefined s
 dnl ========================================================
 if test -z "$SKIP_LIBRARY_CHECKS"; then
     AC_LANG_SAVE
     AC_LANG_CPLUSPLUS
     AC_CHECK_FUNCS(__cxa_demangle, HAVE_DEMANGLE=1, HAVE_DEMANGLE=)
     AC_LANG_RESTORE
 fi
 
-# Demangle only for debug or trace-malloc or DMD builds
+# Demangle only for debug or DMD builds
 MOZ_DEMANGLE_SYMBOLS=
-if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then
+if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$MOZ_DMD"; then
     MOZ_DEMANGLE_SYMBOLS=1
     AC_DEFINE(MOZ_DEMANGLE_SYMBOLS)
 fi
 AC_SUBST(MOZ_DEMANGLE_SYMBOLS)
 
 dnl ========================================================
 dnl = Support for gcc stack unwinding (from gcc 3.3)
 dnl ========================================================
@@ -8418,17 +8389,17 @@ fi
 
 dnl Build second screen and casting features for external devices if required
 AC_SUBST(MOZ_DEVICES)
 if test -n "$MOZ_DEVICES"; then
   AC_DEFINE(MOZ_DEVICES)
 fi
 
 dnl ========================================================
-if test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then
+if test "$MOZ_DEBUG" -o "$MOZ_DMD"; then
     MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
 fi
 
 dnl ========================================================
 dnl =
 dnl = Maintainer debug option (no --enable equivalent)
 dnl =
 dnl ========================================================
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1082,187 +1082,16 @@ nsJSContext::AddSupportsPrimitiveTojsval
       NS_WARNING("Unknown primitive type used");
       *aArgv = JSVAL_NULL;
       break;
     }
   }
   return NS_OK;
 }
 
-#ifdef NS_TRACE_MALLOC
-
-#include <errno.h>              // XXX assume Linux if NS_TRACE_MALLOC
-#include <fcntl.h>
-#ifdef XP_UNIX
-#include <unistd.h>
-#endif
-#ifdef XP_WIN32
-#include <io.h>
-#endif
-#include "nsTraceMalloc.h"
-
-static bool
-CheckUniversalXPConnectForTraceMalloc(JSContext *cx)
-{
-    if (nsContentUtils::IsCallerChrome())
-        return true;
-    JS_ReportError(cx, "trace-malloc functions require UniversalXPConnect");
-    return false;
-}
-
-static bool
-TraceMallocDisable(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    NS_TraceMallocDisable();
-    args.rval().setUndefined();
-    return true;
-}
-
-static bool
-TraceMallocEnable(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    NS_TraceMallocEnable();
-    args.rval().setUndefined();
-    return true;
-}
-
-static bool
-TraceMallocOpenLogFile(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    int fd;
-    if (argc == 0) {
-        fd = -1;
-    } else {
-        JSString *str = JS::ToString(cx, args[0]);
-        if (!str)
-            return false;
-        JSAutoByteString filename(cx, str);
-        if (!filename)
-            return false;
-        fd = open(filename.ptr(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
-        if (fd < 0) {
-            JS_ReportError(cx, "can't open %s: %s", filename.ptr(), strerror(errno));
-            return false;
-        }
-    }
-    args.rval().setInt32(fd);
-    return true;
-}
-
-static bool
-TraceMallocChangeLogFD(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    int32_t fd, oldfd;
-    if (args.length() == 0) {
-        oldfd = -1;
-    } else {
-        if (!JS::ToInt32(cx, args[0], &fd))
-            return false;
-        oldfd = NS_TraceMallocChangeLogFD(fd);
-        if (oldfd == -2) {
-            JS_ReportOutOfMemory(cx);
-            return false;
-        }
-    }
-    args.rval().setInt32(oldfd);
-    return true;
-}
-
-static bool
-TraceMallocCloseLogFD(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    int32_t fd;
-    if (args.length() == 0) {
-        args.rval().setUndefined();
-        return true;
-    }
-    if (!JS::ToInt32(cx, args[0], &fd))
-        return false;
-    NS_TraceMallocCloseLogFD((int) fd);
-    args.rval().setInt32(fd);
-    return true;
-}
-
-static bool
-TraceMallocLogTimestamp(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    JSString *str = JS::ToString(cx, args.get(0));
-    if (!str)
-        return false;
-    JSAutoByteString caption(cx, str);
-    if (!caption)
-        return false;
-    NS_TraceMallocLogTimestamp(caption.ptr());
-    args.rval().setUndefined();
-    return true;
-}
-
-static bool
-TraceMallocDumpAllocations(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-    if (!CheckUniversalXPConnectForTraceMalloc(cx))
-        return false;
-
-    JSString *str = JS::ToString(cx, args.get(0));
-    if (!str)
-        return false;
-    JSAutoByteString pathname(cx, str);
-    if (!pathname)
-        return false;
-    if (NS_TraceMallocDumpAllocations(pathname.ptr()) < 0) {
-        JS_ReportError(cx, "can't dump to %s: %s", pathname.ptr(), strerror(errno));
-        return false;
-    }
-    args.rval().setUndefined();
-    return true;
-}
-
-static const JSFunctionSpec TraceMallocFunctions[] = {
-    JS_FS("TraceMallocDisable",         TraceMallocDisable,         0, 0),
-    JS_FS("TraceMallocEnable",          TraceMallocEnable,          0, 0),
-    JS_FS("TraceMallocOpenLogFile",     TraceMallocOpenLogFile,     1, 0),
-    JS_FS("TraceMallocChangeLogFD",     TraceMallocChangeLogFD,     1, 0),
-    JS_FS("TraceMallocCloseLogFD",      TraceMallocCloseLogFD,      1, 0),
-    JS_FS("TraceMallocLogTimestamp",    TraceMallocLogTimestamp,    1, 0),
-    JS_FS("TraceMallocDumpAllocations", TraceMallocDumpAllocations, 1, 0),
-    JS_FS_END
-};
-
-#endif /* NS_TRACE_MALLOC */
-
 #ifdef MOZ_JPROF
 
 #include <signal.h>
 
 inline bool
 IsJProfAction(struct sigaction *action)
 {
     return (action->sa_sigaction &&
@@ -1369,23 +1198,16 @@ nsJSContext::InitClasses(JS::Handle<JSOb
   AutoJSAPI jsapi;
   jsapi.Init();
   JSContext* cx = jsapi.cx();
   JSAutoCompartment ac(cx, aGlobalObj);
 
   // Attempt to initialize profiling functions
   ::JS_DefineProfilingFunctions(cx, aGlobalObj);
 
-#ifdef NS_TRACE_MALLOC
-  if (nsContentUtils::IsCallerChrome()) {
-    // Attempt to initialize TraceMalloc functions
-    ::JS_DefineFunctions(cx, aGlobalObj, TraceMallocFunctions);
-  }
-#endif
-
 #ifdef MOZ_JPROF
   // Attempt to initialize JProf functions
   ::JS_DefineFunctions(cx, aGlobalObj, JProfFunctions);
 #endif
 
   return NS_OK;
 }
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -697,17 +697,17 @@ gfxPlatform::~gfxPlatform()
     VRHMDManagerOculus::Destroy();
 
     // The cairo folks think we should only clean up in debug builds,
     // but we're generally in the habit of trying to shut down as
     // cleanly as possible even in production code, so call this
     // cairo_debug_* function unconditionally.
     //
     // because cairo can assert and thus crash on shutdown, don't do this in release builds
-#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(NS_TRACE_MALLOC) || defined(MOZ_VALGRIND)
+#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(MOZ_VALGRIND)
 #ifdef USE_SKIA
     // must do Skia cleanup before Cairo cleanup, because Skia may be referencing
     // Cairo objects e.g. through SkCairoFTTypeface
     SkGraphics::Term();
 #endif
 
 #if MOZ_TREE_CAIRO
     cairo_debug_reset_static_data();
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2984,42 +2984,24 @@ elif test "$GNU_CC"; then
 
     if test -n "$MOZ_PGO"; then
         MOZ_C_SUPPORTS_WARNING(-W, no-error=coverage-mismatch, ac_c_has_noerror_coverage_mismatch)
         MOZ_CXX_SUPPORTS_WARNING(-W, no-error=coverage-mismatch, ac_cxx_has_noerror_coverage_mismatch)
     fi
 fi
 
 dnl ========================================================
-dnl = Enable trace malloc
-dnl ========================================================
-NS_TRACE_MALLOC=${MOZ_TRACE_MALLOC}
-MOZ_ARG_ENABLE_BOOL(trace-malloc,
-[  --enable-trace-malloc   Enable malloc tracing],
-    NS_TRACE_MALLOC=1,
-    NS_TRACE_MALLOC= )
-if test "$NS_TRACE_MALLOC"; then
-  # Please, Mr. Linker Man, don't take away our symbol names
-  MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
-  AC_DEFINE(NS_TRACE_MALLOC)
-fi
-AC_SUBST(NS_TRACE_MALLOC)
-
-dnl ========================================================
 dnl = Enable DMD
 dnl ========================================================
 
 MOZ_ARG_ENABLE_BOOL(dmd,
 [  --enable-dmd            Enable DMD; also enables jemalloc and replace-malloc],
     MOZ_DMD=1,
     MOZ_DMD= )
 
-if test "$NS_TRACE_MALLOC"; then        # trace-malloc disables DMD
-    MOZ_DMD=
-fi
 if test "$MOZ_DMD"; then
     AC_DEFINE(MOZ_DMD)
 
     if test "${CPU_ARCH}" = "arm"; then
         CFLAGS="$CFLAGS -funwind-tables"
         CXXFLAGS="$CXXFLAGS -funwind-tables"
     fi
 fi
@@ -3027,20 +3009,16 @@ fi
 dnl ========================================================
 dnl = Enable jemalloc
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(jemalloc,
 [  --enable-jemalloc       Replace memory allocator with jemalloc],
     MOZ_MEMORY=1,
     MOZ_MEMORY=)
 
-if test "$NS_TRACE_MALLOC"; then
-    MOZ_MEMORY=
-fi
-
 if test "$MOZ_MEMORY"; then
   AC_DEFINE(MOZ_MEMORY)
   if test "x$MOZ_DEBUG" = "x1"; then
     AC_DEFINE(MOZ_MEMORY_DEBUG)
   fi
   dnl The generic feature tests that determine how to compute ncpus are long and
   dnl complicated.  Therefore, simply define special cpp variables for the
   dnl platforms we have special knowledge of.
@@ -3424,19 +3402,19 @@ dnl = Support for demangling undefined s
 dnl ========================================================
 if test -z "$SKIP_LIBRARY_CHECKS"; then
     AC_LANG_SAVE
     AC_LANG_CPLUSPLUS
     AC_CHECK_FUNCS(__cxa_demangle, HAVE_DEMANGLE=1, HAVE_DEMANGLE=)
     AC_LANG_RESTORE
 fi
 
-# Demangle only for debug or trace-malloc or DMD builds
+# Demangle only for debug or DMD builds
 MOZ_DEMANGLE_SYMBOLS=
-if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then
+if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$MOZ_DMD"; then
     MOZ_DEMANGLE_SYMBOLS=1
     AC_DEFINE(MOZ_DEMANGLE_SYMBOLS)
 fi
 AC_SUBST(MOZ_DEMANGLE_SYMBOLS)
 
 dnl ========================================================
 dnl JIT observers
 dnl ========================================================
@@ -3666,17 +3644,17 @@ AC_SUBST(BUILD_CTYPES)
 if test "$JS_HAS_CTYPES"; then
   dnl Error out if we're on MSVC and MASM is unavailable.
   if test -n "$_MSC_VER" -a \( "$AS" != "ml.exe" -a "$AS" != "ml64.exe" \); then
     AC_MSG_ERROR([\"$AS\" is not a suitable assembler to build js-ctypes. If you are building with MS Visual Studio 8 Express, you may download the MASM 8.0 package, upgrade to Visual Studio 9 Express, or install the Vista SDK. Or do not use --enable-ctypes.])
   fi
   AC_DEFINE(JS_HAS_CTYPES)
 fi
 
-if test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then
+if test "$MOZ_DEBUG" -o "$MOZ_DMD"; then
     MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
 fi
 
 dnl ========================================================
 dnl =
 dnl = Options for generating the shell as a script
 dnl =
 dnl ========================================================
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -831,19 +831,16 @@ class XPCShellTests(object):
         """
         # Make assertions fatal
         self.env["XPCOM_DEBUG_BREAK"] = "stack-and-abort"
         # Crash reporting interferes with debugging
         if not self.debuggerInfo:
             self.env["MOZ_CRASHREPORTER"] = "1"
         # Don't launch the crash reporter client
         self.env["MOZ_CRASHREPORTER_NO_REPORT"] = "1"
-        # Capturing backtraces is very slow on some platforms, and it's
-        # disabled by automation.py too
-        self.env["NS_TRACE_MALLOC_DISABLE_STACKS"] = "1"
         # Don't permit remote connections by default.
         # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
         # enable non-local connections for the purposes of local testing.
         # Don't override the user's choice here.  See bug 1049688.
         self.env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
 
     def buildEnvironment(self):
         """
--- a/toolkit/components/aboutmemory/tests/test_aboutmemory.xul
+++ b/toolkit/components/aboutmemory/tests/test_aboutmemory.xul
@@ -121,17 +121,17 @@
 
   // mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones:
   // - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e"
   // - but *not* "explicit/c/d" x 2
   // Check explicit now before we add the fake reporters for the fake 2nd
   // and subsequent processes.
   //
   // Nb: mgr.explicit will throw NS_ERROR_NOT_AVAILABLE if this is a
-  // --enable-trace-malloc build.  Allow for that exception, but *only* that
+  // --disable-jemalloc build. Allow for that exception, but *only* that
   // exception.
   try {
     is(mgr.explicit, 500*MB + (100 + 13 + 10)*MB + 599*KB, "mgr.explicit");
   } catch (ex) {
     is(ex.result, Cr.NS_ERROR_NOT_AVAILABLE, "mgr.explicit exception");
   }
 
   // The main process always comes first when we display about:memory.  The
--- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul
+++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul
@@ -134,17 +134,17 @@
   let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
             getService(Ci.nsIMemoryReporterManager);
 
   // Access the distinguished amounts (mgr.explicit et al.) just to make sure
   // they don't crash.  We can't check their actual values because they're
   // non-deterministic.
   //
   // Nb: mgr.explicit will throw NS_ERROR_NOT_AVAILABLE if this is a
-  // --enable-trace-malloc build.  Allow for that exception, but *only* that
+  // --disable-jemalloc build.  Allow for that exception, but *only* that
   // exception.
   let dummy;
   let haveExplicit = true;
   try {
     dummy = mgr.explicit;
   } catch (ex) {
     is(ex.result, Cr.NS_ERROR_NOT_AVAILABLE, "mgr.explicit exception");
     haveExplicit = false;
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
@@ -16,19 +16,16 @@ DIRS += [
     # Depends on certverifier
     '/security/apps',
 ]
 
 # the signing related bits of libmar depend on nss
 if CONFIG['MOZ_UPDATER']:
     DIRS += ['/modules/libmar']
 
-if CONFIG['NS_TRACE_MALLOC']:
-    DIRS += ['/tools/trace-malloc/lib']
-
 DIRS += [
     '/config/external/freetype2',
     '/xpcom',
     '/modules/libpref',
     '/intl',
     '/netwerk',
 ]
 
@@ -158,19 +155,16 @@ DIRS += [
 if CONFIG['MOZ_GIO_COMPONENT']:
     DIRS += ['/extensions/gio']
 
 DIRS += [
     '/toolkit/library/StaticXULComponentsEnd',
     '/toolkit/library',
 ]
 
-if CONFIG['NS_TRACE_MALLOC']:
-    DIRS += ['/tools/trace-malloc']
-
 if CONFIG['MOZ_ENABLE_GNOME_COMPONENT']:
     DIRS += ['/toolkit/system/gnome']
 
 # if QtNetwork is present, it will do its own network monitoring
 if not CONFIG['MOZ_ENABLE_QTNETWORK'] and CONFIG['MOZ_ENABLE_DBUS']:
     DIRS += ['/toolkit/system/dbus']
 
 DIRS += ['/addon-sdk']
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -155,20 +155,16 @@
 #endif
 
 // for X remote support
 #ifdef MOZ_ENABLE_XREMOTE
 #include "XRemoteClient.h"
 #include "nsIRemoteService.h"
 #endif
 
-#ifdef NS_TRACE_MALLOC
-#include "nsTraceMalloc.h"
-#endif
-
 #if defined(DEBUG) && defined(XP_WIN32)
 #include <malloc.h>
 #endif
 
 #if defined (XP_MACOSX)
 #include <Carbon/Carbon.h>
 #endif
 
@@ -219,18 +215,17 @@ int    gRestartArgc;
 char **gRestartArgv;
 
 #ifdef MOZ_WIDGET_QT
 static int    gQtOnlyArgc;
 static char **gQtOnlyArgv;
 #endif
 
 #if defined(MOZ_WIDGET_GTK)
-#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) \
-  || defined(NS_TRACE_MALLOC)
+#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING)
 #define CLEANUP_MEMORY 1
 #define PANGO_ENABLE_BACKEND
 #include <pango/pangofc-fontmap.h>
 #endif
 #include <gtk/gtk.h>
 #ifdef MOZ_X11
 #include <gdk/gdkx.h>
 #endif /* MOZ_X11 */
@@ -3322,20 +3317,16 @@ XREMain::XRE_mainInit(bool* aExitFlag)
     return 0;
   }
 
   if (CheckArg("v") || CheckArg("version")) {
     DumpVersion();
     *aExitFlag = true;
     return 0;
   }
-    
-#ifdef NS_TRACE_MALLOC
-  gArgc = NS_TraceMallocStartupArgs(gArgc, gArgv);
-#endif
 
   rv = XRE_InitCommandLine(gArgc, gArgv);
   NS_ENSURE_SUCCESS(rv, 1);
 
   // Check for --register, which registers chrome and then exits immediately.
   ar = CheckArg("register", true);
   if (ar == ARG_BAD) {
     PR_fprintf(PR_STDERR, "Error: argument --register is invalid when argument --osint is specified\n");
deleted file mode 100644
--- a/tools/trace-malloc/Makefile.in
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXTRACSRCS = tmreader.c
-EXTRACPPSRCS = adreader.cpp
-
-ifndef MOZ_PROFILE_GENERATE
-
-PROGCSRCS = \
-  spacetrace.c \
-  spacecategory.c \
-  formdata.c \
-  $(NULL)
-
-PROGOBJS = $(PROGCSRCS:.c=.$(OBJ_SUFFIX))
-endif
-
-CPPSRCS += $(EXTRACPPSRCS)
-
-include $(topsrcdir)/config/config.mk
-
-# This is the last use of EXTRA_LIBS, and it would be sad to not have an
-# error if it's used in other Makefiles just because of it. So hack around
-# the check.
-_DEPRECATED_VARIABLES := $(filter-out EXTRA_LIBS,$(_DEPRECATED_VARIABLES))
-EXTRA_LIBS	+= \
-		tmreader.$(OBJ_SUFFIX) \
-		adreader.$(OBJ_SUFFIX) \
-		$(NULL)
-
-EXTRA_DEPS = $(EXTRACSRCS:.c=.$(OBJ_SUFFIX)) $(EXTRACPPSRCS:.cpp=.$(OBJ_SUFFIX))
-
-include $(topsrcdir)/config/rules.mk
-
-# install rules.txt along with spacetrace executable
-libs:: rules.txt
-	$(INSTALL) $< $(DIST)/bin
deleted file mode 100644
--- a/tools/trace-malloc/README
+++ /dev/null
@@ -1,177 +0,0 @@
-                      Trace Malloc Tools
-              Chris Waterson <waterson@netscape.com>
-                      November 27, 2000
-
-This is a short primer on how to use the `trace malloc' tools
-contained in this directory.
-
-
-WHAT IS TRACE MALLOC?
-=====================
-
-Trace malloc is an optional facility that is built in to XPCOM. It
-uses `weak linking' to intercept all calls to malloc(), calloc(),
-realloc() and free(). It does two things:
-
-1. Writes information about allocations to a filehandle that you
-specify. As each call to malloc(), et. al. is made, a record is logged
-to the filehandle.
-
-2. Maintains a table of all `live objects' -- that is, objects that
-have been allocated by malloc(), calloc() or realloc(), but have not
-yet been free()'d. The contents of this table can be called by making
-a `secret' call to JavaScript.
-
-
-MAKING A TRACE MALLOC BUILD
-===========================
-
-As of this writing, trace malloc only works on Linux, but work is
-underway to port it to Windows.
-
-On Linux, start with a clean tree, and configure your build with the
-following flags:
-
-  --enable-trace-malloc
-  --enable-cpp-rtti
-
-Be sure that `--enable-boehm' is *not* set. I don't think that the
-values for `--enable-debug' and `--enable-optimize' matter, but I've
-typically had debug on and optimize off.
-
-
-COLLECTING LIVE OBJECT DATA
-===========================
-
-To collect `live object' data from `mozilla' using a build that has
-trace malloc enabled,
-
-  1. Run `mozilla' as follows:
-
-     % mozilla --trace-malloc /dev/null
-
-  2. Do whatever operations in mozilla you'd like to test.
-
-  3. Open the `live-bloat.html' file contained in this directory.
-
-  4. Press the button that says `Dump to /tmp/dump.log'
-
-An enormous file (typically 300MB) called `dump.log' will be dropped
-in your `/tmp' directory.
-
-To collect live object data from `gtkEmbed' using a build that has
-trace malloc enabled:
-
-  1. Run `gtkEmbed' as follows:
-
-     % gtkEmbed --trace-malloc /dev/null
-
-  2. Do whatever operations in gtkEmbed that you'd like to test.
-
-  3. Press the `Dump Memory' button at the bottom of gtkEmbed.
-
-The enormous file will be dropped in the current directory, and is
-called `allocations.log'.
-
-
-About Live Object Logs
-----------------------
-
-A typical entry from the `live object' dump file will look like:
-
-  Address     Type      Size
-  |           |         |
-  v           v         v
-  0x40008080 <nsFooBar> 16
-        0x00000001 <- Fields
-        0x40008084
-        0x80004001
-        0x00000036
-  __builtin_new[./libxpcom.so +0x10E9DC]  <- Stack at allocation time
-  nsFooBar::CreateFooBar(nsFooBar **)[./libfoobar.so +0x408C]
-  main+C7E5AFB5[(null) +0xC7E5AFB5]
-
-One will be printed for each object that was allocated.
-
-
-TOOLS TO PARSE LIVE OBJECT LOGS
-===============================
-
-This directory is meant to house the tools that you can use to parse
-live-object logs.
-
-Object Histograms - histogram.pl
---------------------------------
-
-This program parses a `live object' dump and produces a histogram of
-the objects, sorted from objects that take the most memory to objects
-that take the least. The output of this program is rather spartan: on
-each line, it prints the object type, the number of objects of that
-type, and the total number of bytes that the objects consume.
-
-There are a two simple programs to `pretty print' the output from
-histogram.pl:
-
-  1. histogram-pretty.sh takes a single histogram and produces a table
-     of objects.
-
-       Type                    Count    Bytes %Total
-       TOTAL                   67348  4458127 100.00
-       nsImageGTK                 76   679092  15.23
-       void*                    8956   563572  12.64
-       ...
-       PRLock                    732    61488   1.38
-       OTHER                   24419   940235  21.09
-
-  2. histogram-diff.sh takes two histograms and computes the difference
-     between them.
-
-                  ---- Base ----   ---- Incr ----   ----- Difference ----
-       Type       Count    Bytes   Count    Bytes   Count    Bytes %Total
-       TOTAL      40241  1940945   73545  5315142   33304  3374197 100.00
-       nsImageGTK    16   106824     151   832816     135   725992  21.52
-       PresShell     16    51088     198   340706     182   289618   8.58
-       ...
-       OTHER      27334  1147033   38623  1493385   11289   346352  10.26
-
-Both of these scripts accept `-c' parameter that specifies how many
-rows you'd like to see (by default, twenty). Any rows past the first
-`n' rows are lumped into a single `OTHER' row. This allows you to keep
-your reports short n' sweet.
-
-Stack-based Type Inference - types.dat
---------------------------------------
-
-Trace malloc uses `speculative RTTI' to determine the types of objects
-as it dumps them. Unfortunately, RTTI can only deduce the type name
-for C++ objects with a virtual destructor.
-
-This leaves:
-
- . C++ object without a virtual destructor
- . array allocated C++ objects, and
- . objects allocated with the C runtime function (malloc
-   and friends)
-
-out in the cold. Trace malloc reports objects allocated this was as
-having type `void*'.
-
-The good news is that you can almost always determine the object's
-type by looking at the stack trace that's taken at the time the object
-is allocated.
-
-The file `types.dat' consists of rules to classify objects based on
-stack trace.
-
-
-Uncategorized Objects - uncategorized.pl
-----------------------------------------
-
-Categorizing objects in `types.dat' is sweaty work, and the
-`uncategorized.pl' script is a tool that makes it a bit
-easier. Specifically, it reads a `live object' dump file and sorts the
-stack traces. Stack traces that account for the most uncategorized
-objects are placed first.
-
-Using this tool, you can add the `most effective' rules to
-`types.dat': rules that account for most of the uncategorized data.
deleted file mode 100644
--- a/tools/trace-malloc/TraceMalloc.pm
+++ /dev/null
@@ -1,156 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-package TraceMalloc;
-
-use strict;
-
-# Read in the type inference file and construct a network that we can
-# use to match stack prefixes to types.
-sub init_type_inference($) {
-    my ($file) = @_;
-
-    $::Fingerprints = { };
-
-    open(TYPES, "<$file") || die "unable to open $::opt_types, $!";
-
-  TYPE: while (<TYPES>) {
-      next TYPE unless /<(.*)>/;
-      my $type = $1;
-
-      my $link = \%::Fingerprints;
-
-    FRAME: while (<TYPES>) {
-        chomp;
-        last FRAME if /^$/;
-
-        my $next = $link->{$_};
-        if (! $next) {
-            $next = $link->{$_} = {};
-        }
-        $link = $next;
-    }
-
-      $link->{'#type#'} = $type;
-
-      last TYPE if eof;
-  }
-}
-
-# Infer the type, trying to find the most specific type possible.
-sub infer_type($) {
-    my ($stack) = @_;
-
-    my $link = \%::Fingerprints;
-    my $last;
-    my $type = 'void*';
-  FRAME: foreach my $frame (@$stack) {
-      last FRAME unless $link;
-
-      $frame =~ s/\[.*\]$//; # ignore exact addresses, as they'll drift
-
-      $last = $link;
-
-      #
-      # Remember this type, but keep going.  We use the longest match
-      # we find, but substacks of longer matches will also match.
-      #
-      if ($last->{'#type#'}) {
-          $type = $last->{'#type#'};
-      }
-
-      $link = $link->{$frame};
-
-      if (! $link) {
-        CHILD: foreach my $child (keys %$last) {
-            next CHILD unless $child =~ /^~/;
-
-            $child =~ s/^~//;
-
-            if ($frame =~ $child) {
-                $link = $last->{'~' . $child};
-                last CHILD;
-            }
-          }
-      }
-  }
-
-    return $type;
-}
-
-
-#----------------------------------------------------------------------
-#
-# Read in the output a trace malloc's dump. 
-#
-sub read {
-    my ($callback, $noslop) = @_;
-
-  OBJECT: while (<>) {
-      # e.g., 0x0832FBD0 <void*> (80)
-      next OBJECT unless /^0x(\S+) <(.*)> \((\d+)\)/;
-      my ($addr, $type, $size) = (hex $1, $2, $3);
-
-      my $object = { 'type' => $type, 'size' => $size };
-
-      # Record the object's slots
-      my @slots;
-
-    SLOT: while (<>) {
-        # e.g.,      0x00000000
-        last SLOT unless /^\t0x(\S+)/;
-        my $value = hex $1;
-
-        # Ignore low bits, unless they've specified --noslop
-        $value &= ~0x7 unless $noslop;
-
-        $slots[$#slots + 1] = $value;
-    }
-
-      $object->{'slots'} = \@slots;
-
-      # Record the stack by which the object was allocated
-      my @stack;
-
-      while (/^(.*)\[(.*) \+0x(\S+)\]$/) {
-          # e.g., _dl_debug_message[/lib/ld-linux.so.2 +0x0000B858]
-          my ($func, $lib, $off) = ($1, $2, hex $3);
-
-          chomp;
-          $stack[$#stack + 1] = $_;
-
-          $_ = <>;
-      }
-
-      $object->{'stack'} = \@stack;
-
-      $object->{'type'} = infer_type(\@stack)
-          if $object->{'type'} eq 'void*';
-
-      &$callback($object) if $callback;
-
-      # Gotta check EOF explicitly...
-      last OBJECT if eof;
-  }
-}
-
-1;
-__END__
-
-=head1 NAME
-
-TraceMalloc - Perl routines to deal with output from ``trace malloc''
-and the Boehm GC
-
-=head1 SYNOPSIS
-
-    use TraceMalloc;
-
-    TraceMalloc::init_type_inference("types.dat");
-    TraceMalloc::read(0);
-
-=head1 DESCRIPTION
-
-=head1 EXAMPLES
-
-=cut
deleted file mode 100644
--- a/tools/trace-malloc/adreader.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "adreader.h"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-
-ADLog::ADLog()
-    : mEntryCount(0)
-{
-    mEntries.mNext = static_cast<EntryBlock*>(&mEntries);
-    mEntries.mPrev = static_cast<EntryBlock*>(&mEntries);
-}
-
-ADLog::~ADLog()
-{
-    for (const_iterator entry = begin(), entry_end = end();
-         entry != entry_end; ++entry) {
-        free((void*) (*entry)->type);
-        free((char*) (*entry)->data);
-        free((char*) (*entry)->allocation_stack);
-    }
-
-    for (EntryBlock *b = mEntries.mNext, *next; b != &mEntries; b = next) {
-        next = b->mNext;
-        delete b;
-    }
-}
-
-bool
-ADLog::Read(const char* aFileName)
-{
-    FILE *in = fopen(aFileName, "r");
-    if (!in) {
-        return false;
-    }
-
-    while (!feof(in)) {
-        unsigned int ptr;
-        char typebuf[256];
-        int datasize;
-        int res = fscanf(in, "%x %s (%d)\n", &ptr, typebuf, &datasize);
-        if (res == EOF)
-            break;
-        if (res != 3) {
-            return false;
-        }
-
-        size_t data_mem_size = ((datasize + sizeof(unsigned long) - 1) /
-                               sizeof(unsigned long)) * sizeof(unsigned long);
-        char *data = (char*)malloc(data_mem_size);
-
-        for (size_t *cur_data = (size_t*) data,
-                *cur_data_end = (size_t*) ((char*)data + data_mem_size);
-             cur_data != cur_data_end; ++cur_data) {
-            res = fscanf(in, " %zX\n", cur_data);
-            if (res != 1) {
-                return false;
-            }
-        }
-
-        char stackbuf[100000];
-        stackbuf[0] = '\0';
-
-        char *stack = stackbuf;
-        int len;
-        do {
-            fgets(stack, sizeof(stackbuf) - (stack - stackbuf), in);
-            len = strlen(stack);
-            stack += len;
-        } while (len > 1);
-
-        if (mEntryCount % ADLOG_ENTRY_BLOCK_SIZE == 0) {
-            EntryBlock *new_block = new EntryBlock();
-            new_block->mNext = static_cast<EntryBlock*>(&mEntries);
-            new_block->mPrev = mEntries.mPrev;
-            mEntries.mPrev->mNext = new_block;
-            mEntries.mPrev = new_block;
-        }
-
-        size_t typelen = strlen(typebuf);
-        char *type = (char*)malloc(typelen-1);
-        strncpy(type, typebuf+1, typelen-2);
-        type[typelen-2] = '\0';
-
-        Entry *entry =
-            &mEntries.mPrev->entries[mEntryCount % ADLOG_ENTRY_BLOCK_SIZE];
-        entry->address = (Pointer) (uintptr_t) ptr;
-        entry->type = type;
-        entry->datasize = datasize;
-        entry->data = data;
-        entry->allocation_stack = strdup(stackbuf);
-
-        ++mEntryCount;
-    }
-
-    return true;
-}
-
-ADLog::const_iterator::const_iterator(ADLog::EntryBlock *aBlock,
-                                      size_t aOffset)
-{
-    SetBlock(aBlock);
-    mCur = mBlockStart + aOffset;
-}
-
-ADLog::const_iterator&
-ADLog::const_iterator::operator++()
-{
-    ++mCur;
-    if (mCur == mBlockEnd) {
-        SetBlock(mBlock->mNext);
-        mCur = mBlockStart;
-    }
-
-    return *this;
-}
-
-ADLog::const_iterator&
-ADLog::const_iterator::operator--()
-{
-    if (mCur == mBlockStart) {
-        SetBlock(mBlock->mPrev);
-        mCur = mBlockEnd;
-    }
-    --mCur;
-
-    return *this;
-}
deleted file mode 100644
--- a/tools/trace-malloc/adreader.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdlib.h>
-
-#define ADLOG_ENTRY_BLOCK_SIZE 4096
-
-class ADLog {
-
-public:
-
-    // Use typedef in case somebody wants to process 64-bit output on a
-    // 32-bit machine someday.
-    typedef const char* Pointer;
-
-    struct Entry {
-        Pointer address;
-        const char *type;
-
-        const char *data;         // The contents of the memory.
-        size_t datasize;
-
-        const char *allocation_stack;
-    };
-
-    ADLog();
-    ~ADLog();
-
-    /*
-     * Returns false on failure and true on success.
-     */
-    bool Read(const char *aFilename);
-
-private:
-    // Link structure for a circularly linked list.
-    struct EntryBlock;
-    struct EntryBlockLink {
-        EntryBlock *mPrev;
-        EntryBlock *mNext;
-    };
-
-    struct EntryBlock : public EntryBlockLink {
-        Entry entries[ADLOG_ENTRY_BLOCK_SIZE];
-    };
-
-    size_t mEntryCount;
-    EntryBlockLink mEntries;
-
-public:
-
-    class const_iterator {
-        private:
-            // Only |ADLog| member functions can construct iterators.
-            friend class ADLog;
-            const_iterator(EntryBlock *aBlock, size_t aOffset);
-
-        public:
-            const Entry* operator*() { return mCur; }
-            const Entry* operator->() { return mCur; }
-
-            const_iterator& operator++();
-            const_iterator& operator--();
-
-            bool operator==(const const_iterator& aOther) const {
-                return mCur == aOther.mCur;
-            }
-
-            bool operator!=(const const_iterator& aOther) const {
-                return mCur != aOther.mCur;
-            }
-
-        private:
-            void SetBlock(EntryBlock *aBlock) {
-                mBlock = aBlock;
-                mBlockStart = aBlock->entries;
-                mBlockEnd = aBlock->entries + ADLOG_ENTRY_BLOCK_SIZE;
-            }
-
-            EntryBlock *mBlock;
-            Entry *mCur, *mBlockStart, *mBlockEnd;
-
-            // Not to be implemented.
-            const_iterator operator++(int);
-            const_iterator operator--(int);
-    };
-
-    const_iterator begin() {
-        return const_iterator(mEntries.mNext, 0);
-    }
-    const_iterator end() {
-        return const_iterator(mEntries.mPrev,
-                              mEntryCount % ADLOG_ENTRY_BLOCK_SIZE);
-    }
-
-    size_t count() { return mEntryCount; }
-};
deleted file mode 100644
--- a/tools/trace-malloc/allocation-stacks.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-extern int  getopt(int argc, char *const *argv, const char *shortopts);
-extern char *optarg;
-extern int  optind;
-#ifdef XP_WIN32
-int optind=1;
-#endif
-#endif
-#include <time.h>
-#include "nsTraceMalloc.h"
-#include "tmreader.h"
-
-static char *program;
-
-static void my_tmevent_handler(tmreader *tmr, tmevent *event)
-{
-    tmcallsite *callsite;
-
-    switch (event->type) {
-      case TM_EVENT_REALLOC:
-      case TM_EVENT_MALLOC:
-      case TM_EVENT_CALLOC:
-        for (callsite = tmreader_callsite(tmr, event->serial);
-             callsite != &tmr->calltree_root; callsite = callsite->parent) {
-            fprintf(stdout, "%s +%08X (%s:%d)\n",
-                    (const char*)callsite->method->graphnode.entry.value,
-                    callsite->offset,
-                    callsite->method->sourcefile,
-                    callsite->method->linenumber);
-        }
-        fprintf(stdout, "\n");
-    }
-}
-
-int main(int argc, char **argv)
-{
-    int i, j, rv;
-    tmreader *tmr;
-    FILE *fp;
-    time_t start;
-
-    program = *argv;
-
-    tmr = tmreader_new(program, NULL);
-    if (!tmr) {
-        perror(program);
-        exit(1);
-    }
-
-    start = time(NULL);
-    fprintf(stdout, "%s starting at %s", program, ctime(&start));
-    fflush(stdout);
-
-    argc -= optind;
-    argv += optind;
-    if (argc == 0) {
-        if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0)
-            exit(1);
-    } else {
-        for (i = j = 0; i < argc; i++) {
-            fp = fopen(argv[i], "r");
-            if (!fp) {
-                fprintf(stderr, "%s: can't open %s: %s\n",
-                        program, argv[i], strerror(errno));
-                exit(1);
-            }
-            rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler);
-            if (rv < 0)
-                exit(1);
-            if (rv > 0)
-                j++;
-            fclose(fp);
-        }
-        if (j == 0)
-            exit(1);
-    }
-    
-    tmreader_destroy(tmr);
-
-    exit(0);
-}
deleted file mode 100644
--- a/tools/trace-malloc/blame.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-td {
-  font: x-small sans-serif;
-  vertical-align: top;
-}
-
-thead td {
-  font-weight: bold;
-}
deleted file mode 100755
--- a/tools/trace-malloc/blame.pl
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/usr/bin/perl -w
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Process output of TraceMallocDumpAllocations() to produce a table
-# that attributes memory to the allocators using call stack.
-#
-
-use 5.004;
-use strict;
-
-# A table of all ancestors. Key is function name, value is an
-# array of ancestors, each attributed with a number of calls and
-# the amount of memory allocated.
-my %Ancestors;
-
-# Ibid, for descendants.
-my %Descendants;
-
-# A table that keeps the total amount of memory allocated by each
-# function
-my %Totals;
-$Totals{".root"} = { "#memory#" => 0, "#calls#" => 0 };
-
-# A table that maps the long ugly function name to a unique number so
-# that the HTML we generate isn't too fat
-my %Ids;
-my $NextId = 0;
-
-$Ids{".root"} = ++$NextId;
-
-
-LINE: while (<>) {
-    # The line'll look like:
-    #
-    #  0x4000a008     16  PR_Malloc+16; nsMemoryImpl::Alloc(unsigned int)+12; ...
-
-    # Ignore any lines that don't start with an address
-    next LINE unless /^0x/;
-
-    # Parse it
-    my ($address, $size, $rest) = /^(0x\S*)\s*(\d+)\s*(.*)$/;
-    my @stack = reverse(split /; /, $rest);
-
-    # Accumulate at the root
-    $Totals{".root"}->{"#memory#"} += $size;
-    ++$Totals{".root"}->{"#calls#"};
-
-    my $caller = ".root";
-    foreach my $callee (@stack) {
-        # Strip the offset from the callsite information. I don't
-        # think we care.
-        $callee =~ s/\+\d+$//g;
-
-        # Accumulate the total for the callee
-        if (! $Totals{$callee}) {
-            $Totals{$callee} = { "#memory#" => 0, "#calls#" => 0 };
-        }
-
-        $Totals{$callee}->{"#memory#"} += $size;
-        ++$Totals{$callee}->{"#calls#"};
-
-        # Descendants
-        my $descendants = $Descendants{$caller};
-        if (! $descendants) {
-            $descendants = $Descendants{$caller} = [ ];
-        }
-
-        # Manage the list of descendants
-        {
-            my $wasInserted = 0;
-          DESCENDANT: foreach my $item (@$descendants) {
-                if ($item->{"#name#"} eq $callee) {
-                    $item->{"#memory#"} += $size;
-                    ++$item->{"#calls#"};
-                    $wasInserted = 1;
-                    last DESCENDANT;
-                }
-            }
-
-            if (! $wasInserted) {
-                $descendants->[@$descendants] = {
-                    "#name#"   => $callee,
-                    "#memory#" => $size,
-                    "#calls#"  => 1
-                };
-            }
-        }
-
-        # Ancestors
-        my $ancestors = $Ancestors{$callee};
-        if (! $ancestors) {
-            $ancestors = $Ancestors{$callee} = [ ];
-        }
-
-        # Manage the list of ancestors
-        {
-            my $wasInserted = 0;
-          ANCESTOR: foreach my $item (@$ancestors) {
-                if ($item->{"#name#"} eq $caller) {
-                    $item->{"#memory#"} += $size;
-                    ++$item->{"#calls#"};
-                    $wasInserted = 1;
-                    last ANCESTOR;
-                }
-            }
-
-            if (! $wasInserted) {
-                $ancestors->[@$ancestors] = {
-                    "#name#"   => $caller,
-                    "#memory#" => $size,
-                    "#calls#"  => 1
-                };
-            }
-        }
-
-        # Make a new "id", if necessary
-        if (! $Ids{$callee}) {
-            $Ids{$callee} = ++$NextId;
-        }
-
-        # On to the next one...
-        $caller = $callee;
-    }
-}
-
-
-# Change the manky looking callsite into a pretty function; strip argument
-# types and offset information.
-sub pretty($) {
-    $_ = $_[0];
-    s/&/&amp;/g;
-    s/</&lt;/g;
-    s/>/&gt;/g;
-
-    if (/([^\(]*)(\(.*\))/) {
-        return $1 . "()";
-    }
-    else {
-        return $_[0];
-    }
-}
-
-# Dump a web page!
-print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n";
-print "<html><head>\n";
-print "<title>Live Bloat Blame</title>\n";
-print "<link rel=\"stylesheet\" type=\"text/css\" href=\"blame.css\">\n";
-print "</head>\n";
-print "<body>\n";
-
-# At most 100 rows per table so as not to kill the browser.
-my $maxrows = 100;
-
-print "<table>\n";
-print "<thead><tr><td>Function</td><td>Ancestors</td><td>Descendants</td></tr></thead>\n";
-
-foreach my $node (sort(keys(%Ids))) {
-    print "<tr>\n";
-
-    # Print the current node
-    {
-        my ($memory, $calls) =
-            ($Totals{$node}->{"#memory#"},
-             $Totals{$node}->{"#calls#"});
-
-        my $pretty = pretty($node);
-        print "  <td><a name=\"$Ids{$node}\">$pretty&nbsp;$memory&nbsp;($calls)</a></td>\n";
-    }
-
-    # Ancestors, sorted descending by amount of memory allocated
-    print "  <td>\n";
-    my $ancestors = $Ancestors{$node};
-    if ($ancestors) {
-        foreach my $ancestor (sort { $b->{"#memory#"} <=> $a->{"#memory#"} } @$ancestors) {
-            my ($name, $memory, $calls) =
-                ($ancestor->{"#name#"},
-                 $ancestor->{"#memory#"},
-                 $ancestor->{"#calls#"});
-
-            my $pretty = pretty($name);
-
-            print "    <a href=\"#$Ids{$name}\">$pretty</a>&nbsp;$memory&nbsp;($calls)<br>\n";
-        }
-    }
-
-    print "  </td>\n";
-
-    # Descendants, sorted descending by amount of memory allocated
-    print "  <td>\n";
-    my $descendants = $Descendants{$node};
-    if ($descendants) {
-        foreach my $descendant (sort { $b->{"#memory#"} <=> $a->{"#memory#"} } @$descendants) {
-            my ($name, $memory, $calls) =
-                ($descendant->{"#name#"},
-                 $descendant->{"#memory#"},
-                 $descendant->{"#calls#"});
-
-            my $pretty = pretty($name);
-
-            print "    <a href=\"#$Ids{$name}\">$pretty</a>&nbsp;$memory&nbsp;($calls)<br>\n";
-        }
-    }
-    print "  </td></tr>\n";
-
-    if (--$maxrows == 0) {
-        print "</table>\n";
-        print "<table>\n";
-        print "<thead><tr><td>Function</td><td>Ancestors</td><td>Descendants</td></tr></thead>\n";
-        $maxrows = 100;
-    }
-}
-
-# Footer
-print "</table>\n";
-print "</body></html>\n";
deleted file mode 100644
--- a/tools/trace-malloc/bloatblame.cpp
+++ /dev/null
@@ -1,722 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-#ifdef XP_WIN
-#include "getopt.c"
-#else
-extern int  getopt(int argc, char *const *argv, const char *shortopts);
-extern char *optarg;
-extern int  optind;
-#endif
-#endif
-#include <math.h>
-#include <time.h>
-#include <sys/stat.h>
-#include "prlog.h"
-#include "prprf.h"
-#include "plhash.h"
-#include "pldhash.h"
-#include "nsTraceMalloc.h"
-#include "tmreader.h"
-
-static char   *program;
-static int    sort_by_direct = 0;
-static int    js_mode = 0;
-static int    do_tree_dump = 0;
-static int    unified_output = 0;
-static char   *function_dump = NULL;
-static uint32_t min_subtotal = 0;
-
-static void compute_callsite_totals(tmcallsite *site)
-{
-    tmcallsite *kid;
-
-    site->allocs.bytes.total += site->allocs.bytes.direct;
-    site->allocs.calls.total += site->allocs.calls.direct;
-    for (kid = site->kids; kid; kid = kid->siblings) {
-        compute_callsite_totals(kid);
-        site->allocs.bytes.total += kid->allocs.bytes.total;
-        site->allocs.calls.total += kid->allocs.calls.total;
-    }
-}
-
-static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp)
-{
-    tmcallsite *parent;
-    tmgraphnode *comp, *pcomp, *lib, *plib;
-    tmmethodnode *meth, *pmeth;
-    int old_meth_low, old_comp_low, old_lib_low, nkids;
-    tmcallsite *kid;
-
-    parent = site->parent;
-    comp = lib = NULL;
-    meth = NULL;
-    if (parent) {
-        meth = site->method;
-        if (meth) {
-            pmeth = parent->method;
-            if (pmeth && pmeth != meth) {
-                if (!meth->graphnode.low) {
-                    meth->graphnode.allocs.bytes.total += site->allocs.bytes.total;
-                    meth->graphnode.allocs.calls.total += site->allocs.calls.total;
-                }
-                if (!tmgraphnode_connect(&(pmeth->graphnode), &(meth->graphnode), site))
-                    goto bad;
-
-                comp = meth->graphnode.up;
-                if (comp) {
-                    pcomp = pmeth->graphnode.up;
-                    if (pcomp && pcomp != comp) {
-                        if (!comp->low) {
-                            comp->allocs.bytes.total
-                                += site->allocs.bytes.total;
-                            comp->allocs.calls.total
-                                += site->allocs.calls.total;
-                        }
-                        if (!tmgraphnode_connect(pcomp, comp, site))
-                            goto bad;
-
-                        lib = comp->up;
-                        if (lib) {
-                            plib = pcomp->up;
-                            if (plib && plib != lib) {
-                                if (!lib->low) {
-                                    lib->allocs.bytes.total
-                                        += site->allocs.bytes.total;
-                                    lib->allocs.calls.total
-                                        += site->allocs.calls.total;
-                                }
-                                if (!tmgraphnode_connect(plib, lib, site))
-                                    goto bad;
-                            }
-                            old_lib_low = lib->low;
-                            if (!old_lib_low)
-                                lib->low = level;
-                        }
-                    }
-                    old_comp_low = comp->low;
-                    if (!old_comp_low)
-                        comp->low = level;
-                }
-            }
-            old_meth_low = meth->graphnode.low;
-            if (!old_meth_low)
-                meth->graphnode.low = level;
-        }
-    }
-
-    if (do_tree_dump) {
-        fprintf(fp, "%c%*s%3d %3d %s %lu %ld\n",
-                site->kids ? '+' : '-', level, "", level, kidnum,
-                meth ? tmmethodnode_name(meth) : "???",
-                (unsigned long)site->allocs.bytes.direct,
-                (long)site->allocs.bytes.total);
-    }
-    nkids = 0;
-    level++;
-    for (kid = site->kids; kid; kid = kid->siblings) {
-        walk_callsite_tree(kid, level, nkids, fp);
-        nkids++;
-    }
-
-    if (meth) {
-        if (!old_meth_low)
-            meth->graphnode.low = 0;
-        if (comp) {
-            if (!old_comp_low)
-                comp->low = 0;
-            if (lib) {
-                if (!old_lib_low)
-                    lib->low = 0;
-            }
-        }
-    }
-    return;
-
-bad:
-    perror(program);
-    exit(1);
-}
-
-/*
- * Linked list bubble-sort (waterson and brendan went bald hacking this).
- *
- * Sort the list in non-increasing order, using the expression passed as the
- * 'lessthan' formal macro parameter.  This expression should use 'curr' as
- * the pointer to the current node (of type nodetype) and 'next' as the next
- * node pointer.  It should return true if curr is less than next, and false
- * otherwise.
- */
-#define BUBBLE_SORT_LINKED_LIST(listp, nodetype, lessthan)                    \
-    PR_BEGIN_MACRO                                                            \
-        nodetype *curr, **currp, *next, **nextp, *tmp;                        \
-                                                                              \
-        currp = listp;                                                        \
-        while ((curr = *currp) != NULL && curr->next) {                       \
-            nextp = &curr->next;                                              \
-            while ((next = *nextp) != NULL) {                                 \
-                if (lessthan) {                                               \
-                    tmp = curr->next;                                         \
-                    *currp = tmp;                                             \
-                    if (tmp == next) {                                        \
-                        PR_ASSERT(nextp == &curr->next);                      \
-                        curr->next = next->next;                              \
-                        next->next = curr;                                    \
-                    } else {                                                  \
-                        *nextp = next->next;                                  \
-                        curr->next = next->next;                              \
-                        next->next = tmp;                                     \
-                        *currp = next;                                        \
-                        *nextp = curr;                                        \
-                        nextp = &curr->next;                                  \
-                    }                                                         \
-                    curr = next;                                              \
-                    continue;                                                 \
-                }                                                             \
-                nextp = &next->next;                                          \
-            }                                                                 \
-            currp = &curr->next;                                              \
-        }                                                                     \
-    PR_END_MACRO
-
-static int tabulate_node(PLHashEntry *he, int i, void *arg)
-{
-    tmgraphnode *node = (tmgraphnode*) he;
-    tmgraphnode **table = (tmgraphnode**) arg;
-
-    table[i] = node;
-    BUBBLE_SORT_LINKED_LIST(&node->down, tmgraphnode,
-        (curr->allocs.bytes.total < next->allocs.bytes.total));
-    return HT_ENUMERATE_NEXT;
-}
-
-/* Sort in reverse size order, so biggest node comes first. */
-static int node_table_compare(const void *p1, const void *p2)
-{
-    const tmgraphnode *node1, *node2;
-    uint32_t key1, key2;
-
-    node1 = *(const tmgraphnode**) p1;
-    node2 = *(const tmgraphnode**) p2;
-    if (sort_by_direct) {
-        key1 = node1->allocs.bytes.direct;
-        key2 = node2->allocs.bytes.direct;
-    } else {
-        key1 = node1->allocs.bytes.total;
-        key2 = node2->allocs.bytes.total;
-    }
-    return (key2 < key1) ? -1 : (key2 > key1) ? 1 : 0;
-}
-
-static int mean_size_compare(const void *p1, const void *p2)
-{
-    const tmgraphnode *node1, *node2;
-    double div1, div2, key1, key2;
-
-    node1 = *(const tmgraphnode**) p1;
-    node2 = *(const tmgraphnode**) p2;
-    div1 = (double)node1->allocs.calls.direct;
-    div2 = (double)node2->allocs.calls.direct;
-    if (div1 == 0 || div2 == 0)
-        return (int)(div2 - div1);
-    key1 = (double)node1->allocs.bytes.direct / div1;
-    key2 = (double)node2->allocs.bytes.direct / div2;
-    if (key1 < key2)
-        return 1;
-    if (key1 > key2)
-        return -1;
-    return 0;
-}
-
-static const char *prettybig(uint32_t num, char *buf, size_t limit)
-{
-    if (num >= 1000000000)
-        PR_snprintf(buf, limit, "%1.2fG", (double) num / 1e9);
-    else if (num >= 1000000)
-        PR_snprintf(buf, limit, "%1.2fM", (double) num / 1e6);
-    else if (num >= 1000)
-        PR_snprintf(buf, limit, "%1.2fK", (double) num / 1e3);
-    else
-        PR_snprintf(buf, limit, "%lu", (unsigned long) num);
-    return buf;
-}
-
-static double percent(uint32_t num, uint32_t total)
-{
-    if (num == 0)
-        return 0.0;
-    return ((double) num * 100) / (double) total;
-}
-
-static void sort_graphlink_list(tmgraphlink **listp, int which)
-{
-    BUBBLE_SORT_LINKED_LIST(listp, tmgraphlink,
-        (TM_LINK_TO_EDGE(curr, which)->allocs.bytes.total
-         < TM_LINK_TO_EDGE(next, which)->allocs.bytes.total));
-}
-
-static void dump_graphlink_list(tmgraphlink *list, int which, const char *name,
-                                FILE *fp)
-{
-    tmcounts bytes;
-    tmgraphlink *link;
-    tmgraphedge *edge;
-    char buf[16];
-
-    bytes.direct = bytes.total = 0;
-    for (link = list; link; link = link->next) {
-        edge = TM_LINK_TO_EDGE(link, which);
-        bytes.direct += edge->allocs.bytes.direct;
-        bytes.total += edge->allocs.bytes.total;
-    }
-
-    if (js_mode) {
-        fprintf(fp,
-                "   %s:{dbytes:%ld, tbytes:%ld, edges:[\n",
-                name, (long) bytes.direct, (long) bytes.total);
-        for (link = list; link; link = link->next) {
-            edge = TM_LINK_TO_EDGE(link, which);
-            fprintf(fp,
-                    "    {node:%d, dbytes:%ld, tbytes:%ld},\n",
-                    link->node->sort,
-                    (long) edge->allocs.bytes.direct,
-                    (long) edge->allocs.bytes.total);
-        }
-        fputs("   ]},\n", fp);
-    } else {
-        fputs("<td valign=top>", fp);
-        for (link = list; link; link = link->next) {
-            edge = TM_LINK_TO_EDGE(link, which);
-            fprintf(fp,
-                    "<a href='#%s'>%s&nbsp;(%1.2f%%)</a>\n",
-                    tmgraphnode_name(link->node),
-                    prettybig(edge->allocs.bytes.total, buf, sizeof buf),
-                    percent(edge->allocs.bytes.total, bytes.total));
-        }
-        fputs("</td>", fp);
-    }
-}
-
-static void dump_graph(tmreader *tmr, PLHashTable *hashtbl, const char *varname,
-                       const char *title, FILE *fp)
-{
-    uint32_t i, count;
-    tmgraphnode **table, *node;
-    char *name;
-    size_t namelen;
-    char buf1[16], buf2[16], buf3[16], buf4[16];
-
-    count = hashtbl->nentries;
-    table = (tmgraphnode**) malloc(count * sizeof(tmgraphnode*));
-    if (!table) {
-        perror(program);
-        exit(1);
-    }
-    PL_HashTableEnumerateEntries(hashtbl, tabulate_node, table);
-    qsort(table, count, sizeof(tmgraphnode*), node_table_compare);
-    for (i = 0; i < count; i++)
-        table[i]->sort = i;
-
-    if (js_mode) {
-        fprintf(fp,
-                "var %s = {\n name:'%s', title:'%s', nodes:[\n",
-                varname, varname, title);
-    } else {
-        fprintf(fp,
-                "<table border=1>\n"
-                  "<tr>"
-                    "<th>%s</th>"
-                    "<th>Down</th>"
-                    "<th>Next</th>"
-                    "<th>Total/Direct (percents)</th>"
-                    "<th>Allocations</th>"
-                    "<th>Fan-in</th>"
-                    "<th>Fan-out</th>"
-                  "</tr>\n",
-                title);
-    }
-
-    for (i = 0; i < count; i++) {
-        /* Don't bother with truly puny nodes. */
-        node = table[i];
-        if (node->allocs.bytes.total < min_subtotal)
-            break;
-
-        name = tmgraphnode_name(node);
-        if (js_mode) {
-            fprintf(fp,
-                    "  {name:'%s', dbytes:%ld, tbytes:%ld,"
-                                 " dallocs:%ld, tallocs:%ld,\n",
-                    name,
-                    (long) node->allocs.bytes.direct,
-                    (long) node->allocs.bytes.total,
-                    (long) node->allocs.calls.direct,
-                    (long) node->allocs.calls.total);
-        } else {
-            namelen = strlen(name);
-            fprintf(fp,
-                    "<tr>"
-                      "<td valign=top><a name='%s'>%.*s%s</a></td>",
-                    name,
-                    (namelen > 40) ? 40 : (int)namelen, name,
-                    (namelen > 40) ? "<i>...</i>" : "");
-            if (node->down) {
-                fprintf(fp,
-                      "<td valign=top><a href='#%s'><i>down</i></a></td>",
-                        tmgraphnode_name(node->down));
-            } else {
-                fputs("<td></td>", fp);
-            }
-            if (node->next) {
-                fprintf(fp,
-                      "<td valign=top><a href='#%s'><i>next</i></a></td>",
-                        tmgraphnode_name(node->next));
-            } else {
-                fputs("<td></td>", fp);
-            }
-            fprintf(fp,
-                      "<td valign=top>%s/%s (%1.2f%%/%1.2f%%)</td>"
-                      "<td valign=top>%s/%s (%1.2f%%/%1.2f%%)</td>",
-                    prettybig(node->allocs.bytes.total, buf1, sizeof buf1),
-                    prettybig(node->allocs.bytes.direct, buf2, sizeof buf2),
-                    percent(node->allocs.bytes.total,
-                            tmr->calltree_root.allocs.bytes.total),
-                    percent(node->allocs.bytes.direct,
-                            tmr->calltree_root.allocs.bytes.total),
-                    prettybig(node->allocs.calls.total, buf3, sizeof buf3),
-                    prettybig(node->allocs.calls.direct, buf4, sizeof buf4),
-                    percent(node->allocs.calls.total,
-                            tmr->calltree_root.allocs.calls.total),
-                    percent(node->allocs.calls.direct,
-                            tmr->calltree_root.allocs.calls.total));
-        }
-
-        /* NB: we must use 'fin' because 'in' is a JS keyword! */
-        sort_graphlink_list(&node->in, TM_EDGE_IN_LINK);
-        dump_graphlink_list(node->in, TM_EDGE_IN_LINK, "fin", fp);
-        sort_graphlink_list(&node->out, TM_EDGE_OUT_LINK);
-        dump_graphlink_list(node->out, TM_EDGE_OUT_LINK, "out", fp);
-
-        if (js_mode)
-            fputs("  },\n", fp);
-        else
-            fputs("</tr>\n", fp);
-    }
-
-    if (js_mode) {
-        fputs("]};\n", fp);
-    } else {
-        fputs("</table>\n<hr>\n", fp);
-
-        qsort(table, count, sizeof(tmgraphnode*), mean_size_compare);
-
-        fprintf(fp,
-                "<table border=1>\n"
-                  "<tr><th colspan=4>Direct Allocators</th></tr>\n"
-                  "<tr>"
-                    "<th>%s</th>"
-                    "<th>Mean&nbsp;Size</th>"
-                    "<th>StdDev</th>"
-                    "<th>Allocations<th>"
-                  "</tr>\n",
-                title);
-
-        for (i = 0; i < count; i++) {
-            double allocs, bytes, mean, variance, sigma;
-
-            node = table[i];
-            allocs = (double)node->allocs.calls.direct;
-            if (!allocs)
-                continue;
-
-            /* Compute direct-size mean and standard deviation. */
-            bytes = (double)node->allocs.bytes.direct;
-            mean = bytes / allocs;
-            variance = allocs * node->sqsum - bytes * bytes;
-            if (variance < 0 || allocs == 1)
-                variance = 0;
-            else
-                variance /= allocs * (allocs - 1);
-            sigma = sqrt(variance);
-
-            name = tmgraphnode_name(node);
-            namelen = strlen(name);
-            fprintf(fp,
-                    "<tr>"
-                      "<td valign=top>%.*s%s</td>"
-                      "<td valign=top>%s</td>"
-                      "<td valign=top>%s</td>"
-                      "<td valign=top>%s</td>"
-                    "</tr>\n",
-                    (namelen > 65) ? 45 : (int)namelen, name,
-                    (namelen > 65) ? "<i>...</i>" : "",
-                    prettybig((uint32_t)mean, buf1, sizeof buf1),
-                    prettybig((uint32_t)sigma, buf2, sizeof buf2),
-                    prettybig(node->allocs.calls.direct, buf3, sizeof buf3));
-        }
-        fputs("</table>\n", fp);
-    }
-
-    free((void*) table);
-}
-
-static void my_tmevent_handler(tmreader *tmr, tmevent *event)
-{
-    switch (event->type) {
-      case TM_EVENT_STATS:
-        if (js_mode)
-            break;
-        fprintf(stdout,
-                "<p><table border=1>"
-                  "<tr><th>Counter</th><th>Value</th></tr>\n"
-                  "<tr><td>maximum actual stack depth</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>maximum callsite tree depth</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>number of parent callsites</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>maximum kids per parent</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>hits looking for a kid</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>misses looking for a kid</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>steps over other kids</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>callsite recurrences</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>number of stack backtraces</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>backtrace failures</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>backtrace malloc failures</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>backtrace dladdr failures</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>malloc calls</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>malloc failures</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>calloc calls</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>calloc failures</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>realloc calls</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>realloc failures</td><td align=right>%lu</td></tr>\n"
-                  "<tr><td>free calls</td><td align=right>%lu</td></tr>\n"
-                "<tr><td>free(null) calls</td><td align=right>%lu</td></tr>\n"
-                "</table>",
-                (unsigned long) event->u.stats.tmstats.calltree_maxstack,
-                (unsigned long) event->u.stats.tmstats.calltree_maxdepth,
-                (unsigned long) event->u.stats.tmstats.calltree_parents,
-                (unsigned long) event->u.stats.tmstats.calltree_maxkids,
-                (unsigned long) event->u.stats.tmstats.calltree_kidhits,
-                (unsigned long) event->u.stats.tmstats.calltree_kidmisses,
-                (unsigned long) event->u.stats.tmstats.calltree_kidsteps,
-                (unsigned long) event->u.stats.tmstats.callsite_recurrences,
-                (unsigned long) event->u.stats.tmstats.backtrace_calls,
-                (unsigned long) event->u.stats.tmstats.backtrace_failures,
-                (unsigned long) event->u.stats.tmstats.btmalloc_failures,
-                (unsigned long) event->u.stats.tmstats.dladdr_failures,
-                (unsigned long) event->u.stats.tmstats.malloc_calls,
-                (unsigned long) event->u.stats.tmstats.malloc_failures,
-                (unsigned long) event->u.stats.tmstats.calloc_calls,
-                (unsigned long) event->u.stats.tmstats.calloc_failures,
-                (unsigned long) event->u.stats.tmstats.realloc_calls,
-                (unsigned long) event->u.stats.tmstats.realloc_failures,
-                (unsigned long) event->u.stats.tmstats.free_calls,
-                (unsigned long) event->u.stats.tmstats.null_free_calls);
-
-        if (event->u.stats.calltree_maxkids_parent) {
-            tmcallsite *site =
-                tmreader_callsite(tmr, event->u.stats.calltree_maxkids_parent);
-            if (site && site->method) {
-                fprintf(stdout, "<p>callsite with the most kids: %s</p>",
-                        tmmethodnode_name(site->method));
-            }
-        }
-
-        if (event->u.stats.calltree_maxstack_top) {
-            tmcallsite *site =
-                tmreader_callsite(tmr, event->u.stats.calltree_maxstack_top);
-            fputs("<p>deepest callsite tree path:\n"
-                  "<table border=1>\n"
-                    "<tr><th>Method</th><th>Offset</th></tr>\n",
-                  stdout);
-            while (site) {
-                fprintf(stdout,
-                    "<tr><td>%s</td><td>0x%08lX</td></tr>\n",
-                        site->method ? tmmethodnode_name(site->method) : "???",
-                        (unsigned long) site->offset);
-                site = site->parent;
-            }
-            fputs("</table>\n<hr>\n", stdout);
-        }
-        break;
-    }
-}
-
-int main(int argc, char **argv)
-{
-    int c, i, j, rv;
-    tmreader *tmr;
-    FILE *fp;
-
-    program = *argv;
-    tmr = tmreader_new(program, NULL);
-    if (!tmr) {
-        perror(program);
-        exit(1);
-    }
-
-    while ((c = getopt(argc, argv, "djtuf:m:")) != EOF) {
-        switch (c) {
-          case 'd':
-            sort_by_direct = 1;
-            break;
-          case 'j':
-            js_mode = 1;
-            break;
-          case 't':
-            do_tree_dump = 1;
-            break;
-          case 'u':
-            unified_output = 1;
-            break;
-          case 'f':
-            function_dump = optarg;
-            break;
-          case 'm':
-            min_subtotal = atoi(optarg);
-            break;
-          default:
-            fprintf(stderr,
-        "usage: %s [-dtu] [-f function-dump-filename] [-m min] [output.html]\n",
-                    program);
-            exit(2);
-        }
-    }
-
-    if (!js_mode) {
-        time_t start = time(NULL);
-
-        fprintf(stdout,
-                "<script language=\"JavaScript\">\n"
-                "function onload() {\n"
-                "  document.links[0].__proto__.onmouseover = new Function("
-                    "\"window.status ="
-                    " this.href.substring(this.href.lastIndexOf('#') + 1)\");\n"
-                "}\n"
-                "</script>\n");
-        fprintf(stdout, "%s starting at %s", program, ctime(&start));
-        fflush(stdout);
-    }
-
-    argc -= optind;
-    argv += optind;
-    if (argc == 0) {
-        if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0)
-            exit(1);
-    } else {
-        for (i = j = 0; i < argc; i++) {
-            fp = fopen(argv[i], "r");
-            if (!fp) {
-                fprintf(stderr, "%s: can't open %s: %s\n",
-                        program, argv[i], strerror(errno));
-                exit(1);
-            }
-            rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler);
-            if (rv < 0)
-                exit(1);
-            if (rv > 0)
-                j++;
-            fclose(fp);
-        }
-        if (j == 0)
-            exit(1);
-    }
-
-    compute_callsite_totals(&tmr->calltree_root);
-    walk_callsite_tree(&tmr->calltree_root, 0, 0, stdout);
-
-    if (js_mode) {
-        fprintf(stdout,
-                "<script language='javascript'>\n"
-                "// direct and total byte and allocator-call counts\n"
-                "var dbytes = %ld, tbytes = %ld,"
-                   " dallocs = %ld, tallocs = %ld;\n",
-                (long) tmr->calltree_root.allocs.bytes.direct,
-                (long) tmr->calltree_root.allocs.bytes.total,
-                (long) tmr->calltree_root.allocs.calls.direct,
-                (long) tmr->calltree_root.allocs.calls.total);
-    }
-
-    dump_graph(tmr, tmr->libraries, "libraries", "Library", stdout);
-    if (!js_mode)
-        fputs("<hr>\n", stdout);
-
-    dump_graph(tmr, tmr->components, "classes", "Class or Component", stdout);
-    if (js_mode || unified_output || function_dump) {
-        if (js_mode || unified_output || strcmp(function_dump, "-") == 0) {
-            fp = stdout;
-            if (!js_mode)
-                fputs("<hr>\n", fp);
-        } else {
-            struct stat sb, fsb;
-
-            fstat(fileno(stdout), &sb);
-            if (stat(function_dump, &fsb) == 0 &&
-                fsb.st_dev == sb.st_dev && fsb.st_ino == sb.st_ino) {
-                fp = stdout;
-                fputs("<hr>\n", fp);
-            } else {
-                fp = fopen(function_dump, "w");
-                if (!fp) {
-                    fprintf(stderr, "%s: can't open %s: %s\n",
-                            program, function_dump, strerror(errno));
-                    exit(1);
-                }
-            }
-        }
-
-        dump_graph(tmr, tmr->methods, "methods", "Function or Method", fp);
-        if (fp != stdout)
-            fclose(fp);
-
-        if (js_mode) {
-            fputs("function viewnode(graph, index) {\n"
-                  "  view.location = viewsrc();\n"
-                  "}\n"
-                  "function viewnodelink(graph, index) {\n"
-                  "  var node = graph.nodes[index];\n"
-                  "  return '<a href=\"javascript:viewnode('"
-                      " + graph.name.quote() + ', ' + node.sort"
-                      " + ')\" onmouseover=' + node.name.quote() + '>'"
-                      " + node.name + '</a>';\n"
-                  "}\n"
-                  "function search(expr) {\n"
-                  "  var re = new RegExp(expr);\n"
-                  "  var src = '';\n"
-                  "  var graphs = [libraries, classes, methods]\n"
-                  "  var nodes;\n"
-                  "  for (var n = 0; n < (nodes = graphs[n].nodes).length; n++) {\n"
-                  "    for (var i = 0; i < nodes.length; i++) {\n"
-                  "      if (re.test(nodes[i].name))\n"
-                  "        src += viewnodelink(graph, i) + '\\n';\n"
-                  "    }\n"
-                  "  }\n"
-                  "  view.location = viewsrc();\n"
-                  "}\n"
-                  "function ctrlsrc() {\n"
-                  "  return \"<form>\\n"
-                      "search: <input size=40 onchange='search(this.value)'>\\n"
-                      "</form>\\n\";\n"
-                  "}\n"
-                  "function viewsrc() {\n"
-                  "  return 'hiiiii'\n"
-                  "}\n"
-                  "</script>\n"
-                  "<frameset rows='10%,*'>\n"
-                  " <frame name='ctrl' src='javascript:top.ctrlsrc()'>\n"
-                  " <frame name='view' src='javascript:top.viewsrc()'>\n"
-                  "</frameset>\n",
-                  stdout);
-        }
-    }
-
-    exit(0);
-}
deleted file mode 100755
--- a/tools/trace-malloc/diffbloatdump.pl
+++ /dev/null
@@ -1,207 +0,0 @@
-#!/usr/bin/perl -w
-# vim:cindent:ts=8:et:sw=4:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# This script produces a diff between two files that are the result of
-# calling NS_TraceMallocDumpAllocations.  Such files can be created
-# through the command-line option --shutdown-leaks=<filename> or through
-# the DOM function window.TraceMallocDumpAllocations(<filename>).  Both
-# methods will work only if --trace-malloc=<malloc-log> is also given on
-# the command line.
-
-use 5.004;
-use strict;
-use Getopt::Long;
-
-$::opt_help = 0;
-$::opt_depth = 6;
-$::opt_include_zero = 0;
-$::opt_allocation_count = 0;
-$::opt_use_address = 0;
-
-# XXX Change --use-address to be the default and remove the option
-# once tinderbox is no longer using it without --use-address.
-
-Getopt::Long::Configure("pass_through");
-Getopt::Long::GetOptions("help", "allocation-count", "depth=i",
-                         "include-zero", "use-address");
-
-if ($::opt_help) {
-    die "usage: diffbloatdump.pl [options] <dump1> <dump2>
-  --help                 Display this message
-
-  --allocation-count     Use allocation count rather than size (i.e., treat
-                           all sizes as 1).
-  --depth=<num>          Only display <num> frames at top of allocation stack.
-  --include-zero         Display subtrees totalling zero.
-  --use-address          Don't ignore the address part of the stack trace
-                           (can make comparison more accurate when comparing
-                           results from the same build)
-
-  The input files (<dump1> and <dump2> above) are either trace-malloc
-  memory dumps OR this script's output.  (If this script's output,
-  --allocation-count and --use-address are ignored.)  If the input files
-  have .gz or .bz2 extension, they are uncompressed.
-";
-}
-
-my $calltree = { count => 0 }; # leave children undefined
-
-sub get_child($$) {
-    my ($node, $frame) = @_;
-    if (!defined($node->{children})) {
-        $node->{children} = {};
-    }
-    if (!defined($node->{children}->{$frame})) {
-        $node->{children}->{$frame} = { count => 0 };
-    }
-    return $node->{children}->{$frame};
-}
-
-sub add_tree_file($$$) {
-    my ($infile, $firstline, $factor) = @_;
-
-    my @nodestack;
-    $nodestack[1] = $calltree;
-    $firstline =~ /^(-?\d+) malloc$/;
-    $calltree->{count} += $1 * $factor;
-
-    my $lineno = 1;
-    while (!eof($infile)) {
-        my $line = <$infile>;
-        ++$lineno;
-        $line =~ /^( *)(-?\d+) (.*)$/ || die "malformed input, line $lineno";
-        my $depth = length($1);
-        my $count = $2;
-        my $frame = $3;
-        die "malformed input, line $lineno" if ($depth % 2 != 0);
-        $depth /= 2;
-        die "malformed input, line $lineno" if ($depth > $#nodestack);
-        $#nodestack = $depth;
-        my $node = get_child($nodestack[$depth], $frame);
-        push @nodestack, $node;
-        $node->{count} += $count * $factor;
-    }
-}
-
-sub add_file($$) {
-    # Takes (1) a reference to a file descriptor for input and (2) the
-    # factor to multiply the stacks by (generally +1 or -1).
-    # Returns a reference to an array representing the stack, allocation
-    # site in array[0].
-    sub read_stack($) {
-        my ($infile) = @_;
-        my $line;
-        my @stack;
-
-        # read the data at the memory location
-        while ( defined($infile) && ($line = <$infile>) && substr($line,0,1) eq "\t" ) {
-            # do nothing
-        }
-
-        # read the stack
-        do {
-            chomp($line);
-            if ( ! $::opt_use_address &&
-                 $line =~ /(.*)\[(.*)\]/) {
-                $line = $1;
-            }
-            $stack[$#stack+1] = $line;
-        } while ( defined($infile) && ($line = <$infile>) && $line ne "\n" && $line ne "\r\n" );
-
-        return \@stack;
-    }
-
-    # adds the stack given as a parameter (reference to array, $stack[0] is
-    # allocator) to $calltree, with the call count multiplied by $factor
-    # (typically +1 or -1).
-    sub add_stack($$) {
-        my @stack = @{$_[0]};
-        my $factor = $_[1];
-
-        my $i = 0;
-        my $node = $calltree;
-        while ($i < $#stack && $i < $::opt_depth) {
-            $node->{count} += $factor;
-            $node = get_child($node, $stack[$i]);
-            ++$i;
-        }
-        $node->{count} += $factor;
-    }
-
-    my ($infile, $factor) = @_;
-
-    if ($infile =~ /\.bz2$/) {
-        # XXX This doesn't propagate errors from bzip2.
-        open (INFILE, "bzip2 -cd '$infile' |") || die "Can't open input \"$infile\"";
-    } elsif ($infile =~ /\.gz$/) {
-        # XXX This doesn't propagate errors from gzip.
-        open (INFILE, "gzip -cd '$infile' |") || die "Can't open input \"$infile\"";
-    } else {
-        open (INFILE, "<$infile") || die "Can't open input \"$infile\"";
-    }
-    my $first = 1;
-    while ( ! eof(INFILE) ) {
-        # read the type and address
-        my $line = <INFILE>;
-        if ($first) {
-            $first = 0;
-            if ($line =~ /^-?\d+ malloc$/) {
-                # We're capable of reading in our own output as well.
-                add_tree_file(\*INFILE, $line, $factor);
-                close INFILE;
-                return;
-            }
-        }
-        unless ($line =~ /.*\((\d*)\)[\r|\n]/) {
-            die "badly formed allocation header in $infile";
-        }
-        my $size;
-        if ($::opt_allocation_count) {
-            $size = 1;
-        } else {
-            $size = $1;
-        }
-
-        add_stack(read_stack(\*INFILE), $size * $factor);
-    }
-    close INFILE;
-}
-
-sub print_node_indent($$$);
-
-sub print_calltree() {
-    sub print_indent($) {
-        my ($i) = @_;
-        while (--$i >= 0) {
-            print "  ";
-        }
-    }
-
-    sub print_node_indent($$$) {
-        my ($nodename, $node, $indent) = @_;
-
-        if (!$::opt_include_zero && $node->{count} == 0) {
-            return;
-        }
-
-        print_indent($indent);
-        print "$node->{count} $nodename\n";
-        if (defined($node->{children})) {
-            my %kids = %{$node->{children}};
-            ++$indent;
-            foreach my $kid (sort { $kids{$b}->{count} <=> $kids{$a}->{count} }
-                                  keys (%kids)) {
-                print_node_indent($kid, $kids{$kid}, $indent);
-            }
-        }
-    }
-
-    print_node_indent("malloc", $calltree, 0);
-}
-
-add_file($ARGV[0], -1);
-add_file($ARGV[1],  1);
-print_calltree();
deleted file mode 100644
--- a/tools/trace-malloc/formdata.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-**  formdata.c
-**
-**  Play utility to parse up form get data into name value pairs.
-*/
-
-#include "formdata.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-
-static void unhexcape(char* inPlace)
-/*
-**  Real low tech unhexcaper....
-**
-**  inPlace     string to decode, in place as it were.
-*/
-{
-    if(NULL != inPlace)
-    {
-        int index1 = 0;
-        int index2 = 0;
-        int theLen = strlen(inPlace);
-        
-        for(; index1 <= theLen; index1++)
-        {
-            if('%' == inPlace[index1] && '\0' != inPlace[index1 + 1] && '\0' != inPlace[index1 + 2])
-            {
-                int unhex = 0;
-                
-                if('9' >= inPlace[index1 + 1])
-                {
-                    unhex |= ((inPlace[index1 + 1] - '0') << 4);
-                }
-                else
-                {
-                    unhex |= ((toupper(inPlace[index1 + 1]) - 'A' + 10) << 4);
-                }
-                
-                if('9' >= inPlace[index1 + 2])
-                {
-                    unhex |= (inPlace[index1 + 2] - '0');
-                }
-                else
-                {
-                    unhex |= (toupper(inPlace[index1 + 2]) - 'A' + 10);
-                }
-                
-                index1 += 2;
-                inPlace[index1] = unhex;
-            }
-            
-            inPlace[index2++] = inPlace[index1];
-        }
-    }
-}
-
-
-FormData* FormData_Create(const char* inFormData)
-{
-    FormData* retval = NULL;
-
-    if(NULL != inFormData)
-    {
-        FormData* container = NULL;
-
-        /*
-        **  Allocate form data container.
-        */
-        container = (FormData*)calloc(1, sizeof(FormData));
-        if(NULL != container)
-        {
-            /*
-            **  Dup the incoming form data.
-            */
-            container->mStorage = strdup(inFormData);
-            if(NULL != container->mStorage)
-            {
-                char* traverse = NULL;
-                unsigned nvpairs = 1;
-                unsigned storeLen = 0;
-
-                /*
-                **  Count the number of pairs we are going to have.
-                **  We do this by counting '&' + 1.
-                */
-                for(traverse = container->mStorage; '\0' != *traverse; traverse++)
-                {
-                    if('&' == *traverse)
-                    {
-                        nvpairs++;
-                    }
-                }
-                storeLen = (unsigned)(traverse - container->mStorage);
-
-                /*
-                **  Allocate space for our names and values.
-                */
-                container->mNArray = (char**)calloc(nvpairs * 2, sizeof(char*));
-                if(NULL != container->mNArray)
-                {
-                    char* amp = NULL;
-                    char* equ = NULL;
-
-                    container->mVArray = &container->mNArray[nvpairs];
-
-                    /*
-                    **  Go back over the storage.
-                    **  Fill in the names and values as we go.
-                    **  Terminate on dividing '=' and '&' characters.
-                    **  Increase the count of items as we go.
-                    */
-                    for(traverse = container->mStorage; NULL != traverse; container->mNVCount++)
-                    {
-                        container->mNArray[container->mNVCount] = traverse;
-
-                        amp = strchr(traverse, '&');
-                        equ = strchr(traverse, '=');
-                        traverse = NULL;
-
-                        if(NULL != equ && (NULL == amp || equ < amp))
-                        {
-                            *equ++ = '\0';
-
-                            container->mVArray[container->mNVCount] = equ;
-                        }
-                        else
-                        {
-                            container->mVArray[container->mNVCount] = (container->mStorage + storeLen);
-                        }
-
-                        if(NULL != amp)
-                        {
-                            *amp++ = '\0';
-
-                            traverse = amp;
-                        }
-
-                        unhexcape(container->mNArray[container->mNVCount]);
-                        unhexcape(container->mVArray[container->mNVCount]);
-                    }
-
-                    retval = container;
-                }
-            }
-        }
-
-        /*
-        **  If we failed, cleanup.
-        */
-        if(NULL == retval)
-        {
-            FormData_Destroy(container);
-        }
-    }
-
-    return retval;
-}
-
-
-void FormData_Destroy(FormData* inDestroy)
-{
-    if(NULL != inDestroy)
-    {
-        unsigned traverse = 0;
-
-        for(traverse = 0; traverse < inDestroy->mNVCount; traverse++)
-        {
-            if(NULL != inDestroy->mNArray)
-            {
-                inDestroy->mNArray[traverse] = NULL;
-            }
-            if(NULL != inDestroy->mVArray)
-            {
-                inDestroy->mVArray[traverse] = NULL;
-            }
-        }
-        inDestroy->mNVCount = 0;
-
-        if(NULL != inDestroy->mStorage)
-        {
-            free(inDestroy->mStorage);
-            inDestroy->mStorage = NULL;
-        }
-
-        if(NULL != inDestroy->mNArray)
-        {
-            free(inDestroy->mNArray);
-            inDestroy->mNArray = NULL;
-            inDestroy->mVArray = NULL;
-        }
-
-        free(inDestroy);
-        inDestroy = NULL;
-    }
-}
deleted file mode 100644
--- a/tools/trace-malloc/formdata.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(__formdata_H__)
-#define __formdata_H__
-
-/*
-**  formdata.h
-**
-**  Play (quick and dirty) utility API to parse up form get data into
-**      name value pairs.
-*/
-
-typedef struct __struct_FormData
-/*
-**  Structure to hold the breakdown of any form data.
-**
-**  mNArray     Each form datum is a name value pair.
-**              This array holds the names.
-**              You can find the corresponding value at the same index in
-**                  mVArray.
-**              Never NULL, but perhpas an empty string.
-**  mVArray     Each form datum is a name value pair.
-**              This array holds the values.
-**              You can find the corresponding name at the same index in
-**                  mNArray.
-**              Never NULL, but perhpas an empty string.
-**  mNVCount    Count of array items in both mNArray and mVArray.
-**  mStorage    Should be ignored by users of this API.
-**              In reality holds the duped and decoded form data.
-*/
-{
-    char** mNArray;
-    char** mVArray;
-    unsigned mNVCount;
-    char* mStorage;
-}
-FormData;
-
-FormData* FormData_Create(const char* inFormData)
-/*
-**  Take a contiguous string of form data, possibly hex encoded, and return
-**      the name value pairs parsed up and decoded.
-**  A caller of this routine should call FormData_Destroy at some point.
-**
-**  inFormData          The form data to parse up and decode.
-**  returns FormData*   The result of our effort.
-**                      This should be passed to FormData_Destroy at some
-**                          point of the memory will be leaked.
-*/
-;
-
-void FormData_Destroy(FormData* inDestroy)
-/*
-**  Release to the heap the structure previously created via FormData_Create.
-**
-**  inDestroy   The object to free off.
-*/
-;
-
-#endif /* __formdata_H__ */
deleted file mode 100644
--- a/tools/trace-malloc/getopt.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getopt.c    4.12 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <string.h>
-#define index strchr
-#define rindex strrchr
-
-/*
- * get option letter from argument vector
- */
-int     opterr = 1,             /* if error message should be printed */
-	optind = 1,             /* index into parent argv vector */
-	optopt;                 /* character checked for validity */
-char    *optarg;                /* argument associated with option */
-
-#define BADCH   (int)'?'
-#define EMSG    ""
-
-int getopt(int nargc, char **nargv, char *ostr)
-{
-	static char *place = EMSG;              /* option letter processing */
-	register char *oli;                     /* option letter list index */
-	char *p;
-
-	if (!*place) {                          /* update scanning pointer */
-		if (optind >= nargc || *(place = nargv[optind]) != '-') {
-			place = EMSG;
-			return(EOF);
-		}
-		if (place[1] && *++place == '-') {      /* found "--" */
-			++optind;
-			place = EMSG;
-			return(EOF);
-		}
-	}                                       /* option letter okay? */
-	if ((optopt = (int)*place++) == (int)':' ||
-	    !(oli = index(ostr, optopt))) {
-		/*
-		 * if the user didn't specify '-' as an option,
-		 * assume it means EOF.
-		 */
-		if (optopt == (int)'-')
-			return(EOF);
-		if (!*place)
-			++optind;
-		if (opterr) {
-			if (!(p = rindex(*nargv, '/')))
-				p = *nargv;
-			else
-				++p;
-			(void)fprintf(stderr, "%s: illegal option -- %c\n",
-			    p, optopt);
-		}
-		return(BADCH);
-	}
-	if (*++oli != ':') {                    /* don't need argument */
-		optarg = NULL;
-		if (!*place)
-			++optind;
-	}
-	else {                                  /* need an argument */
-		if (*place)                     /* no white space */
-			optarg = place;
-		else if (nargc <= ++optind) {   /* no arg */
-			place = EMSG;
-			if (!(p = rindex(*nargv, '/')))
-				p = *nargv;
-			else
-				++p;
-			if (opterr)
-				(void)fprintf(stderr,
-				    "%s: option requires an argument -- %c\n",
-				    p, optopt);
-			return(BADCH);
-		}
-		else                            /* white space */
-			optarg = nargv[optind];
-		place = EMSG;
-		++optind;
-	}
-	return(optopt);                         /* dump back option letter */
-}
deleted file mode 100755
--- a/tools/trace-malloc/histogram-diff.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#   histogram-diff.sh [-c <count>] <base> <incr>
-#
-# Compute incremental memory growth from histogram in file <base> to
-# histogram in file <incr>, displaying at most <count> rows.
-
-# How many rows are we gonna show?
-COUNT=20
-
-# Read arguments
-while [ $# -gt 0 ]; do
-    case "$1" in
-    -c) COUNT=$2
-        shift 2
-        ;;
-    *)  break
-        ;;
-    esac
-done
-
-BASE=$1
-INCR=$2
-
-# Sort the base and incremental files so that we can `join' them on
-# the type name
-sort $BASE > /tmp/$$.left
-sort $INCR > /tmp/$$.right
-
-# Do the join. The `awk' script computes the difference between
-# the base and the incremental files.
-join /tmp/$$.left /tmp/$$.right \
-    | awk '{ print $1, $2, $3, $4, $5, $4 - $2, $5 - $3; }' \
-    > /tmp/$$.joined
-
-rm -f /tmp/$$.left /tmp/$$.right
-
-# Now compute a `TOTAL' row.
-awk '{ tobj1 += $2; tbytes1 += $3; tobj2 += $4; tbytes2 += $5; tdobj += $6; tdbytes += $7; } END { print "TOTAL", tobj1, tbytes1, tobj2, tbytes2, tdobj, tdbytes; }' /tmp/$$.joined \
-    > /tmp/$$.sorted
-
-# Then, we sort by the largest delta in bytes.
-sort -nr +6 /tmp/$$.joined >> /tmp/$$.sorted
-
-rm -f /tmp/$$.joined
-
-# Pretty-print, including percentages
-cat <<EOF > /tmp/$$.awk
-BEGIN {
-  print "                        ---- Base ----   ---- Incr ----   ----- Difference ----";
-  print "Type                    Count    Bytes   Count    Bytes   Count    Bytes %Total";
-  }
-\$1 == "TOTAL" {
-  tbytes = \$7;
-  }
-NR <= $COUNT {
-  printf "%-22s %6d %8d  %6d %8d  %6d %8d %6.2lf\n", \$1, \$2, \$3, \$4, \$5, \$6, \$7, 100.0 * \$7 / tbytes;
-  }
-NR > $COUNT {
-  oobjs1 += \$2;  obytes1 += \$3;
-  oobjs2 += \$4;  obytes2 += \$5;
-  odobjs += \$6;  odbytes += \$7;
-  }
-END {
-  printf "%-22s %6d %8d  %6d %8d  %6d %8d %6.2lf\n", "OTHER", oobjs1, obytes1, oobjs2, obytes2, odobjs, odbytes, odbytes * 100.0 / tbytes;
-  }
-EOF
-
-# Now pretty print the file, and spit it out on stdout.
-awk -f /tmp/$$.awk /tmp/$$.sorted
-
-rm -f /tmp/$$.awk /tmp/$$.sorted
deleted file mode 100755
--- a/tools/trace-malloc/histogram-pretty.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#   histogram-pretty.sh [-c <count>] [-w <width>] <file>
-#
-# Pretty-print the histogram in file <file>, displaying at most
-# <count> rows.
-
-# How many rows are we gonna show?
-COUNT=20
-WIDTH=22
-
-# Read arguments
-while [ $# -gt 0 ]; do
-    case "$1" in
-    -c) COUNT=$2
-        shift 2
-        ;;
-    -w) WIDTH=$2
-        shift 2
-        ;;
-    *)  break
-        ;;
-    esac
-done
-
-FILE=$1
-
-# The first `awk' script computes a `TOTAL' row. Then, we sort by the
-# larges delta in bytes.
-awk '{ tobj += $2; tbytes += $3; } END { print "TOTAL", tobj, tbytes; }' ${FILE} > /tmp/$$.sorted
-
-sort -nr +2 ${FILE} >> /tmp/$$.sorted
-
-# Pretty-print, including percentages
-cat <<EOF > /tmp/$$.awk
-BEGIN {
-  printf "%-${WIDTH}s  Count    Bytes %Total   %Cov\n", "Type";
-  }
-\$1 == "TOTAL" {
-  tbytes = \$3;
-  }
-NR <= $COUNT {
-  if (\$1 != "TOTAL") {
-    covered += \$3;
-  }
-  printf "%-${WIDTH}s %6d %8d %6.2lf %6.2lf\n", \$1, \$2, \$3, 100.0 * \$3 / tbytes, 100.0 * covered / tbytes;
-  }
-NR > $COUNT {
-  oobjs += \$2;  obytes += \$3; covered += \$3;
-  }
-END {
-  printf "%-${WIDTH}s %6d %8d %6.2lf %6.2lf\n", "OTHER", oobjs, obytes, obytes * 100.0 / tbytes, covered * 100.0 / tbytes;
-  }
-EOF
-
-# Now pretty print the file, and spit it out on stdout.
-awk -f /tmp/$$.awk /tmp/$$.sorted
-
-rm -f /tmp/$$.awk /tmp/$$.sorted
deleted file mode 100755
--- a/tools/trace-malloc/histogram.pl
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/perl -w
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# This program produces a ``class histogram'' of the live objects, one
-# line per class, with the total number of objects allocated, and
-# total number of bytes attributed to those objects.
-
-use 5.004;
-use strict;
-use Getopt::Long;
-
-# So we can find TraceMalloc.pm
-use FindBin;
-use lib "$FindBin::Bin";
-
-use TraceMalloc;
-
-# Collect program options
-$::opt_help = 0;
-$::opt_types = "${FindBin::Bin}/types.dat";
-
-GetOptions("help", "types=s");
-
-if ($::opt_help) {
-    die "usage: histogram.pl [options] <dumpfile>
-  --help          Display this message
-  --types=<file>  Read type heuristics from <file>";
-}
-
-# Initialize type inference juju from the type file specified by
-# ``--types''.
-if ($::opt_types) {
-    TraceMalloc::init_type_inference($::opt_types);
-}
-
-# Read the dump file, collecting count and size information for each
-# object that's detected.
-
-# This'll hold a record for each class that we detect
-$::Classes = { };
-
-sub collect_objects($) {
-    my ($object) = @_;
-    my $type = $object->{'type'};
-
-    my $entry = $::Classes{$type};
-    if (! $entry) {
-        $entry = $::Classes{$type} = { '#count#' => 0, '#bytes#' => 0 };
-    }
-
-    $entry->{'#count#'} += 1;
-    $entry->{'#bytes#'} += $object->{'size'};
-}
-
-TraceMalloc::read(\&collect_objects);
-
-# Print one line per class, sorted with the classes that accumulated
-# the most bytes first.
-foreach my $class (sort { $::Classes{$b}->{'#bytes#'} <=> $::Classes{$a}->{'#bytes#'} } keys %::Classes) {
-    print "$class $::Classes{$class}->{'#count#'} $::Classes{$class}->{'#bytes#'}\n";
-}
deleted file mode 100755
--- a/tools/trace-malloc/leak-soup.pl
+++ /dev/null
@@ -1,1180 +0,0 @@
-#!/usr/bin/perl -w
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# A perl version of Patrick Beard's ``Leak Soup'', which processes the
-# stack crawls from the Boehm GC into a graph.
-
-use 5.004;
-use strict;
-use Getopt::Long;
-use FileHandle;
-use IPC::Open2;
-
-# Collect program options
-$::opt_help = 0;
-$::opt_detail = 0;
-$::opt_fragment = 1.0; # Default to no fragment analysis
-$::opt_nostacks = 0;
-$::opt_nochildstacks = 0;
-$::opt_depth = 9999;
-$::opt_noentrained = 0;
-$::opt_noslop = 0;
-$::opt_showtype = -1; # default to listing all types
-$::opt_stackrefine = "C";
-@::opt_stackretype = ();
-@::opt_stackskipclass = ();
-@::opt_stackskipfunc = ();
-@::opt_typedivide = ();
-
-GetOptions("help", "detail", "format=s", "fragment=f", "nostacks", 
-	   "nochildstacks", "depth=i", "noentrained", "noslop", "showtype=i", 
-	   "stackrefine=s", "stackretype=s@", "stackskipclass=s@", "stackskipfunc=s@",
-	   "typedivide=s@"
-	   );
-
-if ($::opt_help) {
-    die "usage: leak-soup.pl [options] <leakfile>
-  --help                 Display this message
-  --detail               Provide details of memory sweeping from child to parents
-  --fragment=ratio       Histogram bucket ratio for fragmentation analysis
-#  --nostacks            Do not compute stack traces
-#  --nochildstacks       Do not compute stack traces for entrained objects
-#  --depth=<max>         Only compute stack traces to depth of <max>
-#  --noentrained         Do not compute amount of memory entrained by root objects
-  --noslop               Don't ignore low bits when searching for pointers
-  --showtype=<i>         Show memory usage histogram for most-significant <i> types
-  --stackrefine={F|C}    During stack based refinement, use 'F'ull name name or just 'C'lass
-  --stackretype=type     Use allocation stack to refine vague types like void*
-  --stackskipclass=class When refining types, ignore stack frames from 'class'
-  --stackskipfunc=func   When refining types, ignore stack frames for 'func'
-  --typedivide=type      Subdivide 'type' based on objects pointing to each instance
-";
-}
-
-# This is the table that keeps a graph of objects. It's indexed by the
-# object's address (as an integer), and refers to a simple hash that
-# has information about the object's type, size, slots, and allocation
-# stack.
-%::Objects = %{0};
-
-# This will be a list of keys to (addresses in) Objects, that is sorted
-# It gets used to evaluate overlaps, calculate fragmentation, and chase 
-# parent->child (interior) pointers.
-@::SortedAddresses = [];
-
-# This is the table that keeps track of memory usage on a per-type basis.
-# It is indexed by the type name (string), and keeps a tally of the 
-# total number of such objects, and the memory usage of such objects.
-%::Types = %{0};
-$::TotalSize = 0; # sum of sizes of all objects included $::Types{}
-
-# This is an array of leaf node addresses.  A leaf node has no children
-# with memory allocations. We traverse them sweeping memory
-# tallies into parents.  Note that after all children have
-# been swept into a parent, that parent may also become a leaf node.
-@::Leafs = @{0};
-
-
-
-
-#----------------------------------------------------------------------
-#
-# Decode arguments to override default values for doing call-stack-based 
-# refinement of typename based on contents of the stack at allocation time.
-#
-
-# List the types that we need to refine (if any) based on allocation stack
-$::VagueType = {
-    'void*' => 1,
-};
-
-# With regard to the stack, ignore stack frames in the following
-# overly vague classes.
-$::VagueClasses = {
-#    'nsStr' => 1,
-    'nsVoidArray' => 1,
-};
-
-# With regard to stack, ignore stack frames with the following vague
-# function names
-$::VagueFunctions = {
-    'PL_ArenaAllocate' => 1,
-    'PL_HashTableFinalize(PLHashTable *)' => 1,
-    'PL_HashTableInit__FP11PLHashTableUiPFPCv_UiPFPCvPCv_iT3PC14PLHashAllocOpsPv' => 1,
-    'PL_HashTableRawAdd' => 1,
-    '__builtin_vec_new' => 1,
-    '_init' => 1,
-    'il_get_container(_IL_GroupContext *, ImgCachePolicy, char const *, _NI_IRGB *, IL_DitherMode, int, int, int)' => 1,
-    'nsCStringKey::Clone(void) const' => 1,
-    'nsCppSharedAllocator<unsigned short>::allocate(unsigned int, void const *)' => 1,
-    'nsHashtable::Put(nsHashKey *, void *)' => 1,
-    'nsHashtable::nsHashtable(unsigned int, int)' => 1,
-    'nsMemory::Alloc(unsigned int)' => 1,
-    'nsMemoryImpl::Alloc(unsigned int)' => 1,
-};
-
-sub init_stack_based_type_refinement() {
-    # Move across stackretype options, or use default values
-    if ($#::opt_stackretype < 0) {
-	print "Default --stackretype options will be used (since none were specified)\n";
-	print "  use --stackretype='nothing' to disable re-typing activity\n";
-    } else {
-	foreach my $type (keys %{$::VagueType}) {
-	    delete ($::VagueType->{$type});
-	}
-	if ($#::opt_stackretype == 0 && $::opt_stackretype[0] eq 'nothing') {
-	    print "Types will not be refined based on call stack\n";
-	} else {
-	    foreach my $type (@::opt_stackretype) {
-		$::VagueType->{$type} = 1;
-	    }
-	}
-    }
-
-
-    if (keys %{$::VagueType}) {
-	print "The following type(s) will be refined based on call stacks:\n";
-	foreach my $type (sort keys %{$::VagueType}) {
-	    print "     $type\n";
-	}
-	print "Equivalent command line argument(s):\n";
-	foreach my $type (sort keys %{$::VagueType}) {
-	    print " --stackretype='$type'";
-	}
-	print "\n\n";
-
-	if ($#::opt_stackskipclass < 0) {
-	    print "Default --stackskipclass options will be used (since none were specified)\n";
-	    print "  use --stackskipclass='nothing' to disable skipping stack frames based on class names\n";
-	} else {
-	    foreach my $type (keys %{$::VagueClasses}) {
-		delete ($::VagueClasses->{$type});
-	    }
-	    if ($#::opt_stackskipclass == 0 && $::opt_stackskipclass[0] eq 'nothing') {
-		print "Types will not be refined based on call stack\n";
-	    } else {
-		foreach my $type (@::opt_stackskipclass) {
-		    $::VagueClasses->{$type} = 1;
-		}
-	    }
-	}
-
-	if (keys %{$::VagueClasses}) {
-	    print "Stack frames from the following class(es) will not be used to refine types:\n";
-	    foreach my $class (sort keys %{$::VagueClasses}) {
-		print "     $class\n";
-	    }
-	    print "Equivalent command line argument(s):\n";
-	    foreach my $class (sort keys %{$::VagueClasses}) {
-		print " --stackskipclass='$class'";
-	    }
-	    print "\n\n";
-	}
-
-
-	if ($#::opt_stackskipfunc < 0) {
-	    print "Default --stackskipfunc options will be used (since none were specified)\n";
-	    print "  use --stackskipfunc='nothing' to disable skipping stack frames based on function names\n";
-	} else {
-	    foreach my $type (keys %{$::VagueFunctions}) {
-		delete ($::VagueFunctions->{$type});
-	    }
-	    if ($#::opt_stackskipfunc == 0 && $::opt_stackskipfunc[0] eq 'nothing') {
-		print "Types will not be refined based on call stack\n";
-	    } else {
-		foreach my $type (@::opt_stackskipfunc) {
-		    $::VagueFunctions->{$type} = 1;
-		}
-	    }
-	}
-
-	if (keys %{$::VagueFunctions}) {
-	    print "Stack frames from the following function(s) will not be used to refine types:\n";
-	    foreach my $func (sort keys %{$::VagueFunctions}) {
-		print "     $func\n";
-	    }
-	    print "Equivalent command line argument(s):\n";
-	    foreach my $func (sort keys %{$::VagueFunctions}) {
-		print " --stackskipfunc='$func'";
-	    }
-	    print "\n\n";
-	}
-    }
-}
-
-
-#----------------------------------------------------------------------
-#
-# Read in the output from the Boehm GC or Trace-malloc. 
-#
-sub read_boehm() {
-  OBJECT: while (<>) {
-      # e.g., 0x0832FBD0 <void*> (80)
-      next OBJECT unless /^0x(\S+) <(.*)> \((\d+)\)/;
-      my ($addr, $type, $size) = (hex $1, $2, $3);
-
-      my $object = $::Objects{$addr};
-      if (! $object) {
-          # Found a new object entry. Record its type and size
-          $::Objects{$addr} =
-              $object =
-              { 'type' => $type, 'size' => $size };
-      } else {
-	  print "Duplicate address $addr contains $object->{'type'} and $type\n";
-	  $object->{'dup_addr_count'}++;
-      }
-
-      # Record the object's slots
-      my @slots;
-
-    SLOT: while (<>) {
-        # e.g.,      0x00000000
-        last SLOT unless /^\t0x(\S+)/;
-        my $value = hex $1;
-
-        # Ignore low bits, unless they've specified --noslop
-        $value &= ~0x7 unless $::opt_noslop;
-
-        $slots[$#slots + 1] = $value;
-    }
-
-      $object->{'slots'} = \@slots;
-
-      if (@::opt_stackretype && (defined $::VagueType->{$type})) {
-	  # Change the value of type of the object based on stack
-	  # if we can find an interesting calling function
-        VAGUEFRAME: while (<>) {
-            # e.g., _dl_debug_message[/lib/ld-linux.so.2 +0x0000B858]
-            last VAGUEFRAMEFRAME unless /^(.*)\[(.*) \+0x(\S+)\]$/;
-            my ($func, $lib, $off) = ($1, $2, hex $3);
-            chomp;
-
-	    my ($class,,$fname) = split(/:/, $func);
-	    next VAGUEFRAME if (defined $::VagueFunctions->{$func} || 
-				defined $::VagueClasses->{$class});
-
-	    # Refine typename and exit stack scan
-	    $object->{'type'} = $type . ":" . 
-		(('C' eq $::opt_stackrefine) ?
-		 $class :
-		 $func);
-	    last VAGUEFRAME;
-	} 
-      } else {
-	  # Save all stack info if requested
-	  if (! $::opt_nostacks) {
-	      # Record the stack by which the object was allocated
-	      my @stack;
-
-	    FRAME: while (<>) {
-		# e.g., _dl_debug_message[/lib/ld-linux.so.2 +0x0000B858]
-		last FRAME unless /^(.*)\[(.*) \+0x(\S+)\]$/;
-		my ($func, $lib, $off) = ($1, $2, hex $3);
-		chomp;
-
-		$stack[$#stack + 1] = $_;
-	    }
-		
-	      $object->{'stack'} = \@stack;
-	  }
-      }
-
-      # Gotta check EOF explicitly...
-      last OBJECT if eof;
-  }
-}
-
-
-#----------------------------------------------------------------------
-#
-# Read input
-#
-init_stack_based_type_refinement();
-read_boehm;
-
-
-
-#----------------------------------------------------------------------
-#
-# Do basic initialization of the type hash table.  Accumulate
-# total counts, and basic memory usage (not including children)
-sub load_type_table() {
-    # Reset global counter and hash table
-    $::TotalSize = 0;
-    %::Types = %{0};
-
-    OBJECT: foreach my $addr (keys %::Objects) {
-	my $obj = $::Objects{$addr};
-	my ($type, $size, $swept_in, $overlap_count, $dup_addr_count) = 
-	    ($obj->{'type'}, $obj->{'size'}, 
-	     $obj->{'swept_in'}, 
-	     $obj->{'overlap_count'},$obj->{'dup_addr_count'});
-
-	my $type_data = $::Types{$type};
-	if (! defined $type_data) {
-	    $::Types{$type} =
-		$type_data = {'count' => 0, 'size' => 0, 
-			      'max' => $size, 'min' => $size,
-			      'swept_in' => 0, 'swept' => 0,
-			      'overlap_count' => 0,
-			      'dup_addr_count' => 0};
-	}
-
-	if (!$size) {
-	    $type_data->{'swept'}++;
-	    next OBJECT;
-	}
-	$::TotalSize += $size;
-
-	$type_data->{'count'}++;
-	$type_data->{'size'} += $size;
-	if (defined $swept_in) {
-	    $type_data->{'swept_in'} += $swept_in;
-
-	    if ($::opt_detail) {
-		my $type_detail_sizes = $type_data->{'sweep_details_size'};
-		my $type_detail_counts;
-		if (!defined $type_detail_sizes) {
-		    $type_detail_sizes = $type_data->{'sweep_details_size'} = {};
-		    $type_detail_counts = $type_data->{'sweep_details_count'} = {};
-		} else {
-		    $type_detail_counts = $type_data->{'sweep_details_count'};
-		}
-
-		my $sweep_details = $obj->{'sweep_details'};
-		for my $swept_addr (keys (%{$sweep_details})) {
-		    my $swept_obj = $::Objects{$swept_addr};
-		    my $swept_type = $swept_obj->{'type'};
-		    $type_detail_sizes->{$swept_type} += $sweep_details->{$swept_addr};
-		    $type_detail_counts->{$swept_type}++;
-		}
-	    }
-	}
-	if (defined $overlap_count) {
-	    $type_data->{'overlap_count'} += $overlap_count;
-	}
-
-	if (defined $dup_addr_count) {
-	    $type_data->{'dup_addr_count'} += $dup_addr_count;
-	}
-
-	if ($type_data->{'max'} < $size) {
-	    $type_data->{'max'} = $size;
-	}
-	# Watch out for case where min is produced by a swept object
-	if (!$type_data->{'min'} || $type_data->{'min'} > $size) {
-	    $type_data->{'min'} = $size;
-	}
-    }
-}
-
-
-#----------------------------------------------------------------------
-sub print_type_table(){
-    if (!$::opt_showtype) {
-	return;
-    }
-    my $line_count = 0;
-    my $bytes_printed_tally = 0;
-
-    # Display type summary information
-    my @sorted_types = keys (%::Types);
-    print "There are ", 1 + $#sorted_types, " types containing ", $::TotalSize, " bytes\n";
-    @sorted_types = sort {$::Types{$b}->{'size'}
-			  <=> $::Types{$a}->{'size'} } @sorted_types;
-
-    foreach my $type (@sorted_types) {
-	last if ($line_count++ == $::opt_showtype);
-
-	my $type_data = $::Types{$type};
-	$bytes_printed_tally += $type_data->{'size'};
-
-	if ($type_data->{'count'}) {
-	    printf "%.2f%% ", $type_data->{'size'} * 100.0/$::TotalSize;
-	    print $type_data->{'size'}, 
-	    "\t(", 
-	    $type_data->{'min'}, "/", 
-	    int($type_data->{'size'} / $type_data->{'count'}),"/", 
-	    $type_data->{'max'}, ")";
-	    print "\t", $type_data->{'count'}, 
-	    " x ";
-	}
-	print $type;
-
-	if ($type_data->{'swept_in'}) {	    
-	    print ", $type_data->{'swept_in'} sub-objs absorbed";
-	}
-	if ($type_data->{'swept'}) {
-	    print ", $type_data->{'swept'} swept away";
-	}
-	if ($type_data->{'overlap_count'}) {	    
-	    print ", $type_data->{'overlap_count'} range overlaps";
-	}
-	if ($type_data->{'dup_addr_count'}) {	    
-	    print ", $type_data->{'dup_addr_count'} duplicated addresses";
-	}
-
-	print "\n" ;
-	if (defined $type_data->{'sweep_details_size'}) {
-	    my $sizes = $type_data->{'sweep_details_size'};
-	    my $counts = $type_data->{'sweep_details_count'};
-	    my @swept_types = sort {$sizes->{$b} <=> $sizes->{$a}} keys (%{$sizes});
-	    
-	    for my $type (@swept_types) {
-		printf "    %.2f%% ", $sizes->{$type} * 100.0/$::TotalSize;
-		print "$sizes->{$type}     (", int($sizes->{$type}/$counts->{$type}) , ")   $counts->{$type} x $type\n";
-	    }
-	    print "    ---------------\n";
-	}
-    }
-    if ($bytes_printed_tally != $::TotalSize) {
-	printf "%.2f%% ", ($::TotalSize- $bytes_printed_tally) * 100.0/$::TotalSize;
-	print $::TotalSize - $bytes_printed_tally, "\t not shown due to truncation of type list\n";
-	print "Currently only data on $::opt_showtype types are displayed, due to command \n",
-	    "line argument '--showtype=$::opt_showtype'\n\n";
-    }
-
-}
-
-#----------------------------------------------------------------------
-#
-# Check for duplicate address ranges is Objects table, and 
-# create list of sorted addresses for doing pointer-chasing
-
-sub validate_address_ranges() {
-    # Build sorted list of address for validating interior pointers
-    @::SortedAddresses = sort {$a <=> $b} keys %::Objects;
-
-    # Validate non-overlap of memory
-    my $prev_addr_end = -1;
-    my $prev_addr = -1;
-    my $index = 0;
-    my $overlap_tally = 0; # overlapping object memory
-    my $unused_tally = 0;  # unused memory between blocks
-    while ($index <= $#::SortedAddresses) {
-	my $address = $::SortedAddresses[$index];
-	if ($prev_addr_end > $address) {
-	    print "Object overlap from $::Objects{$prev_addr}->{'type'}:$prev_addr-$prev_addr_end into";
-	    my $test_index = $index;
-	    my $prev_addr_overlap_tally = 0;
-
-	    while ($test_index <=  $#::SortedAddresses) {
-		my $test_address = $::SortedAddresses[$test_index];
-		last if ($prev_addr_end < $test_address);
-		print " $::Objects{$test_address}->{'type'}:$test_address";
-
-		$::Objects{$prev_addr}->{'overlap_count'}++;
-		$::Objects{$test_address}->{'overlap_count'}++;
-		my $overlap = $prev_addr_end - $test_address;
-		if ($overlap > $::Objects{$test_address}->{'size'}) {
-		    $overlap = $::Objects{$test_address}->{'size'};
-		}
-		print "($overlap bytes)";
-		$prev_addr_overlap_tally += $overlap;
-
-		$test_index++;
-	    }
-	    print " [total $prev_addr_overlap_tally bytes]";
-	    $overlap_tally += $prev_addr_overlap_tally;
-	    print "\n";
-	} 
-
-	$prev_addr = $address;
-	$prev_addr_end = $prev_addr + $::Objects{$prev_addr}->{'size'} - 1;
-	$index++;
-    } #end while
-    if ($overlap_tally) {
-	print "Total overlap of $overlap_tally bytes\n";
-    }
-}
-
-#----------------------------------------------------------------------
-#
-# Evaluate sizes of interobject spacing (fragmentation loss?)
-# Gather the sizes into histograms for analysis
-# This function assumes a sorted list of addresses is present globally
-
-sub generate_and_print_unused_memory_histogram() {
-    print "\nInterobject spacing (fragmentation waste) Statistics\n";
-    if ($::opt_fragment <= 1) {
-	print "Statistics are not being gathered.  Use '--fragment=10' to get stats\n";
-	return;
-    }
-    print "Ratio of histogram buckets will be a factor of $::opt_fragment\n";
-
-    my $prev_addr_end = -1;
-    my $prev_addr = -1;
-    my $index = 0;
-
-    my @fragment_count;
-    my @fragment_tally;
-    my $power;
-    my $bucket_size;
-
-    my $max_power = 0;
-
-    my $tally_sizes = 0;
-
-    while ($index <= $#::SortedAddresses) {
-	my $address = $::SortedAddresses[$index];
-
-	my $unused = $address - $prev_addr_end;
-
-	# handle overlaps gracefully
-	if ($unused < 0) {
-	    $unused = 0;
-	}
-
-	$power = 0;
-	$bucket_size = 1;
-	while ($bucket_size < $unused) {
-	    $bucket_size *= $::opt_fragment;
-	    $power++;
-	}
-	$fragment_count[$power]++;
-	$fragment_tally[$power] += $unused;
-	if ($power > $max_power) {
-	    $max_power = $power;
-	}
-	my $size = $::Objects{$address}->{'size'}; 
-	$tally_sizes += $size;
-	$prev_addr_end = $address + $size - 1;
-	$index++;
-    }
-
-
-    $power = 0;
-    $bucket_size = 1;
-    print "Basic gap histogram is (max_size:count):\n";
-    while ($power <= $max_power) {
-	if (! defined $fragment_count[$power]) {
-	    $fragment_count[$power] = $fragment_tally[$power] = 0;
-	}
-	printf " %.1f:", $bucket_size;
-	print $fragment_count[$power];
-	$power++;
-	$bucket_size *= $::opt_fragment;
-    }
-    print "\n";
-
-    print "Summary gap analysis:\n";
-
-    $power = 0;
-    $bucket_size = 1;
-    my $tally = 0;
-    my $count = 0;
-    while ($power <= $max_power) {
-	$count += $fragment_count[$power];
-	$tally += $fragment_tally[$power];
-	print "$count gaps, totaling $tally bytes, were under ";
-	printf "%.1f bytes each", $bucket_size;
-	if ($count) {
-	    printf ", for an average of %.1f bytes per gap", $tally/$count, ;
-	}
-	print "\n";
-	$power++;
-	$bucket_size *= $::opt_fragment;
-    }
-
-    print "Total allocation was $tally_sizes bytes, or ";
-    printf "%.0f bytes per allocation block\n\n", $tally_sizes/($count+1);
-    
-}
-
-#----------------------------------------------------------------------
-#
-# Now thread the parents and children together by looking through the
-# slots for each object.
-#
-sub create_parent_links(){
-    my $min_addr = $::SortedAddresses[0];
-    my $max_addr = $::SortedAddresses[ $#::SortedAddresses]; #allow one beyond each object
-    $max_addr += $::Objects{$max_addr}->{'size'};
-
-    print "Viable addresses range from $min_addr to $max_addr for a total of ", 
-    $max_addr-$min_addr, " bytes\n\n";
-
-    # Gather stats as we try to convert slots to children
-    my $slot_count = 0;   # total slots examined
-    my $fixed_addr_count = 0; # slots into interiors that were adjusted
-    my $parent_child_count = 0;  # Number of parent-child links
-    my $child_count = 0;   # valid slots, discounting sibling twins
-    my $child_dup_count = 0; # number of duplicate child pointers
-    my $self_pointer_count = 0; # count of discarded self-pointers
-
-    foreach my $parent (keys %::Objects) {
-	# We'll collect a list of this parent object's children
-	# by iterating through its slots.
-	my @children;
-	my %children_hash;
-	my $self_pointer = 0;
-
-	my @slots = @{$::Objects{$parent}->{'slots'}};
-	$slot_count += $#slots + 1;
-	SLOT: foreach my $child (@slots) {
-
-	    # We only care about pointers that refer to other objects
-	    if (! defined $::Objects{$child}) {
-		# check to see if we are an interior pointer
-
-		# Punt if we are completely out of range
-		next SLOT unless ($max_addr >= $child && 
-				  $child >= $min_addr);
-
-		# Do binary search to find object below this address
-		my ($min_index, $beyond_index) = (0, $#::SortedAddresses + 1);
-		my $test_index;
-		while ($min_index != 
-		       ($test_index = int (($beyond_index+$min_index)/2)))  {
-		    if ($child >= $::SortedAddresses[$test_index]) {
-			$min_index = $test_index;
-		    } else {
-			$beyond_index = $test_index;
-		    }
-		}
-		# See if pointer is within extent of this object
-		my $address = $::SortedAddresses[$test_index];
-		next SLOT unless ($child < 
-				  $address + $::Objects{$address}->{'size'});
-
-		# Make adjustment so we point to the actual child precisely
-		$child = $address;
-		$fixed_addr_count++;
-	    }
-
-	    if ($child == $parent) {
-		$self_pointer_count++;
-		next SLOT; # Discard self-pointers
-	    }
-
-	    # Avoid creating duplicate child-parent links
-	    if (! defined $children_hash{$child}) {
-		$parent_child_count++;
-		# Add the parent to the child's list of parents
-		my $parents = $::Objects{$child}->{'parents'};
-		if (! $parents) {
-		    $parents = $::Objects{$child}->{'parents'} = [];
-		}
-
-		$parents->[scalar(@$parents)] = $parent;
-
-		# Add the child to the parent's list of children
-		$children_hash{$child} = 1;
-	    } else {
-		$child_dup_count++;
-	    }
-	}
-	@children = keys %children_hash;
-	# Track tally of unique children linked
-	$child_count += $#children + 1;
-
-	$::Objects{$parent}->{'children'} = \@children;
-
-	if (! @children) {
-	    $::Leafs[$#::Leafs + 1] = $parent;
-	} 
-    }
-    print "Scanning $#::SortedAddresses objects, we found $parent_child_count parents-to-child connections by chasing $slot_count pointers.\n",
-    "This required $fixed_addr_count interior pointer fixups, skipping $child_dup_count duplicate pointers, ",
-    "and $self_pointer_count self pointers\nAlso discarded ", 
-    $slot_count - $parent_child_count -$self_pointer_count - $child_dup_count, 
-    " out-of-range pointers\n\n";
-}
-
-
-#----------------------------------------------------------------------
-# For every leaf, if a leaf has only one parent, then sweep the memory 
-# cost into the parent from the leaf
-sub sweep_leaf_memory () {
-    my $sweep_count = 0;
-    my $leaf_counter = 0;
-    LEAF: while ($leaf_counter <= $#::Leafs) {
-	my $leaf_addr = $::Leafs[$leaf_counter++];
-	my $leaf_obj = $::Objects{$leaf_addr};
-	my $parents = $leaf_obj->{'parents'};
-
-	next LEAF if (! defined($parents) || 1 != scalar(@$parents));
-
-	# We have only one parent, so we'll try to sweep upwards
-	my $parent_addr = @$parents[0];
-	my $parent_obj = $::Objects{$parent_addr};
-
-	# watch out for self-pointers
-	next LEAF if ($parent_addr == $leaf_addr); 
-
-	if ($::opt_detail) {
-	    foreach my $obj ($parent_obj, $leaf_obj) {
-		if (!defined $obj->{'original_size'}) {
-		    $obj->{'original_size'} = $obj->{'size'};
-		}
-	    }
-	    if (defined $leaf_obj->{'sweep_details'}) {
-		if (defined $parent_obj->{'sweep_details'}) { # merge details
-		    foreach my $swept_obj (keys (%{$leaf_obj->{'sweep_details'}})) {
-			%{$parent_obj->{'sweep_details'}}->{$swept_obj} = 
-			    %{$leaf_obj->{'sweep_details'}}->{$swept_obj};
-		    }
-		} else { # No parent info
-		    $parent_obj->{'sweep_details'} = \%{$leaf_obj->{'sweep_details'}};
-		}
-		delete $leaf_obj->{'sweep_details'};
-	    } else { # no leaf detail
-		if (!defined $parent_obj->{'sweep_details'}) {
-		    $parent_obj->{'sweep_details'} = {};
-		}
-	    }
-	    %{$parent_obj->{'sweep_details'}}->{$leaf_addr} = $leaf_obj->{'original_size'};
-	}
-
-	$parent_obj->{'size'} += $leaf_obj->{'size'};
-	$leaf_obj->{'size'} = 0;
-
-	if (defined ($leaf_obj->{'swept_in'})) {
-	    $parent_obj->{'swept_in'} += $leaf_obj->{'swept_in'};
-	    $leaf_obj->{'swept_in'} = 0;  # sweep has been handed off to parent
-	} 
-	$parent_obj->{'swept_in'} ++;  # tally swept in leaf_obj
-
-	$sweep_count++;
-
-	# See if we created another leaf
-	my $consumed_children = $parent_obj->{'consumed'}++;
-	my @children = $parent_obj->{'children'};
-	if ($consumed_children == $#children) {
-	    $::Leafs[$#::Leafs + 1] = @$parents[0];
-	}
-    }
-    print "Processed ", $leaf_counter, " leaves sweeping memory to parents in ", $sweep_count, " objects\n";
-}
-
-
-#----------------------------------------------------------------------
-#
-# Subdivide the types of objects that are in our "expand" list
-# List types that should be sub-divided based on parents, and possibly 
-# children
-# The argument supplied is a hash table with keys selecting types that
-# need to be "refined" by including the types of the parent objects,
-# and (when we are desparate) the types of the children objects.
-
-sub expand_type_names($) {
-    my %TypeExpand = %{$_[0]};
-
-    my @retype; # array of addrs that get extended type names
-    foreach my $child (keys %::Objects) {
-	my $child_obj = $::Objects{$child};
-	next unless (defined ($TypeExpand{$child_obj->{'type'}}));
-
-	foreach my $relation ('parents','children') {
-	    my $relatives = $child_obj->{$relation};
-	    next unless defined @$relatives;
-
-	    # Sort out the names of the types of the relatives
-	    my %names;
-	    foreach my $relative (@$relatives) {
-		%names->{$::Objects{$relative}->{'type'}} = 1;
-	    }
-	    my $related_type_names = join(',' , sort(keys(%names)));
-
-
-	    $child_obj->{'name' . $relation} = $related_type_names;
-
-	    # Don't bother with children if we have significant parent types 
-	    last if (!defined ($TypeExpand{$related_type_names}));
-	}
-	$retype[$#retype + 1] = $child;
-    }
-
-    # Revisit all addresses we've marked
-    foreach my $child (@retype) {
-	my $child_obj = $::Objects{$child};
-	$child_obj->{'type'} = $TypeExpand{$child_obj->{'type'}};
-	my $extended_type = $child_obj->{'namechildren'};
-	if (defined $extended_type) {
-	    $child_obj->{'type'}.= "->(" . $extended_type . ")";
-	    delete ($child_obj->{'namechildren'});
-	}
-	$extended_type = $child_obj->{'nameparents'};
-	if (defined $extended_type) {
-	    $child_obj->{'type'} = "(" . $extended_type . ")->" . $::Objects{$child}->{'type'};
-	    delete ($child_obj->{'nameparents'});
-	}
-    }
-}
-
-#----------------------------------------------------------------------
-#
-# Print out a type histogram
-
-sub print_type_histogram() {
-    load_type_table();
-    print_type_table();
-    print "\n\n";
-}
-
-
-#----------------------------------------------------------------------
-# Provide a nice summary of the types during the process
-validate_address_ranges();
-create_parent_links();
-
-print "\nBasic memory use histogram is:\n";
-print_type_histogram();
-
-generate_and_print_unused_memory_histogram();
-
-sweep_leaf_memory ();
-print "After doing basic leaf-sweep processing of instances:\n";
-print_type_histogram();
-
-{
-    foreach my $typename (@::opt_typedivide) {
-	my %expansion_table;
-	$expansion_table{$typename} = $typename;
-	expand_type_names(\%expansion_table);
-	print "After subdividing <$typename> based on inbound (and somtimes outbound) pointers:\n";
-	print_type_histogram();
-    }
-}
-
-exit();  # Don't bother with SCCs yet.
-
-
-#----------------------------------------------------------------------
-#
-# Determine objects that entrain equivalent sets, using the strongly
-# connected component algorithm from Cormen, Leiserson, and Rivest,
-# ``An Introduction to Algorithms'', MIT Press 1990, pp. 488-493.
-#
-sub compute_post_order($$$) {
-# This routine produces a post-order of the call graph (what CLR call
-# ``ordering the nodes by f[u]'')
-    my ($parent, $visited, $finish) = @_;
-
-    # Bail if we've already seen this node
-    return if $visited->{$parent};
-
-    # We have now!
-    $visited->{$parent} = 1;
-
-    # Walk the children
-    my $children = $::Objects{$parent}->{'children'};
-
-    foreach my $child (@$children) {
-        compute_post_order($child, $visited, $finish);
-    }
-
-    # Now that we've walked all the kids, we can append the parent to
-    # the post-order
-    @$finish[scalar(@$finish)] = $parent;
-}
-
-sub compute_equivalencies($$$) {
-# This routine recursively computes equivalencies by walking the
-# transpose of the callgraph.
-    my ($child, $table, $equivalencies) = @_;
-
-    # Bail if we've already seen this node
-    return if $table->{$child};
-
-    # Otherwise, append ourself to the list of equivalencies...
-    @$equivalencies[scalar(@$equivalencies)] = $child;
-
-    # ...and note our other equivalents in the table
-    $table->{$child} = $equivalencies;
-
-    my $parents = $::Objects{$child}->{'parents'};
-
-    foreach my $parent (@$parents) {
-        compute_equivalencies($parent, $table, $equivalencies);
-    }
-}
-
-sub compute_equivalents() {
-# Here's the strongly connected components algorithm. (Step 2 has been
-# done implictly by our object graph construction.)
-    my %visited;
-    my @finish;
-
-    # Step 1. Compute a post-ordering of the object graph
-    foreach my $parent (keys %::Objects) {
-        compute_post_order($parent, \%visited, \@finish);
-    }
-
-    # Step 3. Traverse the transpose of the object graph in reverse
-    # post-order, collecting vertices into %equivalents
-    my %equivalents;
-    foreach my $child (reverse @finish) {
-        compute_equivalencies($child, \%equivalents, []);
-    }
-
-    # Now, we'll trim the %equivalents table, arbitrarily removing
-    # ``redundant'' entries.
-  EQUIVALENT: foreach my $node (keys %equivalents) {
-      my $equivalencies = $equivalents{$node};
-      next EQUIVALENT unless $equivalencies;
-
-      foreach my $equivalent (@$equivalencies) {
-          delete $equivalents{$equivalent} unless $equivalent == $node;
-      }
-  }
-
-     # Note the equivalent objects in a way that will yield the most
-     # interesting order as we do depth-first traversal later to
-     # output them.
-  ROOT: foreach my $equivalent (reverse @finish) {
-      next ROOT unless $equivalents{$equivalent};
-      $::Equivalents[$#::Equivalents + 1] = $equivalent;
-
-      # XXX Lame! Should figure out function refs.
-      $::Objects{$equivalent}->{'entrained-size'} = 0;
-  }
-}
-
-# Do it!
-compute_equivalents();
-
-
-#----------------------------------------------------------------------
-#
-# Compute the size of each node's transitive closure.
-#
-sub compute_entrained($$) {
-    my ($parent, $visited) = @_;
-
-    $visited->{$parent} = 1;
-
-    $::Objects{$parent}->{'entrained-size'} = $::Objects{$parent}->{'size'};
-
-    my $children = $::Objects{$parent}->{'children'};
-    CHILD: foreach my $child (@$children) {
-        next CHILD if $visited->{$child};
-
-        compute_entrained($child, $visited);
-        $::Objects{$parent}->{'entrained-size'} += $::Objects{$child}->{'entrained-size'};
-    }
-}
-
-if (! $::opt_noentrained) {
-    my %visited;
-
-  PARENT: foreach my $parent (@::Equivalents) {
-      next PARENT if $visited{$parent};
-      compute_entrained($parent, \%visited);
-  }
-}
-
-
-#----------------------------------------------------------------------
-#
-# Converts a shared library and an address into a file and line number
-# using a bunch of addr2line processes.
-#
-sub addr2line($$) {
-    my ($dso, $addr) = @_;
-
-    # $::Addr2Lines is a global table that maps a DSO's name to a pair
-    # of filehandles that are talking to an addr2line process.
-    my $fhs = $::Addr2Lines{$dso};
-    if (! $fhs) {
-        if (!(-r $dso)) {
-            # bogus filename (that happens sometimes), so bail
-            return { 'dso' => $dso, 'addr' => $addr };
-        }
-        my ($in, $out) = (new FileHandle, new FileHandle);
-        open2($in, $out, "addr2line --exe=$dso") || die "unable to open addr2line --exe=$dso";
-        $::Addr2Lines{$dso} = $fhs = { 'in' => $in, 'out' => $out };
-    }
-
-    # addr2line takes a hex address as input...
-    $fhs->{'out'}->print($addr . "\n");
-
-    # ...and'll return file:lineno as output
-    if ($fhs->{'in'}->getline() =~ /([^:]+):(.+)/) {
-        return { 'file' => $1, 'line' => $2 };
-    }
-    else {
-        return { 'dso' => $dso, 'addr' => $addr };
-    }
-}
-
-
-#----------------------------------------------------------------------
-#
-# Dump the objects, using a depth-first traversal.
-#
-sub dump_objects($$$) {
-    my ($parent, $visited, $depth) = @_;
-    
-    # Have we already seen this?
-    my $already_visited = $visited->{$parent};
-    return if ($depth == 0 && $already_visited);
-
-    if (! $already_visited) {
-        $visited->{$parent} = 1;
-        $::Total += $::Objects{$parent}->{'size'};
-    }
-
-    my $parententry = $::Objects{$parent};
-
-    # Make an ``object'' div, which'll contain an ``object'' span, two
-    # ``toggle'' spans, an invisible ``stack'' div, and the invisible
-    # ``children'' div.
-    print "<div class='object'>";
-
-    if ($already_visited) {
-        print "<a href='#$parent'>";
-    }
-    else {
-        print "<span id='$parent' class='object";
-        print " root" if $depth == 0;
-        print "'>";
-    }
-
-    printf "0x%x&lt;%s&gt;[%d]", $parent, $parententry->{'type'}, $parententry->{'size'};
-
-    if ($already_visited) {
-        print "</a>";
-        goto DONE;
-    }
-        
-    if ($depth == 0) {
-        print "($parententry->{'entrained-size'})"
-            if $parententry->{'entrained-size'};
-
-        print "&nbsp;<span class='toggle' onclick='toggleDisplay(this.parentNode.nextSibling.nextSibling);'>Children</span>"
-            if @{$parententry->{'children'}} > 0;
-    }
-
-    if (($depth == 0 || !$::opt_nochildstacks) && !$::opt_nostacks) {
-        print "&nbsp;<span class='toggle' onclick='toggleDisplay(this.parentNode.nextSibling);'>Stack</span>";
-    }
-
-    print "</span>";
-
-    # Print stack traces
-    print "<div class='stack'>\n";
-
-    if (($depth == 0 || !$::opt_nochildstacks) && !$::opt_nostacks) {
-        my $depth = $::opt_depth;
-
-      FRAME: foreach my $frame (@{$parententry->{'stack'}}) {
-          # Only go as deep as they've asked us to.
-          last FRAME unless --$depth >= 0;
-
-          # Stack frames look like ``mangled_name[dso address]''
-          $frame =~ /([^\]]+)\[(.*) \+0x([0-9A-Fa-f]+)\]/;
-
-          # Convert address to file and line number
-          my $mangled = $1;
-          my $result = addr2line($2, $3);
-
-          if ($result->{'file'}) {
-              # It's mozilla source! Clean up refs to dist/include
-              if (($result->{'file'} =~ s/.*\.\.\/\.\.\/dist\/include\//http:\/\/bonsai.mozilla.org\/cvsguess.cgi\?file=/) ||
-                  ($result->{'file'} =~ s/.*\/mozilla/http:\/\/bonsai.mozilla.org\/cvsblame.cgi\?file=mozilla/)) {
-                  my $prevline = $result->{'line'} - 10;
-                  print "<a target=\"lxr_source\" href=\"$result->{'file'}\&mark=$result->{'line'}#$prevline\">$mangled</a><br>\n";
-              }
-              else {
-                  print "$mangled ($result->{'file'}, line $result->{'line'})<br>\n";
-              }
-          }
-          else {
-              print "$result->{'dso'} ($result->{'addr'})<br>\n";
-          }
-      }
-
-    }
-
-    print "</div>";
-
-    # Recurse to children
-    if (@{$parententry->{'children'}} >= 0) {
-        print "<div class='children'>\n" if $depth == 0;
-
-        foreach my $child (@{$parententry->{'children'}}) {
-            dump_objects($child, $visited, $depth + 1);
-        }
-
-        print "</div>" if $depth == 0;
-    }
-
-  DONE:
-    print "</div>\n";
-}
-
-
-#----------------------------------------------------------------------
-#
-# Do the output.
-#
-
-# Force flush on STDOUT. We get funky output unless we do this.
-$| = 1;
-
-# Header
-print "<html>
-<head>
-<title>Object Graph</title>
-<style type='text/css'>
-    body { font: medium monospace; background-color: white; }
-
-    /* give nested div's some margins to make it look like a tree */
-    div.children > div.object { margin-left: 1em; }
-    div.object > div.object { margin-left: 1em; }
-
-    /* Indent stacks, too */
-    div.object > div.stack { margin-left: 3em; }
-
-    /* apply font decorations to special ``object'' spans */
-    span.object { font-weight: bold; color: darkgrey; }
-    span.object.root { color: black; }
-
-    /* hide ``stack'' divs by default; JS will show them */
-    div.stack { display: none; }
-
-    /* hide ``children'' divs by default; JS will show them */
-    div.children { display: none; }
-
-    /* make ``toggle'' spans look like links */
-    span.toggle { color: blue; text-decoration: underline; cursor: pointer; }
-    span.toggle:active { color: red; }
-</style>
-<script language='JavaScript'>
-function toggleDisplay(element)
-{
-    element.style.display = (element.style.display == 'block') ? 'none' : 'block';
-}
-</script>
-</head>
-<body>
-";
-
-{
-# Body. Display ``roots'', sorted by the amount of memory they
-# entrain. Because of the way we've sorted @::Equivalents, we should
-# get a nice ordering that sorts things with a lot of kids early
-# on. This should yield a fairly "deep" depth-first traversal, with
-# most of the objects appearing as children.
-#
-# XXX I sure hope that Perl implements a stable sort!
-    my %visited;
-
-    foreach my $parent (sort { $::Objects{$b}->{'entrained-size'}
-                               <=> $::Objects{$a}->{'entrained-size'} }
-                        @::Equivalents) {
-        dump_objects($parent, \%visited, 0);
-        print "\n";
-    }
-}
-
-# Footer
-print "<br> $::Total total bytes\n" if $::Total;
-print "</body>
-</html>
-";
-
deleted file mode 100644
--- a/tools/trace-malloc/leaksoup.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "adreader.h"
-
-#include <stdio.h>
-#include "plhash.h"
-
-#include "nsTArray.h"
-#include "nsQuickSort.h"
-#include "nsXPCOM.h"
-
-const uint32_t kPointersDefaultSize = 8;
-
-/*
- * Read in an allocation dump, presumably one taken at shutdown (using
- * the --shutdown-leaks=file option, which must be used along with
- * --trace-malloc=tmlog), and treat the memory in the dump as leaks.
- * Find the leak roots, including cycles that are roots, by finding the
- * strongly connected components in the graph.  Print output to stdout
- * as HTML.
- */
-
-struct AllocationNode {
-    const ADLog::Entry *entry;
-
-    // Other |AllocationNode| objects whose memory has a pointer to
-    // this object.
-    nsAutoTArray<AllocationNode*, kPointersDefaultSize> pointers_to;
-
-    // The reverse.
-    nsAutoTArray<AllocationNode*, kPointersDefaultSize> pointers_from;
-
-    // Early on in the algorithm, the pre-order index from a DFS.
-    // Later on, set to the index of the strongly connected component to
-    // which this node belongs.
-    uint32_t index;
-
-    bool reached;
-    bool is_root;
-};
-
-static PLHashNumber hash_pointer(const void *key)
-{
-    return (PLHashNumber) NS_PTR_TO_INT32(key);
-}
-
-static int sort_by_index(const void* e1, const void* e2, void*)
-{
-    const AllocationNode *n1 = *static_cast<const AllocationNode*const*>(e1);
-    const AllocationNode *n2 = *static_cast<const AllocationNode*const*>(e2);
-    return n1->index - n2->index;
-}
-
-static int sort_by_reverse_index(const void* e1, const void* e2, void*)
-{
-    const AllocationNode *n1 = *static_cast<const AllocationNode*const*>(e1);
-    const AllocationNode *n2 = *static_cast<const AllocationNode*const*>(e2);
-    return n2->index - n1->index;
-}
-
-static void print_escaped(FILE *aStream, const char* aData)
-{
-    char c;
-    char buf[1000];
-    char *p = buf;
-    while ((c = *aData++)) {
-        switch (c) {
-#define CH(char) *p++ = char
-            case '<':
-                CH('&'); CH('l'); CH('t'); CH(';');
-                break;
-            case '>':
-                CH('&'); CH('g'); CH('t'); CH(';');
-                break;
-            case '&':
-                CH('&'); CH('a'); CH('m'); CH('p'); CH(';');
-                break;
-            default:
-                CH(c);
-                break;
-#undef CH
-        }
-        if (p + 10 > buf + sizeof(buf)) {
-            *p = '\0';
-            fputs(buf, aStream);
-            p = buf;
-        }
-    }
-    *p = '\0';
-    fputs(buf, aStream);
-}
-
-static const char *allocation_format =
-  (sizeof(ADLog::Pointer) == 4) ? "0x%08zX" :
-  (sizeof(ADLog::Pointer) == 8) ? "0x%016zX" :
-  "UNEXPECTED sizeof(void*)";
-
-int main(int argc, char **argv)
-{
-    if (argc != 2) {
-        fprintf(stderr,
-                "Expected usage:  %s <sd-leak-file>\n"
-                "  sd-leak-file: Output of --shutdown-leaks=<file> option.\n",
-                argv[0]);
-        return 1;
-    }
-
-    NS_InitXPCOM2(nullptr, nullptr, nullptr);
-
-    ADLog log;
-    if (!log.Read(argv[1])) {
-        fprintf(stderr,
-                "%s: Error reading input file %s.\n", argv[0], argv[1]);
-    }
-
-    const size_t count = log.count();
-
-    PLHashTable *memory_map =
-        PL_NewHashTable(count * 8, hash_pointer, PL_CompareValues,
-                        PL_CompareValues, 0, 0);
-    if (!memory_map) {
-        fprintf(stderr, "%s: Out of memory.\n", argv[0]);
-        return 1;
-    }
-
-    // Create one |AllocationNode| object for each log entry, and create
-    // entries in the hashtable pointing to it for each byte it occupies.
-    AllocationNode *nodes = new AllocationNode[count];
-    if (!nodes) {
-        fprintf(stderr, "%s: Out of memory.\n", argv[0]);
-        return 1;
-    }
-
-    {
-        AllocationNode *cur_node = nodes;
-        for (ADLog::const_iterator entry = log.begin(), entry_end = log.end();
-             entry != entry_end; ++entry, ++cur_node) {
-            const ADLog::Entry *e = cur_node->entry = *entry;
-            cur_node->reached = false;
-
-            for (ADLog::Pointer p = e->address,
-                            p_end = e->address + e->datasize;
-                 p != p_end; ++p) {
-                PLHashEntry *he = PL_HashTableAdd(memory_map, p, cur_node);
-                if (!he) {
-                    fprintf(stderr, "%s: Out of memory.\n", argv[0]);
-                    return 1;
-                }
-            }
-        }
-    }
-
-    // Construct graph based on pointers.
-    for (AllocationNode *node = nodes, *node_end = nodes + count;
-         node != node_end; ++node) {
-        const ADLog::Entry *e = node->entry;
-        for (const char *d = e->data, *d_end = e->data + e->datasize -
-                                         e->datasize % sizeof(ADLog::Pointer);
-             d != d_end; d += sizeof(ADLog::Pointer)) {
-            AllocationNode *target = (AllocationNode*)
-                PL_HashTableLookup(memory_map, *(void**)d);
-            if (target) {
-                target->pointers_from.AppendElement(node);
-                node->pointers_to.AppendElement(target);
-            }
-        }
-    }
-
-    // Do a depth-first search on the graph (i.e., by following
-    // |pointers_to|) and assign the post-order index to |index|.
-    {
-        uint32_t dfs_index = 0;
-        nsTArray<AllocationNode*> stack;
-
-        for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) {
-            if (n->reached) {
-                continue;
-            }
-            stack.AppendElement(n);
-
-            do {
-                uint32_t pos = stack.Length() - 1;
-                AllocationNode *n = stack[pos];
-                if (n->reached) {
-                    n->index = dfs_index++;
-                    stack.RemoveElementAt(pos);
-                } else {
-                    n->reached = true;
-
-                    // When doing post-order processing, we have to be
-                    // careful not to put reached nodes into the stack.
-                    for (int32_t i = n->pointers_to.Length() - 1; i >= 0; --i) {
-                        AllocationNode* e = n->pointers_to[i];
-                        if (!e->reached) {
-                            stack.AppendElement(e);
-                        }
-                    }
-                }
-            } while (stack.Length() > 0);
-        }
-    }
-
-    // Sort the nodes by their DFS index, in reverse, so that the first
-    // node is guaranteed to be in a root SCC.
-    AllocationNode **sorted_nodes = new AllocationNode*[count];
-    if (!sorted_nodes) {
-        fprintf(stderr, "%s: Out of memory.\n", argv[0]);
-        return 1;
-    }
-
-    {
-        for (size_t i = 0; i < count; ++i) {
-            sorted_nodes[i] = nodes + i;
-        }
-        NS_QuickSort(sorted_nodes, count, sizeof(AllocationNode*),
-                     sort_by_reverse_index, 0);
-    }
-
-    // Put the nodes into their strongly-connected components.
-    uint32_t num_sccs = 0;
-    {
-        for (size_t i = 0; i < count; ++i) {
-            nodes[i].reached = false;
-        }
-        nsTArray<AllocationNode*> stack;
-        for (AllocationNode **sn = sorted_nodes,
-                        **sn_end = sorted_nodes + count; sn != sn_end; ++sn) {
-            if ((*sn)->reached) {
-                continue;
-            }
-
-            // We found a new strongly connected index.
-            stack.AppendElement(*sn);
-            do {
-                uint32_t pos = stack.Length() - 1;
-                AllocationNode *n = stack[pos];
-                stack.RemoveElementAt(pos);
-
-                if (!n->reached) {
-                    n->reached = true;
-                    n->index = num_sccs;
-                    stack.AppendElements(n->pointers_from);
-                }
-            } while (stack.Length() > 0);
-            ++num_sccs;
-        }
-    }
-
-    // Identify which nodes are leak roots by using DFS, and watching
-    // for component transitions.
-    uint32_t num_root_nodes = count;
-    {
-        for (size_t i = 0; i < count; ++i) {
-            nodes[i].is_root = true;
-        }
-
-        nsTArray<AllocationNode*> stack;
-        for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) {
-            if (!n->is_root) {
-                continue;
-            }
-
-            // Loop through pointers_to, and add any that are in a
-            // different SCC to stack:
-            for (int i = n->pointers_to.Length() - 1; i >= 0; --i) {
-                AllocationNode *target = n->pointers_to[i];
-                if (n->index != target->index) {
-                    stack.AppendElement(target);
-                }
-            }
-
-            while (stack.Length() > 0) {
-                uint32_t pos = stack.Length() - 1;
-                AllocationNode *n = stack[pos];
-                stack.RemoveElementAt(pos);
-
-                if (n->is_root) {
-                    n->is_root = false;
-                    --num_root_nodes;
-                    stack.AppendElements(n->pointers_to);
-                }
-            }
-        }
-    }
-
-    // Sort the nodes by their SCC index.
-    NS_QuickSort(sorted_nodes, count, sizeof(AllocationNode*),
-                 sort_by_index, 0);
-
-    // Print output.
-    {
-        printf("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n"
-               "<html>\n"
-               "<head>\n"
-               "<title>Leak analysis</title>\n"
-               "<style type=\"text/css\">\n"
-               "  .root { background: white; color: black; }\n"
-               "  .nonroot { background: #ccc; color: black; }\n"
-               "</style>\n"
-               "</head>\n");
-        printf("<body>\n\n"
-               "<p>Generated %zd entries (%d in root SCCs) and %d SCCs.</p>\n\n",
-               count, num_root_nodes, num_sccs);
-
-        for (size_t i = 0; i < count; ++i) {
-            nodes[i].reached = false;
-        }
-
-        // Loop over the sorted nodes twice, first printing the roots
-        // and then the non-roots.
-        for (int32_t root_type = true;
-             root_type == true || root_type == false; --root_type) {
-            if (root_type) {
-                printf("\n\n"
-                       "<div class=\"root\">\n"
-                       "<h1 id=\"root\">Root components</h1>\n");
-            } else {
-                printf("\n\n"
-                       "<div class=\"nonroot\">\n"
-                       "<h1 id=\"nonroot\">Non-root components</h1>\n");
-            }
-            uint32_t component = (uint32_t)-1;
-            bool one_object_component;
-            for (const AllocationNode *const* sn = sorted_nodes,
-                                  *const* sn_end = sorted_nodes + count;
-                 sn != sn_end; ++sn) {
-                const AllocationNode *n = *sn;
-                if (n->is_root != root_type)
-                    continue;
-                const ADLog::Entry *e = n->entry;
-
-                if (n->index != component) {
-                    component = n->index;
-                    one_object_component =
-                        sn + 1 == sn_end || (*(sn+1))->index != component;
-                    if (!one_object_component)
-                        printf("\n\n<h2 id=\"c%d\">Component %d</h2>\n",
-                               component, component);
-                }
-
-                if (one_object_component) {
-                    printf("\n\n<div id=\"c%d\">\n", component);
-                    printf("<h2 id=\"o%td\">Object %td "
-                           "(single-object component %d)</h2>\n",
-                           n-nodes, n-nodes, component);
-                } else {
-                    printf("\n\n<h3 id=\"o%td\">Object %td</h3>\n",
-                           n-nodes, n-nodes);
-                }
-                printf("<pre>\n");
-                printf("%p &lt;%s&gt; (%zd)\n",
-                       e->address, e->type, e->datasize);
-                for (size_t d = 0; d < e->datasize;
-                     d += sizeof(ADLog::Pointer)) {
-                    AllocationNode *target = (AllocationNode*)
-                        PL_HashTableLookup(memory_map, *(void**)(e->data + d));
-                    if (target) {
-                        printf("        <a href=\"#o%td\">",
-                               target - nodes);
-                        printf(allocation_format,
-                               *(size_t*)(e->data + d));
-                        printf("</a> &lt;%s&gt;",
-                               target->entry->type);
-                        if (target->index != n->index) {
-                            printf(", component %d", target->index);
-                        }
-                        printf("\n");
-                    } else {
-                        printf("        ");
-                        printf(allocation_format,
-                               *(size_t*)(e->data + d));
-                        printf("\n");
-                    }
-                }
-
-                if (n->pointers_from.Length()) {
-                    printf("\nPointers from:\n");
-                    for (uint32_t i = 0, i_end = n->pointers_from.Length();
-                         i != i_end; ++i) {
-                        AllocationNode *t = n->pointers_from[i];
-                        const ADLog::Entry *te = t->entry;
-                        printf("    <a href=\"#o%td\">%s</a> (Object %td, ",
-                               t - nodes, te->type, t - nodes);
-                        if (t->index != n->index) {
-                            printf("component %d, ", t->index);
-                        }
-                        if (t == n) {
-                            printf("self)\n");
-                        } else {
-                            printf("%p)\n", te->address);
-                        }
-                    }
-                }
-
-                print_escaped(stdout, e->allocation_stack);
-
-                printf("</pre>\n");
-                if (one_object_component) {
-                    printf("</div>\n");
-                }
-            }
-            printf("</div>\n");
-        }
-        printf("</body>\n"
-               "</html>\n");
-    }
-
-    delete [] sorted_nodes;
-    delete [] nodes;
-
-    NS_ShutdownXPCOM(nullptr);
-
-    return 0;
-}
deleted file mode 100644
--- a/tools/trace-malloc/leakstats.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-extern int  getopt(int argc, char *const *argv, const char *shortopts);
-extern char *optarg;
-extern int  optind;
-#ifdef XP_WIN32
-int optind=1;
-#endif
-#endif
-#include <time.h>
-#include "nsTraceMalloc.h"
-#include "tmreader.h"
-#include "prlog.h"
-
-static char *program;
-
-typedef struct handler_data {
-    uint32_t current_heapsize;
-    uint32_t max_heapsize;
-    uint32_t bytes_allocated;
-    uint32_t current_allocations;
-    uint32_t total_allocations;
-    uint32_t unmatched_frees;
-    int finished;
-} handler_data;
-
-static void handler_data_init(handler_data *data)
-{
-    data->current_heapsize = 0;
-    data->max_heapsize = 0;
-    data->bytes_allocated = 0;
-    data->current_allocations = 0;
-    data->total_allocations = 0;
-    data->unmatched_frees = 0;
-    data->finished = 0;
-}
-
-static void handler_data_finish(handler_data *data)
-{
-}
-
-static void my_tmevent_handler(tmreader *tmr, tmevent *event)
-{
-    handler_data *data = (handler_data*) tmr->data;
-
-    switch (event->type) {
-      case TM_EVENT_REALLOC:
-        /* On Windows, original allocation could be before we overrode malloc */
-        if (event->u.alloc.oldserial != 0) {
-          data->current_heapsize -= event->u.alloc.oldsize;
-          --data->current_allocations;
-        } else {
-          ++data->unmatched_frees;
-          PR_ASSERT(event->u.alloc.oldsize == 0);
-        }
-        /* fall-through intentional */
-      case TM_EVENT_MALLOC:
-      case TM_EVENT_CALLOC:
-        ++data->current_allocations;
-        ++data->total_allocations;
-        data->bytes_allocated += event->u.alloc.size;
-        data->current_heapsize += event->u.alloc.size;
-        if (data->current_heapsize > data->max_heapsize)
-            data->max_heapsize = data->current_heapsize;
-        break;
-      case TM_EVENT_FREE:
-        /* On Windows, original allocation could be before we overrode malloc */
-        if (event->serial != 0) {
-          --data->current_allocations;
-          data->current_heapsize -= event->u.alloc.size;
-        } else {
-          ++data->unmatched_frees;
-          PR_ASSERT(event->u.alloc.size == 0);
-        }
-        break;
-      case TM_EVENT_STATS:
-        data->finished = 1;
-        break;
-    }
-}
-
-
-int main(int argc, char **argv)
-{
-    int i, j, rv;
-    tmreader *tmr;
-    FILE *fp;
-    time_t start;
-    handler_data data;
-
-    program = *argv;
-
-    handler_data_init(&data);
-    tmr = tmreader_new(program, &data);
-    if (!tmr) {
-        perror(program);
-        exit(1);
-    }
-
-    start = time(NULL);
-    fprintf(stdout, "%s starting at %s", program, ctime(&start));
-    fflush(stdout);
-
-    argc -= optind;
-    argv += optind;
-    if (argc == 0) {
-        if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0)
-            exit(1);
-    } else {
-        for (i = j = 0; i < argc; i++) {
-            fp = fopen(argv[i], "r");
-            if (!fp) {
-                fprintf(stderr,
-                        "TEST-UNEXPECTED-FAIL | leakstats | can't open %s: %s\n",
-                        argv[i], strerror(errno));
-                exit(1);
-            }
-            rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler);
-            if (rv < 0)
-                exit(1);
-            if (rv > 0)
-                j++;
-            fclose(fp);
-        }
-        if (j == 0)
-            exit(1);
-    }
-    
-    if (!data.finished) {
-        fprintf(stderr, "TEST-UNEXPECTED-FAIL | leakstats | log file incomplete\n");
-        exit(1);
-    }
-
-    fprintf(stdout,
-            "Leaks: %u bytes, %u allocations\n"
-            "Maximum Heap Size: %u bytes\n"
-            "%u bytes were allocated in %u allocations.\n",
-            data.current_heapsize, data.current_allocations,
-            data.max_heapsize,
-            data.bytes_allocated, data.total_allocations);
-    if (data.unmatched_frees != 0)
-        fprintf(stdout,
-                "Logged %u free (or realloc) calls for which we missed the "
-                "original malloc.\n",
-                data.unmatched_frees);
-
-    handler_data_finish(&data);
-    tmreader_destroy(tmr);
-
-    exit(0);
-}
deleted file mode 100644
--- a/tools/trace-malloc/lib/moz.build
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
-    'nsTraceMalloc.h',
-]
-
-SOURCES += [
-    'nsTraceMalloc.c',
-]
-
-SOURCES += [
-    'nsTypeInfo.cpp',
-]
-
-if CONFIG['OS_ARCH'] == 'WINNT':
-    SOURCES += [
-        'nsDebugHelpWin32.cpp',
-        'nsWinTraceMalloc.cpp',
-    ]
-
-FINAL_LIBRARY = 'xul'
-
-if CONFIG['WRAP_SYSTEM_INCLUDES']:
-    DEFINES['WRAP_SYSTEM_INCLUDES'] = True
-
-DEFINES['MOZ_NO_MOZALLOC'] = True
-
-DEFFILE = SRCDIR + '/tm.def'
-
-DISABLE_STL_WRAPPING = True
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsDebugHelpWin32.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
-// This is the .cpp file where the globals live
-#define DHW_IMPLEMENT_GLOBALS
-#include <stdio.h>
-#include "prprf.h"
-#include "prlog.h"
-#include "plstr.h"
-#include "prlock.h"
-#include "nscore.h"
-#include "nsDebugHelpWin32.h"
-#else
-#error "nsDebugHelpWin32.cpp should only be built in Win32 x86/x64 builds"
-#endif
-
-
-
-/***************************************************************************/
-
-
-PRLock*           DHWImportHooker::gLock  = nullptr;
-DHWImportHooker*  DHWImportHooker::gHooks = nullptr;
-decltype(GetProcAddress)* DHWImportHooker::gRealGetProcAddress = nullptr;
-
-
-static bool
-dhwEnsureImageHlpInitialized()
-{
-  static bool gInitialized = false;
-  static bool gTried       = false;
-
-  if (!gInitialized && !gTried) {
-    gTried = true;
-    HMODULE module = ::LoadLibrary("DBGHELP.DLL");
-    if (!module) {
-      DWORD dw = GetLastError();
-      printf("DumpStack Error: DBGHELP.DLL wasn't found. GetLastError() returned 0x%8.8X\n"
-             "                 This DLL is needed for succeessfully implementing trace-malloc.\n"
-             "                 This dll ships by default on Win2k. Disabling trace-malloc functionality.\n"
-             , dw);
-      return false;
-    }
-
-#define INIT_PROC(typename_, name_) \
-    dhw##name_ = (decltype(name_)*) ::GetProcAddress(module, #name_); \
-    if(!dhw##name_) return false;
-
-#ifdef _WIN64
-    INIT_PROC(ENUMERATELOADEDMODULES64, EnumerateLoadedModules64);
-#else
-    INIT_PROC(ENUMERATELOADEDMODULES, EnumerateLoadedModules);
-#endif
-    INIT_PROC(IMAGEDIRECTORYENTRYTODATA, ImageDirectoryEntryToData);
-
-#undef INIT_PROC
-
-    gInitialized = true;
-  }
-
-  return gInitialized;
-} 
-
-
-DHWImportHooker&
-DHWImportHooker::getGetProcAddressHooker()
-{
-  static DHWImportHooker gGetProcAddress("Kernel32.dll", "GetProcAddress",
-                                           (PROC)DHWImportHooker::GetProcAddress);
-  return gGetProcAddress;
-}
- 
-
-DHWImportHooker&
-DHWImportHooker::getLoadLibraryWHooker()
-{
-  static DHWImportHooker gLoadLibraryW("Kernel32.dll", "LoadLibraryW",
-                                         (PROC)DHWImportHooker::LoadLibraryW);
-  return gLoadLibraryW;
-}
-
-DHWImportHooker&
-DHWImportHooker::getLoadLibraryExWHooker()
-{
-  static DHWImportHooker gLoadLibraryExW("Kernel32.dll", "LoadLibraryExW",
-                                         (PROC)DHWImportHooker::LoadLibraryExW);
-  return gLoadLibraryExW;
-}
-
-DHWImportHooker&
-DHWImportHooker::getLoadLibraryAHooker()
-{
-  static DHWImportHooker gLoadLibraryA("Kernel32.dll", "LoadLibraryA",
-                                         (PROC)DHWImportHooker::LoadLibraryA);
-  return gLoadLibraryA;
-}
-
-DHWImportHooker&
-DHWImportHooker::getLoadLibraryExAHooker()
-{
-  static DHWImportHooker gLoadLibraryExA("Kernel32.dll", "LoadLibraryExA",
-                                           (PROC)DHWImportHooker::LoadLibraryExA);
-  return gLoadLibraryExA;
-}
-
-
-static HMODULE ThisModule()
-{
-    MEMORY_BASIC_INFORMATION info;
-    return VirtualQuery(ThisModule, &info, sizeof(info)) ? 
-                            (HMODULE) info.AllocationBase : nullptr;
-}
-
-DHWImportHooker::DHWImportHooker(const char* aModuleName,
-                                 const char* aFunctionName,
-                                 PROC aHook,
-                                 bool aExcludeOurModule /* = false */)
-    :   mNext(nullptr),
-        mModuleName(aModuleName),
-        mFunctionName(aFunctionName),
-        mOriginal(nullptr),
-        mHook(aHook),
-        mIgnoreModule(aExcludeOurModule ? ThisModule() : nullptr),
-        mHooking(true)
-{
-    //printf("DHWImportHooker hooking %s, function %s\n",aModuleName, aFunctionName);
-
-    if(!gLock)
-        gLock = PR_NewLock();
-    PR_Lock(gLock);
-
-    dhwEnsureImageHlpInitialized(); // for the extra ones we care about.
-
-    if(!gRealGetProcAddress)
-        gRealGetProcAddress = ::GetProcAddress;
-
-    mOriginal = gRealGetProcAddress(::GetModuleHandleA(aModuleName), 
-                                    aFunctionName),
- 
-    mNext = gHooks;
-    gHooks = this;
-
-    PatchAllModules();
-
-    PR_Unlock(gLock);
-}   
-
-DHWImportHooker::~DHWImportHooker()
-{
-    PR_Lock(gLock);
-
-    mHooking = false;
-    PatchAllModules();
-
-    for (DHWImportHooker **cur = &gHooks;
-         (PR_ASSERT(*cur), *cur); /* assert that we find this */
-         cur = &(*cur)->mNext)
-    {
-        if (*cur == this)
-        {
-            *cur = mNext;
-            break;
-        }
-    }
-
-    if(!gHooks)
-    {
-        PRLock* theLock = gLock;
-        gLock = nullptr;
-        PR_Unlock(theLock);
-        PR_DestroyLock(theLock);
-    }
-    if (gLock)
-        PR_Unlock(gLock);
-}    
-
-#ifdef _WIN64
-static BOOL CALLBACK ModuleEnumCallback(PCSTR ModuleName,
-                                        DWORD64 ModuleBase,
-                                        ULONG ModuleSize,
-                                        PVOID UserContext)
-#else
-static BOOL CALLBACK ModuleEnumCallback(PCSTR ModuleName,
-                                        ULONG ModuleBase,
-                                        ULONG ModuleSize,
-                                        PVOID UserContext)
-#endif
-{
-    //printf("Module Name %s\n",ModuleName);
-    DHWImportHooker* self = (DHWImportHooker*) UserContext;
-    HMODULE aModule = (HMODULE) ModuleBase;
-    return self->PatchOneModule(aModule, ModuleName);
-}
-
-bool 
-DHWImportHooker::PatchAllModules()
-{
-    // Need to cast to PENUMLOADED_MODULES_CALLBACK because the
-    // constness of the first parameter of PENUMLOADED_MODULES_CALLBACK
-    // varies over SDK versions (from non-const to const over time).
-    // See bug 391848 and bug 415426.
-#ifdef _WIN64
-    return dhwEnumerateLoadedModules64(::GetCurrentProcess(),
-               (PENUMLOADED_MODULES_CALLBACK64)ModuleEnumCallback, this);
-#else
-    return dhwEnumerateLoadedModules(::GetCurrentProcess(), 
-               (PENUMLOADED_MODULES_CALLBACK)ModuleEnumCallback, this);
-#endif
-}    
-                                
-bool 
-DHWImportHooker::PatchOneModule(HMODULE aModule, const char* name)
-{
-    if(aModule == mIgnoreModule)
-    {
-        return true;
-    }
-
-    // do the fun stuff...
-
-    PIMAGE_IMPORT_DESCRIPTOR desc;
-    ULONG size;
-
-    desc = (PIMAGE_IMPORT_DESCRIPTOR) 
-        dhwImageDirectoryEntryToData(aModule, true, 
-                                     IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
-
-    if(!desc)
-    {
-        return true;
-    }
-
-    for(; desc->Name; desc++)
-    {
-        const char* entryModuleName = (const char*)
-            ((char*)aModule + desc->Name);
-        if(!lstrcmpi(entryModuleName, mModuleName))
-            break;
-    }
-
-    if(!desc->Name)
-    {
-        return true;
-    }
-
-    PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)
-        ((char*) aModule + desc->FirstThunk);
-
-    for(; thunk->u1.Function; thunk++)
-    {
-        PROC original;
-        PROC replacement;
-        
-        if(mHooking)
-        {
-            original = mOriginal;
-            replacement = mHook;  
-        } 
-        else
-        {
-            original = mHook;  
-            replacement = mOriginal;
-        }   
-
-        PROC* ppfn = (PROC*) &thunk->u1.Function;
-        if(*ppfn == original)
-        {
-            DWORD dwDummy;
-            VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy);
-            BOOL result = WriteProcessMemory(GetCurrentProcess(), 
-                               ppfn, &replacement, sizeof(replacement), nullptr);
-            if (!result) //failure
-            {
-              printf("failure name %s  func %x\n",name,*ppfn);
-              DWORD error = GetLastError();
-              return true;
-            }
-            else
-            {
-              // printf("success name %s  func %x\n",name,*ppfn);
-              DWORD filler = result+1;
-              return result;
-            }
-        }
-
-    }
-    return true;
-}
-
-bool 
-DHWImportHooker::ModuleLoaded(HMODULE aModule, DWORD flags)
-{
-    //printf("ModuleLoaded\n");
-    if(aModule && !(flags & LOAD_LIBRARY_AS_DATAFILE))
-    {
-        PR_Lock(gLock);
-        // We don't know that the newly loaded module didn't drag in implicitly
-        // linked modules, so we patch everything in sight.
-        for(DHWImportHooker* cur = gHooks; cur; cur = cur->mNext)
-            cur->PatchAllModules();
-        PR_Unlock(gLock);
-    }
-    return true;
-}
-
-// static 
-HMODULE WINAPI 
-DHWImportHooker::LoadLibraryW(PCWSTR path)
-{
-    //wprintf(L"LoadLibraryW %s\n",path);
-    HMODULE hmod = DHW_ORIGINAL(::LoadLibraryW, getLoadLibraryWHooker())(path);
-    ModuleLoaded(hmod, 0);
-    return hmod;
-}
-
-
-// static 
-HMODULE WINAPI 
-DHWImportHooker::LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags)
-{
-    //wprintf(L"LoadLibraryExW %s\n",path);
-    HMODULE hmod = DHW_ORIGINAL(::LoadLibraryExW, getLoadLibraryExWHooker())(path, file, flags);
-    ModuleLoaded(hmod, flags);
-    return hmod;
-}    
-
-// static 
-HMODULE WINAPI 
-DHWImportHooker::LoadLibraryA(PCSTR path)
-{
-    //printf("LoadLibraryA %s\n",path);
-    HMODULE hmod = DHW_ORIGINAL(::LoadLibraryA, getLoadLibraryAHooker())(path);
-    ModuleLoaded(hmod, 0);
-    return hmod;
-}
-
-// static 
-HMODULE WINAPI 
-DHWImportHooker::LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags)
-{
-    //printf("LoadLibraryExA %s\n",path);
-    HMODULE hmod = DHW_ORIGINAL(::LoadLibraryExA, getLoadLibraryExAHooker())(path, file, flags);
-    ModuleLoaded(hmod, flags);
-    return hmod;
-}     
-// static 
-FARPROC WINAPI 
-DHWImportHooker::GetProcAddress(HMODULE aModule, PCSTR aFunctionName)
-{
-    FARPROC pfn = gRealGetProcAddress(aModule, aFunctionName);
-    
-    if(pfn)
-    {
-        PR_Lock(gLock);
-        for(DHWImportHooker* cur = gHooks; cur; cur = cur->mNext)
-        {
-            if(pfn == cur->mOriginal)
-            {
-                pfn = cur->mHook;
-                break;
-            }    
-        }
-        PR_Unlock(gLock);
-    }
-    return pfn;
-}
-
-
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsDebugHelpWin32.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Win32 x86/x64 code for stack walking, symbol resolution, and function hooking */
-
-#ifndef __nsDebugHelpWin32_h__
-#define __nsDebugHelpWin32_h__
-
-#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
-  #ifndef WIN32_LEAN_AND_MEAN
-    #define WIN32_LEAN_AND_MEAN
-  #endif
-  #include <windows.h>
-  #include <imagehlp.h>
-  #include <crtdbg.h>
-#else
-  #error "nsDebugHelpWin32.h should only be included in Win32 x86/x64 builds"
-#endif
-
-// XXX temporary hack...
-//#include "hacky_defines.h"
-
-
-/***************************************************************************/
-// useful macros...
-
-#ifdef DHW_IMPLEMENT_GLOBALS
-#define DHW_DECLARE_FUN_GLOBAL(name_) decltype(name_)* dhw##name_
-#else
-#define DHW_DECLARE_FUN_GLOBAL(name_) extern decltype(name_)* dhw##name_
-#endif
-
-
-/**********************************************************/
-// This is used to get 'original' function addresses from DHWImportHooker.
-
-#define DHW_ORIGINAL(name_, hooker_) \
-    ((decltype(name_)*) hooker_ . GetOriginalFunction())
-
-/***************************************************************************/
-// Global declarations of entry points into ImgHelp functions
-
-#ifndef _WIN64
-DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules);
-#else
-DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules64);
-#endif
-
-DHW_DECLARE_FUN_GLOBAL(ImageDirectoryEntryToData);
-
-/***************************************************************************/
-
-extern bool
-dhwEnsureImageHlpInitialized();
-
-/***************************************************************************/
-
-class DHWImportHooker
-{
-public: 
-
-    DHWImportHooker(const char* aModuleName,
-                    const char* aFunctionName,
-                    PROC aHook,
-                    bool aExcludeOurModule = false);
-                    
-    ~DHWImportHooker();
-
-    PROC GetOriginalFunction()  {return mOriginal;}
-
-    bool PatchAllModules();
-    bool PatchOneModule(HMODULE aModule, const char* name);
-    static bool ModuleLoaded(HMODULE aModule, DWORD flags);
-
-
-    // I think that these should be made not static members, but allocated
-    // things created in an explicit static 'init' method and cleaned up in
-    // an explicit static 'finish' method. This would allow the application
-    // to have proper lifetime control over all the hooks.
-
-    static DHWImportHooker &getLoadLibraryWHooker();
-    static DHWImportHooker &getLoadLibraryExWHooker();
-    static DHWImportHooker &getLoadLibraryAHooker();
-    static DHWImportHooker &getLoadLibraryExAHooker();
-    static DHWImportHooker &getGetProcAddressHooker();
-
-    static HMODULE WINAPI LoadLibraryA(PCSTR path);
-
-private:
-    DHWImportHooker* mNext;
-    const char*      mModuleName;
-    const char*      mFunctionName;
-    PROC             mOriginal;
-    PROC             mHook;
-    HMODULE          mIgnoreModule;
-    bool             mHooking;
-
-private:
-    static PRLock* gLock;
-    static DHWImportHooker* gHooks;
-    static decltype(GetProcAddress)* gRealGetProcAddress;
-    
-    static HMODULE WINAPI LoadLibraryW(PCWSTR path);
-    static HMODULE WINAPI LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags);
-    static HMODULE WINAPI LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags);
-
-    static FARPROC WINAPI GetProcAddress(HMODULE aModule, PCSTR aFunctionName);
-};
-
-/***************************************************************************/
-// This supports the _CrtSetAllocHook based hooking.
-// This system sucks because you don't get to see the allocated pointer. I
-// don't think it appropriate for nsTraceMalloc, but is useful as a means to make
-// malloc fail for testing purposes.
-#if 0 //comment out this stuff. not necessary
-
-class DHWAllocationSizeDebugHook
-{
-public:
-    virtual bool AllocHook(size_t size) = 0;
-    virtual bool ReallocHook(size_t size, size_t sizeOld) = 0;
-    virtual bool FreeHook(size_t size) = 0;
-};
-
-extern bool dhwSetAllocationSizeDebugHook(DHWAllocationSizeDebugHook* hook);
-extern bool dhwClearAllocationSizeDebugHook();
-
-/***************************************************************************/
-#endif //0
-
-#endif /* __nsDebugHelpWin32_h__ */
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsTraceMalloc.c
+++ /dev/null
@@ -1,2063 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim:cindent:ts=8:et:sw=4:
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef NS_TRACE_MALLOC
- /*
-  * TODO:
-  * - FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=392008
-  * - extend logfile so 'F' record tells free stack
-  */
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef XP_UNIX
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#endif
-#include "plhash.h"
-#include "pratom.h"
-#include "prlog.h"
-#include "prlock.h"
-#include "prmon.h"
-#include "prprf.h"
-#include "prenv.h"
-#include "prnetdb.h"
-#include "nsTraceMalloc.h"
-#include "nscore.h"
-#include "prinit.h"
-#include "prthread.h"
-#include "plstr.h"
-#include "nsStackWalk.h"
-#include "nsTraceMallocCallbacks.h"
-#include "nsTypeInfo.h"
-#include "mozilla/PoisonIOInterposer.h"
-
-#if defined(XP_MACOSX)
-
-#include <malloc/malloc.h>
-
-#define WRITE_FLAGS "w"
-
-#define __libc_malloc(x)                malloc(x)
-#define __libc_realloc(x, y)            realloc(x, y)
-#define __libc_free(x)                  free(x)
-
-#elif defined(XP_UNIX)
-
-#include <malloc.h>
-
-#define WRITE_FLAGS "w"
-
-#ifdef WRAP_SYSTEM_INCLUDES
-#pragma GCC visibility push(default)
-#endif
-extern __ptr_t __libc_malloc(size_t);
-extern __ptr_t __libc_calloc(size_t, size_t);
-extern __ptr_t __libc_realloc(__ptr_t, size_t);
-extern void    __libc_free(__ptr_t);
-extern __ptr_t __libc_memalign(size_t, size_t);
-extern __ptr_t __libc_valloc(size_t);
-#ifdef WRAP_SYSTEM_INCLUDES
-#pragma GCC visibility pop
-#endif
-
-#elif defined(XP_WIN32)
-
-#include <sys/timeb.h>                  /* for timeb */
-#include <sys/stat.h>                   /* for fstat */
-
-#include <io.h> /*for write*/
-
-#define WRITE_FLAGS "w"
-
-#define __libc_malloc(x)                dhw_orig_malloc(x)
-#define __libc_realloc(x, y)            dhw_orig_realloc(x,y)
-#define __libc_free(x)                  dhw_orig_free(x)
-
-#else  /* not XP_MACOSX, XP_UNIX, or XP_WIN32 */
-
-# error "Unknown build configuration!"
-
-#endif
-
-typedef struct logfile logfile;
-
-#define STARTUP_TMBUFSIZE (64 * 1024)
-#define LOGFILE_TMBUFSIZE (16 * 1024)
-
-struct logfile {
-    int         fd;
-    int         lfd;            /* logical fd, dense among all logfiles */
-    char        *buf;
-    int         bufsize;
-    int         pos;
-    uint32_t    size;
-    uint32_t    simsize;
-    logfile     *next;
-    logfile     **prevp;
-};
-
-static char      default_buf[STARTUP_TMBUFSIZE];
-static logfile   default_logfile =
-                   {-1, 0, default_buf, STARTUP_TMBUFSIZE, 0, 0, 0, NULL, NULL};
-static logfile   *logfile_list = NULL;
-static logfile   **logfile_tail = &logfile_list;
-static logfile   *logfp = &default_logfile;
-static PRLock    *tmlock = NULL;
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif
-static char      sdlogname[PATH_MAX] = ""; /* filename for shutdown leak log */
-
-/*
- * This enables/disables trace-malloc logging.
- *
- * It is separate from suppress_tracing so that we do not have to pay
- * the performance cost of repeated TM_TLS_GET_DATA calls when
- * trace-malloc is disabled (which is not as bad as the locking we used
- * to have).
- *
- * It must default to zero, since it can be tested by the Linux malloc
- * hooks before NS_TraceMallocStartup sets it.
- */
-static uint32_t tracing_enabled = 0;
-
-/*
- * Control whether we should log stacks
- */
-static uint32_t stacks_enabled = 1;
-
-/*
- * This lock must be held while manipulating the calltree, the
- * allocations table, the log, or the tmstats.
- *
- * Callers should not *enter* the lock without checking suppress_tracing
- * first; otherwise they risk trying to re-enter on the same thread.
- */
-#define TM_ENTER_LOCK(t)                                                      \
-    PR_BEGIN_MACRO                                                            \
-        PR_ASSERT(t->suppress_tracing != 0);                                  \
-        if (tmlock)                                                           \
-            PR_Lock(tmlock);                                                  \
-    PR_END_MACRO
-
-#define TM_EXIT_LOCK(t)                                                       \
-    PR_BEGIN_MACRO                                                            \
-        PR_ASSERT(t->suppress_tracing != 0);                                  \
-        if (tmlock)                                                           \
-            PR_Unlock(tmlock);                                                \
-    PR_END_MACRO
-
-#define TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t)                                 \
-    PR_BEGIN_MACRO                                                            \
-        t->suppress_tracing++;                                                \
-        TM_ENTER_LOCK(t);                                                     \
-    PR_END_MACRO
-
-#define TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t)                                \
-    PR_BEGIN_MACRO                                                            \
-        TM_EXIT_LOCK(t);                                                      \
-        t->suppress_tracing--;                                                \
-    PR_END_MACRO
-
-
-/*
- * Thread-local storage.
- *
- * We can't use NSPR thread-local storage for this because it mallocs
- * within PR_GetThreadPrivate (the first time) and PR_SetThreadPrivate
- * (which can be worked around by protecting all uses of those functions
- * with a monitor, ugh) and because it calls malloc/free when the
- * thread-local storage is in an inconsistent state within
- * PR_SetThreadPrivate (when expanding the thread-local storage array)
- * and _PRI_DetachThread (when and after deleting the thread-local
- * storage array).
- */
-
-#ifdef XP_WIN32
-
-#include <windows.h>
-
-#define TM_TLS_INDEX_TYPE               DWORD
-#define TM_CREATE_TLS_INDEX(i_)         PR_BEGIN_MACRO                        \
-                                          (i_) = TlsAlloc();                  \
-                                        PR_END_MACRO
-#define TM_DESTROY_TLS_INDEX(i_)        TlsFree((i_))
-#define TM_GET_TLS_DATA(i_)             TlsGetValue((i_))
-#define TM_SET_TLS_DATA(i_, v_)         TlsSetValue((i_), (v_))
-
-#else
-
-#include <pthread.h>
-
-#define TM_TLS_INDEX_TYPE               pthread_key_t
-#define TM_CREATE_TLS_INDEX(i_)         pthread_key_create(&(i_), NULL)
-#define TM_DESTROY_TLS_INDEX(i_)        pthread_key_delete((i_))
-#define TM_GET_TLS_DATA(i_)             pthread_getspecific((i_))
-#define TM_SET_TLS_DATA(i_, v_)         pthread_setspecific((i_), (v_))
-
-#endif
-
-static TM_TLS_INDEX_TYPE tls_index;
-static PRBool tls_index_initialized = PR_FALSE;
-
-/* FIXME (maybe): This is currently unused; we leak the thread-local data. */
-#if 0
-static void
-free_tm_thread(void *priv)
-{
-    tm_thread *t = (tm_thread*) priv;
-
-    PR_ASSERT(t->suppress_tracing == 0);
-
-    if (t->in_heap) {
-        t->suppress_tracing = 1;
-        if (t->backtrace_buf.buffer)
-            __libc_free(t->backtrace_buf.buffer);
-
-        __libc_free(t);
-    }
-}
-#endif
-
-tm_thread *
-tm_get_thread(void)
-{
-    tm_thread *t;
-    tm_thread stack_tm_thread;
-
-    if (!tls_index_initialized) {
-        /**
-         * Assume that the first call to |malloc| will occur before
-         * there are multiple threads.  (If that's not the case, we
-         * probably need to do the necessary synchronization without
-         * using NSPR primitives.  See discussion in
-         * https://bugzilla.mozilla.org/show_bug.cgi?id=442192
-         */
-        TM_CREATE_TLS_INDEX(tls_index);
-        tls_index_initialized = PR_TRUE;
-    }
-
-    t = TM_GET_TLS_DATA(tls_index);
-
-    if (!t) {
-        /*
-         * First, store a tm_thread on the stack to suppress for the
-         * malloc below
-         */
-        stack_tm_thread.suppress_tracing = 1;
-        stack_tm_thread.backtrace_buf.buffer = NULL;
-        stack_tm_thread.backtrace_buf.size = 0;
-        stack_tm_thread.backtrace_buf.entries = 0;
-        TM_SET_TLS_DATA(tls_index, &stack_tm_thread);
-
-        t = (tm_thread*) __libc_malloc(sizeof(tm_thread));
-        t->suppress_tracing = 0;
-        t->backtrace_buf = stack_tm_thread.backtrace_buf;
-        TM_SET_TLS_DATA(tls_index, t);
-
-        PR_ASSERT(stack_tm_thread.suppress_tracing == 1); /* balanced */
-    }
-
-    return t;
-}
-
-/* We don't want more than 32 logfiles open at once, ok? */
-typedef uint32_t        lfd_set;
-
-#define LFD_SET_STATIC_INITIALIZER 0
-#define LFD_SET_SIZE    32
-
-#define LFD_ZERO(s)     (*(s) = 0)
-#define LFD_BIT(i)      ((uint32_t)1 << (i))
-#define LFD_TEST(i,s)   (LFD_BIT(i) & *(s))
-#define LFD_SET(i,s)    (*(s) |= LFD_BIT(i))
-#define LFD_CLR(i,s)    (*(s) &= ~LFD_BIT(i))
-
-static logfile *get_logfile(int fd)
-{
-    logfile *fp;
-    int lfd;
-
-    for (fp = logfile_list; fp; fp = fp->next) {
-        if (fp->fd == fd)
-            return fp;
-    }
-    lfd = 0;
-retry:
-    for (fp = logfile_list; fp; fp = fp->next) {
-        if (fp->fd == lfd) {
-            if (++lfd >= LFD_SET_SIZE)
-                return NULL;
-            goto retry;
-        }
-    }
-    fp = __libc_malloc(sizeof(logfile) + LOGFILE_TMBUFSIZE);
-    if (!fp)
-        return NULL;
-    fp->fd = fd;
-    fp->lfd = lfd;
-    fp->buf = (char*) (fp + 1);
-    fp->bufsize = LOGFILE_TMBUFSIZE;
-    fp->pos = 0;
-    fp->size = fp->simsize = 0;
-    fp->next = NULL;
-    fp->prevp = logfile_tail;
-    *logfile_tail = fp;
-    logfile_tail = &fp->next;
-    return fp;
-}
-
-static void flush_logfile(logfile *fp)
-{
-    int len, cnt, fd;
-    char *bp;
-
-    len = fp->pos;
-    if (len == 0)
-        return;
-    fp->pos = 0;
-    fd = fp->fd;
-    if (fd >= 0) {
-        fp->size += len;
-        bp = fp->buf;
-        do {
-            cnt = write(fd, bp, len);
-            if (cnt <= 0) {
-                printf("### nsTraceMalloc: write failed or wrote 0 bytes!\n");
-                return;
-            }
-            bp += cnt;
-            len -= cnt;
-        } while (len > 0);
-    }
-    fp->simsize += len;
-}
-
-static void log_byte(logfile *fp, char byte)
-{
-    if (fp->pos == fp->bufsize)
-        flush_logfile(fp);
-    fp->buf[fp->pos++] = byte;
-}
-
-static void log_string(logfile *fp, const char *str)
-{
-    int len, rem, cnt;
-
-    len = strlen(str) + 1; /* include null terminator */
-    while ((rem = fp->pos + len - fp->bufsize) > 0) {
-        cnt = len - rem;
-        memcpy(&fp->buf[fp->pos], str, cnt);
-        str += cnt;
-        fp->pos += cnt;
-        flush_logfile(fp);
-        len = rem;
-    }
-    memcpy(&fp->buf[fp->pos], str, len);
-    fp->pos += len;
-}
-
-static void log_filename(logfile* fp, const char* filename)
-{
-    if (strlen(filename) < 512) {
-        char *bp, *cp, buf[512];
-
-        bp = strstr(strcpy(buf, filename), "mozilla");
-        if (!bp)
-            bp = buf;
-
-        for (cp = bp; *cp; cp++) {
-            if (*cp == '\\')
-                *cp = '/';
-        }
-
-        filename = bp;
-    }
-    log_string(fp, filename);
-}
-
-static void log_uint32(logfile *fp, uint32_t ival)
-{
-    if (ival < 0x80) {
-        /* 0xxx xxxx */
-        log_byte(fp, (char) ival);
-    } else if (ival < 0x4000) {
-        /* 10xx xxxx xxxx xxxx */
-        log_byte(fp, (char) ((ival >> 8) | 0x80));
-        log_byte(fp, (char) (ival & 0xff));
-    } else if (ival < 0x200000) {
-        /* 110x xxxx xxxx xxxx xxxx xxxx */
-        log_byte(fp, (char) ((ival >> 16) | 0xc0));
-        log_byte(fp, (char) ((ival >> 8) & 0xff));
-        log_byte(fp, (char) (ival & 0xff));
-    } else if (ival < 0x10000000) {
-        /* 1110 xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
-        log_byte(fp, (char) ((ival >> 24) | 0xe0));
-        log_byte(fp, (char) ((ival >> 16) & 0xff));
-        log_byte(fp, (char) ((ival >> 8) & 0xff));
-        log_byte(fp, (char) (ival & 0xff));
-    } else {
-        /* 1111 0000 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
-        log_byte(fp, (char) 0xf0);
-        log_byte(fp, (char) ((ival >> 24) & 0xff));
-        log_byte(fp, (char) ((ival >> 16) & 0xff));
-        log_byte(fp, (char) ((ival >> 8) & 0xff));
-        log_byte(fp, (char) (ival & 0xff));
-    }
-}
-
-static void log_event1(logfile *fp, char event, uint32_t serial)
-{
-    log_byte(fp, event);
-    log_uint32(fp, (uint32_t) serial);
-}
-
-static void log_event2(logfile *fp, char event, uint32_t serial, size_t size)
-{
-    log_event1(fp, event, serial);
-    log_uint32(fp, (uint32_t) size);
-}
-
-static void log_event3(logfile *fp, char event, uint32_t serial, size_t oldsize,
-                       size_t size)
-{
-    log_event2(fp, event, serial, oldsize);
-    log_uint32(fp, (uint32_t) size);
-}
-
-static void log_event4(logfile *fp, char event, uint32_t serial, uint32_t ui2,
-                       uint32_t ui3, uint32_t ui4)
-{
-    log_event3(fp, event, serial, ui2, ui3);
-    log_uint32(fp, ui4);
-}
-
-static void log_event5(logfile *fp, char event, uint32_t serial, uint32_t ui2,
-                       uint32_t ui3, uint32_t ui4, uint32_t ui5)
-{
-    log_event4(fp, event, serial, ui2, ui3, ui4);
-    log_uint32(fp, ui5);
-}
-
-static void log_event6(logfile *fp, char event, uint32_t serial, uint32_t ui2,
-                       uint32_t ui3, uint32_t ui4, uint32_t ui5, uint32_t ui6)
-{
-    log_event5(fp, event, serial, ui2, ui3, ui4, ui5);
-    log_uint32(fp, ui6);
-}
-
-static void log_event7(logfile *fp, char event, uint32_t serial, uint32_t ui2,
-                       uint32_t ui3, uint32_t ui4, uint32_t ui5, uint32_t ui6,
-                       uint32_t ui7)
-{
-    log_event6(fp, event, serial, ui2, ui3, ui4, ui5, ui6);
-    log_uint32(fp, ui7);
-}
-
-static void log_event8(logfile *fp, char event, uint32_t serial, uint32_t ui2,
-                       uint32_t ui3, uint32_t ui4, uint32_t ui5, uint32_t ui6,
-                       uint32_t ui7, uint32_t ui8)
-{
-    log_event7(fp, event, serial, ui2, ui3, ui4, ui5, ui6, ui7);
-    log_uint32(fp, ui8);
-}
-
-typedef struct callsite callsite;
-
-struct callsite {
-    void*       pc;
-    uint32_t      serial;
-    lfd_set     lfdset;
-    const char  *name;    /* pointer to string owned by methods table */
-    const char  *library; /* pointer to string owned by libraries table */
-    int         offset;
-    callsite    *parent;
-    callsite    *siblings;
-    callsite    *kids;
-};
-
-/* NB: these counters are incremented and decremented only within tmlock. */
-static uint32_t library_serial_generator = 0;
-static uint32_t method_serial_generator = 0;
-static uint32_t callsite_serial_generator = 0;
-static uint32_t tmstats_serial_generator = 0;
-static uint32_t filename_serial_generator = 0;
-
-/* Root of the tree of callsites, the sum of all (cycle-compressed) stacks. */
-static callsite calltree_root =
-  {0, 0, LFD_SET_STATIC_INITIALIZER, NULL, NULL, 0, NULL, NULL, NULL};
-
-/* a fake pc for when stacks are disabled; must be different from the
-   pc in calltree_root */
-#define STACK_DISABLED_PC ((void*)1)
-
-/* Basic instrumentation. */
-static nsTMStats tmstats = NS_TMSTATS_STATIC_INITIALIZER;
-
-/* Parent with the most kids (tmstats.calltree_maxkids). */
-static callsite *calltree_maxkids_parent;
-
-/* Calltree leaf for path with deepest stack backtrace. */
-static callsite *calltree_maxstack_top;
-
-/* Last site (i.e., calling pc) that recurred during a backtrace. */
-static callsite *last_callsite_recurrence;
-
-static void log_tmstats(logfile *fp)
-{
-    log_event1(fp, TM_EVENT_STATS, ++tmstats_serial_generator);
-    log_uint32(fp, tmstats.calltree_maxstack);
-    log_uint32(fp, tmstats.calltree_maxdepth);
-    log_uint32(fp, tmstats.calltree_parents);
-    log_uint32(fp, tmstats.calltree_maxkids);
-    log_uint32(fp, tmstats.calltree_kidhits);
-    log_uint32(fp, tmstats.calltree_kidmisses);
-    log_uint32(fp, tmstats.calltree_kidsteps);
-    log_uint32(fp, tmstats.callsite_recurrences);
-    log_uint32(fp, tmstats.backtrace_calls);
-    log_uint32(fp, tmstats.backtrace_failures);
-    log_uint32(fp, tmstats.btmalloc_failures);
-    log_uint32(fp, tmstats.dladdr_failures);
-    log_uint32(fp, tmstats.malloc_calls);
-    log_uint32(fp, tmstats.malloc_failures);
-    log_uint32(fp, tmstats.calloc_calls);
-    log_uint32(fp, tmstats.calloc_failures);
-    log_uint32(fp, tmstats.realloc_calls);
-    log_uint32(fp, tmstats.realloc_failures);
-    log_uint32(fp, tmstats.free_calls);
-    log_uint32(fp, tmstats.null_free_calls);
-    log_uint32(fp, calltree_maxkids_parent ? calltree_maxkids_parent->serial
-                                           : 0);
-    log_uint32(fp, calltree_maxstack_top ? calltree_maxstack_top->serial : 0);
-}
-
-static void *generic_alloctable(void *pool, size_t size)
-{
-    return __libc_malloc(size);
-}
-
-static void generic_freetable(void *pool, void *item)
-{
-    __libc_free(item);
-}
-
-typedef struct lfdset_entry {
-    PLHashEntry base;
-    lfd_set     lfdset;
-} lfdset_entry;
-
-static PLHashEntry *lfdset_allocentry(void *pool, const void *key)
-{
-    lfdset_entry *le = __libc_malloc(sizeof *le);
-    if (le)
-        LFD_ZERO(&le->lfdset);
-    return &le->base;
-}
-
-static void lfdset_freeentry(void *pool, PLHashEntry *he, unsigned flag)
-{
-    lfdset_entry *le;
-
-    if (flag != HT_FREE_ENTRY)
-        return;
-    le = (lfdset_entry*) he;
-    __libc_free((void*) le);
-}
-
-static PLHashAllocOps lfdset_hashallocops = {
-    generic_alloctable, generic_freetable,
-    lfdset_allocentry,  lfdset_freeentry
-};
-
-/* Table of library pathnames mapped to to logged 'L' record serial numbers. */
-static PLHashTable *libraries = NULL;
-
-/* Table of filename pathnames mapped to logged 'G' record serial numbers. */
-static PLHashTable *filenames = NULL;
-
-/* Table mapping method names to logged 'N' record serial numbers. */
-static PLHashTable *methods = NULL;
-
-/*
- * Presumes that its caller is holding tmlock, but may temporarily exit
- * the lock.
- */
-static callsite *
-calltree(void **stack, size_t num_stack_entries, tm_thread *t)
-{
-    logfile *fp = logfp;
-    void *pc;
-    uint32_t nkids;
-    callsite *parent, *site, **csp, *tmp;
-    int maxstack;
-    uint32_t library_serial, method_serial, filename_serial;
-    const char *library, *method, *filename;
-    char *slash;
-    PLHashNumber hash;
-    PLHashEntry **hep, *he;
-    lfdset_entry *le;
-    size_t stack_index;
-    nsCodeAddressDetails details;
-    nsresult rv;
-
-    maxstack = (num_stack_entries > tmstats.calltree_maxstack);
-    if (maxstack) {
-        /* these two are the same, although that used to be less clear */
-        tmstats.calltree_maxstack = num_stack_entries;
-        tmstats.calltree_maxdepth = num_stack_entries;
-    }
-
-    /* Reverse the stack again, finding and building a path in the tree. */
-    parent = &calltree_root;
-    stack_index = num_stack_entries;
-    do {
-        --stack_index;
-        pc = stack[stack_index];
-
-        csp = &parent->kids;
-        while ((site = *csp) != NULL) {
-            if (site->pc == pc) {
-                tmstats.calltree_kidhits++;
-
-                /* Put the most recently used site at the front of siblings. */
-                *csp = site->siblings;
-                site->siblings = parent->kids;
-                parent->kids = site;
-
-                /* Check whether we've logged for this site and logfile yet. */
-                if (!LFD_TEST(fp->lfd, &site->lfdset)) {
-                    /*
-                     * Some other logfile put this site in the calltree.  We
-                     * must log an event for site, and possibly first for its
-                     * method and/or library.  Note the code after the while
-                     * loop that tests if (!site).
-                     */
-                    break;
-                }
-
-                /* Site already built and logged to fp -- go up the stack. */
-                goto upward;
-            }
-            tmstats.calltree_kidsteps++;
-            csp = &site->siblings;
-        }
-
-        if (!site) {
-            tmstats.calltree_kidmisses++;
-
-            /* Check for recursion: see if pc is on our ancestor line. */
-            for (site = parent; site; site = site->parent) {
-                if (site->pc == pc) {
-                    tmstats.callsite_recurrences++;
-                    last_callsite_recurrence = site;
-                    goto upward;
-                }
-            }
-        }
-
-        /*
-         * Not in tree at all, or not logged to fp: let's find our symbolic
-         * callsite info.
-         */
-
-        if (!stacks_enabled) {
-            /*
-             * Fake the necessary information for our single fake stack
-             * frame.
-             */
-            PL_strncpyz(details.library, "stacks_disabled",
-                        sizeof(details.library));
-            details.loffset = 0;
-            details.filename[0] = '\0';
-            details.lineno = 0;
-            details.function[0] = '\0';
-            details.foffset = 0;
-        } else {
-            /*
-             * NS_DescribeCodeAddress can (on Linux) acquire a lock inside
-             * the shared library loader.  Another thread might call malloc
-             * while holding that lock (when loading a shared library).  So
-             * we have to exit tmlock around this call.  For details, see
-             * https://bugzilla.mozilla.org/show_bug.cgi?id=363334#c3
-             *
-             * We could be more efficient by building the nodes in the
-             * calltree, exiting the monitor once to describe all of them,
-             * and then filling in the descriptions for any that hadn't been
-             * described already.  But this is easier for now.
-             */
-            TM_EXIT_LOCK(t);
-            rv = NS_DescribeCodeAddress(pc, &details);
-            TM_ENTER_LOCK(t);
-            if (NS_FAILED(rv)) {
-                tmstats.dladdr_failures++;
-                goto fail;
-            }
-        }
-
-        /* Check whether we need to emit a library trace record. */
-        library_serial = 0;
-        library = NULL;
-        if (details.library[0]) {
-            if (!libraries) {
-                libraries = PL_NewHashTable(100, PL_HashString,
-                                            PL_CompareStrings, PL_CompareValues,
-                                            &lfdset_hashallocops, NULL);
-                if (!libraries) {
-                    tmstats.btmalloc_failures++;
-                    goto fail;
-                }
-            }
-            hash = PL_HashString(details.library);
-            hep = PL_HashTableRawLookup(libraries, hash, details.library);
-            he = *hep;
-            if (he) {
-                library = (char*) he->key;
-                library_serial = (uint32_t) NS_PTR_TO_INT32(he->value);
-                le = (lfdset_entry *) he;
-                if (LFD_TEST(fp->lfd, &le->lfdset)) {
-                    /* We already logged an event on fp for this library. */
-                    le = NULL;
-                }
-            } else {
-                library = strdup(details.library);
-                if (library) {
-                    library_serial = ++library_serial_generator;
-                    he = PL_HashTableRawAdd(libraries, hep, hash, library,
-                                            NS_INT32_TO_PTR(library_serial));
-                }
-                if (!he) {
-                    tmstats.btmalloc_failures++;
-                    goto fail;
-                }
-                le = (lfdset_entry *) he;
-            }
-            if (le) {
-                /* Need to log an event to fp for this lib. */
-                slash = strrchr(library, '/');
-                log_event1(fp, TM_EVENT_LIBRARY, library_serial);
-                log_string(fp, slash ? slash + 1 : library);
-                LFD_SET(fp->lfd, &le->lfdset);
-            }
-        }
-
-        /* For compatibility with current log format, always emit a
-         * filename trace record, using "noname" / 0 when no file name
-         * is available. */
-        filename_serial = 0;
-        filename = details.filename[0] ? details.filename : "noname";
-        if (!filenames) {
-            filenames = PL_NewHashTable(100, PL_HashString,
-                                        PL_CompareStrings, PL_CompareValues,
-                                        &lfdset_hashallocops, NULL);
-            if (!filenames) {
-                tmstats.btmalloc_failures++;
-                return NULL;
-            }
-        }
-        hash = PL_HashString(filename);
-        hep = PL_HashTableRawLookup(filenames, hash, filename);
-        he = *hep;
-        if (he) {
-            filename = (char*) he->key;
-            filename_serial = (uint32_t) NS_PTR_TO_INT32(he->value);
-            le = (lfdset_entry *) he;
-            if (LFD_TEST(fp->lfd, &le->lfdset)) {
-                /* We already logged an event on fp for this filename. */
-                le = NULL;
-            }
-        } else {
-            filename = strdup(filename);
-            if (filename) {
-                filename_serial = ++filename_serial_generator;
-                he = PL_HashTableRawAdd(filenames, hep, hash, filename,
-                                        NS_INT32_TO_PTR(filename_serial));
-            }
-            if (!he) {
-                tmstats.btmalloc_failures++;
-                return NULL;
-            }
-            le = (lfdset_entry *) he;
-        }
-        if (le) {
-            /* Need to log an event to fp for this filename. */
-            log_event1(fp, TM_EVENT_FILENAME, filename_serial);
-            log_filename(fp, filename);
-            LFD_SET(fp->lfd, &le->lfdset);
-        }
-
-        if (!details.function[0]) {
-            PR_snprintf(details.function, sizeof(details.function),
-                        "%s+%X", library ? library : "main", details.loffset);
-        }
-
-        /* Emit an 'N' (for New method, 'M' is for malloc!) event if needed. */
-        method_serial = 0;
-        if (!methods) {
-            methods = PL_NewHashTable(10000, PL_HashString,
-                                      PL_CompareStrings, PL_CompareValues,
-                                      &lfdset_hashallocops, NULL);
-            if (!methods) {
-                tmstats.btmalloc_failures++;
-                goto fail;
-            }
-        }
-        hash = PL_HashString(details.function);
-        hep = PL_HashTableRawLookup(methods, hash, details.function);
-        he = *hep;
-        if (he) {
-            method = (char*) he->key;
-            method_serial = (uint32_t) NS_PTR_TO_INT32(he->value);
-            le = (lfdset_entry *) he;
-            if (LFD_TEST(fp->lfd, &le->lfdset)) {
-                /* We already logged an event on fp for this method. */
-                le = NULL;
-            }
-        } else {
-            method = strdup(details.function);
-            if (method) {
-                method_serial = ++method_serial_generator;
-                he = PL_HashTableRawAdd(methods, hep, hash, method,
-                                        NS_INT32_TO_PTR(method_serial));
-            }
-            if (!he) {
-                tmstats.btmalloc_failures++;
-                return NULL;
-            }
-            le = (lfdset_entry *) he;
-        }
-        if (le) {
-            log_event4(fp, TM_EVENT_METHOD, method_serial, library_serial,
-                       filename_serial, details.lineno);
-            log_string(fp, method);
-            LFD_SET(fp->lfd, &le->lfdset);
-        }
-
-        /* Create a new callsite record. */
-        if (!site) {
-            site = __libc_malloc(sizeof(callsite));
-            if (!site) {
-                tmstats.btmalloc_failures++;
-                goto fail;
-            }
-
-            /* Update parent and max-kids-per-parent stats. */
-            if (!parent->kids)
-                tmstats.calltree_parents++;
-            nkids = 1;
-            for (tmp = parent->kids; tmp; tmp = tmp->siblings)
-                nkids++;
-            if (nkids > tmstats.calltree_maxkids) {
-                tmstats.calltree_maxkids = nkids;
-                calltree_maxkids_parent = parent;
-            }
-
-            /* Insert the new site into the tree. */
-            site->pc = pc;
-            site->serial = ++callsite_serial_generator;
-            LFD_ZERO(&site->lfdset);
-            site->name = method;
-            site->library = library;
-            site->offset = details.loffset;
-            site->parent = parent;
-            site->siblings = parent->kids;
-            parent->kids = site;
-            site->kids = NULL;
-        }
-
-        /* Log the site with its parent, method, and offset. */
-        log_event4(fp, TM_EVENT_CALLSITE, site->serial, parent->serial,
-                   method_serial, details.foffset);
-        LFD_SET(fp->lfd, &site->lfdset);
-
-      upward:
-        parent = site;
-    } while (stack_index > 0);
-
-    if (maxstack)
-        calltree_maxstack_top = site;
-
-    return site;
-
-  fail:
-    return NULL;
-}
-
-/*
- * Buffer the stack from top at low index to bottom at high, so that we can
- * reverse it in calltree.
- */
-static void
-stack_callback(uint32_t frameNumber, void *pc, void *sp, void *closure)
-{
-    stack_buffer_info *info = (stack_buffer_info*) closure;
-
-    /*
-     * If we run out of buffer, keep incrementing entries so that
-     * backtrace can call us again with a bigger buffer.
-     */
-    if (info->entries < info->size)
-        info->buffer[info->entries] = pc;
-    ++info->entries;
-}
-
-/*
- * The caller MUST NOT be holding tmlock when calling backtrace.
- * On return, if *immediate_abort is set, then the return value is NULL
- * and the thread is in a very dangerous situation (e.g. holding
- * sem_pool_lock in Mac OS X pthreads); the caller should bail out
- * without doing anything (such as acquiring locks).
- */
-static callsite *
-backtrace(tm_thread *t, int skipFrames, int *immediate_abort)
-{
-    callsite *site;
-    stack_buffer_info *info = &t->backtrace_buf;
-    void ** new_stack_buffer;
-    size_t new_stack_buffer_size;
-    nsresult rv;
-
-    t->suppress_tracing++;
-
-    if (!stacks_enabled) {
-#if defined(XP_MACOSX)
-        /* Walk the stack, even if stacks_enabled is false. We do this to
-           check if we must set immediate_abort. */
-        info->entries = 0;
-        rv = NS_StackWalk(stack_callback, skipFrames, /* maxFrames */ 0, info,
-                          0, NULL);
-        *immediate_abort = rv == NS_ERROR_UNEXPECTED;
-        if (rv == NS_ERROR_UNEXPECTED || info->entries == 0) {
-            t->suppress_tracing--;
-            return NULL;
-        }
-#endif
-
-        /*
-         * Create a single fake stack frame so that all the tools get
-         * data in the correct format.
-         */
-        *immediate_abort = 0;
-        if (info->size < 1) {
-            PR_ASSERT(!info->buffer); /* !info->size == !info->buffer */
-            info->buffer = __libc_malloc(1 * sizeof(void*));
-            if (!info->buffer)
-                return NULL;
-            info->size = 1;
-        }
-
-        info->entries = 1;
-        info->buffer[0] = STACK_DISABLED_PC;
-    } else {
-        /*
-         * NS_StackWalk can (on Windows) acquire a lock the shared library
-         * loader.  Another thread might call malloc while holding that lock
-         * (when loading a shared library).  So we can't be in tmlock during
-         * this call.  For details, see
-         * https://bugzilla.mozilla.org/show_bug.cgi?id=374829#c8
-         */
-
-        /*
-         * skipFrames == 0 means |backtrace| should show up, so don't use
-         * skipFrames + 1.
-         * NB: this call is repeated below if the buffer is too small.
-         */
-        info->entries = 0;
-        rv = NS_StackWalk(stack_callback, skipFrames, /* maxFrames */ 0, info,
-                          0, NULL);
-        *immediate_abort = rv == NS_ERROR_UNEXPECTED;
-        if (rv == NS_ERROR_UNEXPECTED || info->entries == 0) {
-            t->suppress_tracing--;
-            return NULL;
-        }
-
-        /*
-         * To avoid allocating in stack_callback (which, on Windows, is
-         * called on a different thread from the one we're running on here),
-         * reallocate here if it didn't have a big enough buffer (which
-         * includes the first call on any thread), and call it again.
-         */
-        if (info->entries > info->size) {
-            new_stack_buffer_size = 2 * info->entries;
-            new_stack_buffer = __libc_realloc(info->buffer,
-                                   new_stack_buffer_size * sizeof(void*));
-            if (!new_stack_buffer)
-                return NULL;
-            info->buffer = new_stack_buffer;
-            info->size = new_stack_buffer_size;
-
-            /* and call NS_StackWalk again */
-            info->entries = 0;
-            NS_StackWalk(stack_callback, skipFrames, /* maxFrames */ 0, info,
-                         0, NULL);
-
-            /* same stack */
-            PR_ASSERT(info->entries * 2 == new_stack_buffer_size);
-        }
-    }
-
-    TM_ENTER_LOCK(t);
-
-    site = calltree(info->buffer, info->entries, t);
-
-    tmstats.backtrace_calls++;
-    if (!site) {
-        tmstats.backtrace_failures++;
-        PR_ASSERT(tmstats.backtrace_failures < 100);
-    }
-    TM_EXIT_LOCK(t);
-
-    t->suppress_tracing--;
-    return site;
-}
-
-typedef struct allocation {
-    PLHashEntry entry;
-    size_t      size;
-    FILE        *trackfp;       /* for allocation tracking */
-} allocation;
-
-#define ALLOC_HEAP_SIZE 150000
-
-static allocation alloc_heap[ALLOC_HEAP_SIZE];
-static allocation *alloc_freelist = NULL;
-static int alloc_heap_initialized = 0;
-
-static PLHashEntry *alloc_allocentry(void *pool, const void *key)
-{
-    allocation **listp, *alloc;
-    int n;
-
-    if (!alloc_heap_initialized) {
-        n = ALLOC_HEAP_SIZE;
-        listp = &alloc_freelist;
-        for (alloc = alloc_heap; --n >= 0; alloc++) {
-            *listp = alloc;
-            listp = (allocation**) &alloc->entry.next;
-        }
-        *listp = NULL;
-        alloc_heap_initialized = 1;
-    }
-
-    listp = &alloc_freelist;
-    alloc = *listp;
-    if (!alloc)
-        return __libc_malloc(sizeof(allocation));
-    *listp = (allocation*) alloc->entry.next;
-    return &alloc->entry;
-}
-
-static void alloc_freeentry(void *pool, PLHashEntry *he, unsigned flag)
-{
-    allocation *alloc;
-
-    if (flag != HT_FREE_ENTRY)
-        return;
-    alloc = (allocation*) he;
-    if ((ptrdiff_t)(alloc - alloc_heap) < (ptrdiff_t)ALLOC_HEAP_SIZE) {
-        alloc->entry.next = &alloc_freelist->entry;
-        alloc_freelist = alloc;
-    } else {
-        __libc_free((void*) alloc);
-    }
-}
-
-static PLHashAllocOps alloc_hashallocops = {
-    generic_alloctable, generic_freetable,
-    alloc_allocentry,   alloc_freeentry
-};
-
-static PLHashNumber hash_pointer(const void *key)
-{
-    return (PLHashNumber) key;
-}
-
-static PLHashTable *allocations = NULL;
-
-static PLHashTable *new_allocations(void)
-{
-    allocations = PL_NewHashTable(200000, hash_pointer,
-                                  PL_CompareValues, PL_CompareValues,
-                                  &alloc_hashallocops, NULL);
-    return allocations;
-}
-
-#define get_allocations() (allocations ? allocations : new_allocations())
-
-#if defined(XP_MACOSX)
-
-/* from malloc.c in Libc */
-typedef void
-malloc_logger_t(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
-                uintptr_t result, uint32_t num_hot_frames_to_skip);
-
-extern malloc_logger_t *malloc_logger;
-
-#define MALLOC_LOG_TYPE_ALLOCATE        2
-#define MALLOC_LOG_TYPE_DEALLOCATE      4
-#define MALLOC_LOG_TYPE_HAS_ZONE        8
-#define MALLOC_LOG_TYPE_CLEARED         64
-
-static void
-my_malloc_logger(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
-                 uintptr_t result, uint32_t num_hot_frames_to_skip)
-{
-    uintptr_t all_args[3] = { arg1, arg2, arg3 };
-    uintptr_t *args = all_args + ((type & MALLOC_LOG_TYPE_HAS_ZONE) ? 1 : 0);
-
-    uint32_t alloc_type =
-        type & (MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE);
-    tm_thread *t = tm_get_thread();
-
-    if (alloc_type == (MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE)) {
-        ReallocCallback((void*)args[0], (void*)result, args[1], 0, 0, t);
-    } else if (alloc_type == MALLOC_LOG_TYPE_ALLOCATE) {
-        /*
-         * We don't get size/count information for calloc, so just use
-         * MallocCallback.
-         */
-        MallocCallback((void*)result, args[0], 0, 0, t);
-    } else if (alloc_type == MALLOC_LOG_TYPE_DEALLOCATE) {
-        FreeCallback((void*)args[0], 0, 0, t);
-    }
-}
-
-static void
-StartupHooker(void)
-{
-    PR_ASSERT(!malloc_logger);
-    malloc_logger = my_malloc_logger;
-}
-
-static void
-ShutdownHooker(void)
-{
-    PR_ASSERT(malloc_logger == my_malloc_logger);
-    malloc_logger = NULL;
-}
-
-#elif defined(XP_UNIX)
-
-/*
- * We can't use glibc's malloc hooks because they can't be used in a
- * threadsafe manner.  They require unsetting the hooks to call into the
- * original malloc implementation, and then resetting them when the
- * original implementation returns.  If another thread calls the same
- * allocation function while the hooks are unset, we have no chance to
- * intercept the call.
- */
-
-NS_EXTERNAL_VIS_(__ptr_t)
-malloc(size_t size)
-{
-    uint32_t start, end;
-    __ptr_t ptr;
-    tm_thread *t;
-
-    if (!tracing_enabled || !PR_Initialized() ||
-        (t = tm_get_thread())->suppress_tracing != 0) {
-        return __libc_malloc(size);
-    }
-
-    t->suppress_tracing++;
-    start = PR_IntervalNow();
-    ptr = __libc_malloc(size);
-    end = PR_IntervalNow();
-    t->suppress_tracing--;
-
-    MallocCallback(ptr, size, start, end, t);
-
-    return ptr;
-}
-
-NS_EXTERNAL_VIS_(__ptr_t)
-calloc(size_t count, size_t size)
-{
-    uint32_t start, end;
-    __ptr_t ptr;
-    tm_thread *t;
-
-    if (!tracing_enabled || !PR_Initialized() ||
-        (t = tm_get_thread())->suppress_tracing != 0) {
-        return __libc_calloc(count, size);
-    }
-
-    t->suppress_tracing++;
-    start = PR_IntervalNow();
-    ptr = __libc_calloc(count, size);
-    end = PR_IntervalNow();
-    t->suppress_tracing--;
-
-    CallocCallback(ptr, count, size, start, end, t);
-
-    return ptr;
-}
-
-NS_EXTERNAL_VIS_(__ptr_t)
-realloc(__ptr_t oldptr, size_t size)
-{
-    uint32_t start, end;
-    __ptr_t ptr;
-    tm_thread *t;
-
-    if (!tracing_enabled || !PR_Initialized() ||
-        (t = tm_get_thread())->suppress_tracing != 0) {
-        return __libc_realloc(oldptr, size);
-    }
-
-    t->suppress_tracing++;
-    start = PR_IntervalNow();
-    ptr = __libc_realloc(oldptr, size);
-    end = PR_IntervalNow();
-    t->suppress_tracing--;
-
-    /* FIXME bug 392008: We could race with reallocation of oldptr. */
-    ReallocCallback(oldptr, ptr, size, start, end, t);
-
-    return ptr;
-}
-
-NS_EXTERNAL_VIS_(void*)
-valloc(size_t size)
-{
-    uint32_t start, end;
-    __ptr_t ptr;
-    tm_thread *t;
-
-    if (!tracing_enabled || !PR_Initialized() ||
-        (t = tm_get_thread())->suppress_tracing != 0) {
-        return __libc_valloc(size);
-    }
-
-    t->suppress_tracing++;
-    start = PR_IntervalNow();
-    ptr = __libc_valloc(size);
-    end = PR_IntervalNow();
-    t->suppress_tracing--;
-
-    MallocCallback(ptr, size, start, end, t);
-
-    return ptr;
-}
-
-NS_EXTERNAL_VIS_(void*)
-memalign(size_t boundary, size_t size)
-{
-    uint32_t start, end;
-    __ptr_t ptr;
-    tm_thread *t;
-
-    if (!tracing_enabled || !PR_Initialized() ||
-        (t = tm_get_thread())->suppress_tracing != 0) {
-        return __libc_memalign(boundary, size);
-    }
-
-    t->suppress_tracing++;
-    start = PR_IntervalNow();
-    ptr = __libc_memalign(boundary, size);
-    end = PR_IntervalNow();
-    t->suppress_tracing--;
-
-    MallocCallback(ptr, size, start, end, t);
-
-    return ptr;
-}
-
-NS_EXTERNAL_VIS_(int)
-posix_memalign(void **memptr, size_t alignment, size_t size)
-{
-    __ptr_t ptr = memalign(alignment, size);
-    if (!ptr)
-        return ENOMEM;
-    *memptr = ptr;
-    return 0;
-}
-
-NS_EXTERNAL_VIS_(void)
-free(__ptr_t ptr)
-{
-    uint32_t start, end;
-    tm_thread *t;
-
-    if (!tracing_enabled || !PR_Initialized() ||
-        (t = tm_get_thread())->suppress_tracing != 0) {
-        __libc_free(ptr);
-        return;
-    }
-
-    t->suppress_tracing++;
-    start = PR_IntervalNow();
-    __libc_free(ptr);
-    end = PR_IntervalNow();
-    t->suppress_tracing--;
-
-    /* FIXME bug 392008: We could race with reallocation of ptr. */
-
-    FreeCallback(ptr, start, end, t);
-}
-
-NS_EXTERNAL_VIS_(void)
-cfree(void *ptr)
-{
-    free(ptr);
-}
-
-#define StartupHooker()                 PR_BEGIN_MACRO PR_END_MACRO
-#define ShutdownHooker()                PR_BEGIN_MACRO PR_END_MACRO
-
-#elif defined(XP_WIN32)
-
-/* See nsWinTraceMalloc.cpp. */
-
-#endif
-
-static const char magic[] = NS_TRACE_MALLOC_MAGIC;
-
-static void
-log_header(int logfd)
-{
-    uint32_t ticksPerSec = PR_htonl(PR_TicksPerSecond());
-    (void) write(logfd, magic, NS_TRACE_MALLOC_MAGIC_SIZE);
-    (void) write(logfd, &ticksPerSec, sizeof ticksPerSec);
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocStartup(int logfd)
-{
-    const char* stack_disable_env;
-
-    /* We must be running on the primordial thread. */
-    PR_ASSERT(tracing_enabled == 0);
-    PR_ASSERT(logfp == &default_logfile);
-    tracing_enabled = (logfd >= 0);
-
-    if (logfd >= 3)
-        MozillaRegisterDebugFD(logfd);
-
-    /* stacks are disabled if this env var is set to a non-empty value */
-    stack_disable_env = PR_GetEnv("NS_TRACE_MALLOC_DISABLE_STACKS");
-    stacks_enabled = !stack_disable_env || !*stack_disable_env;
-
-    if (tracing_enabled) {
-        PR_ASSERT(logfp->simsize == 0); /* didn't overflow startup buffer */
-
-        /* Log everything in logfp (aka default_logfile)'s buffer to logfd. */
-        logfp->fd = logfd;
-        logfile_list = &default_logfile;
-        logfp->prevp = &logfile_list;
-        logfile_tail = &logfp->next;
-        log_header(logfd);
-    }
-
-    RegisterTraceMallocShutdown();
-
-    tmlock = PR_NewLock();
-    (void) tm_get_thread(); /* ensure index initialization while it's easy */
-
-    if (tracing_enabled)
-        StartupHooker();
-}
-
-/*
- * Options for log files, with the log file name either as the next option
- * or separated by '=' (e.g. "./mozilla --trace-malloc * malloc.log" or
- * "./mozilla --trace-malloc=malloc.log").
- */
-static const char TMLOG_OPTION[] = "--trace-malloc";
-static const char SDLOG_OPTION[] = "--shutdown-leaks";
-
-#define SHOULD_PARSE_ARG(name_, log_, arg_) \
-    (0 == strncmp(arg_, name_, sizeof(name_) - 1))
-
-#define PARSE_ARG(name_, log_, argv_, i_, consumed_)                          \
-    PR_BEGIN_MACRO                                                            \
-        char _nextchar = argv_[i_][sizeof(name_) - 1];                        \
-        if (_nextchar == '=') {                                               \
-            log_ = argv_[i_] + sizeof(name_);                                 \
-            consumed_ = 1;                                                    \
-        } else if (_nextchar == '\0') {                                       \
-            log_ = argv_[i_+1];                                               \
-            consumed_ = 2;                                                    \
-        }                                                                     \
-    PR_END_MACRO
-
-PR_IMPLEMENT(int)
-NS_TraceMallocStartupArgs(int argc, char **argv)
-{
-    int i, logfd = -1, consumed, logflags;
-    char *tmlogname = NULL, *sdlogname_local = NULL;
-
-    /*
-     * Look for the --trace-malloc <logfile> option early, to avoid missing
-     * early mallocs (we miss static constructors whose output overflows the
-     * log file's static 16K output buffer).
-     */
-    for (i = 1; i < argc; i += consumed) {
-        consumed = 0;
-        if (SHOULD_PARSE_ARG(TMLOG_OPTION, tmlogname, argv[i]))
-            PARSE_ARG(TMLOG_OPTION, tmlogname, argv, i, consumed);
-        else if (SHOULD_PARSE_ARG(SDLOG_OPTION, sdlogname_local, argv[i]))
-            PARSE_ARG(SDLOG_OPTION, sdlogname_local, argv, i, consumed);
-
-        if (consumed) {
-#ifndef XP_WIN32 /* If we don't comment this out, it will crash Windows. */
-            int j;
-            /* Now remove --trace-malloc and its argument from argv. */
-            argc -= consumed;
-            for (j = i; j < argc; ++j)
-                argv[j] = argv[j+consumed];
-            argv[argc] = NULL;
-            consumed = 0; /* don't advance next iteration */
-#endif
-        } else {
-            consumed = 1;
-        }
-    }
-
-    if (tmlogname) {
-#ifdef XP_UNIX
-        int pipefds[2];
-#endif
-
-        switch (*tmlogname) {
-#ifdef XP_UNIX
-          case '|':
-            if (pipe(pipefds) == 0) {
-                pid_t pid = fork();
-                if (pid == 0) {
-                    /* In child: set up stdin, parse args, and exec. */
-                    int maxargc, nargc;
-                    char **nargv, *token;
-
-                    if (pipefds[0] != 0) {
-                        dup2(pipefds[0], 0);
-                        close(pipefds[0]);
-                    }
-                    close(pipefds[1]);
-
-                    tmlogname = strtok(tmlogname + 1, " \t");
-                    maxargc = 3;
-                    nargv = (char **) malloc((maxargc+1) * sizeof(char *));
-                    if (!nargv) exit(1);
-                    nargc = 0;
-                    nargv[nargc++] = tmlogname;
-                    while ((token = strtok(NULL, " \t")) != NULL) {
-                        if (nargc == maxargc) {
-                            maxargc *= 2;
-                            nargv = (char**)
-                                realloc(nargv, (maxargc+1) * sizeof(char*));
-                            if (!nargv) exit(1);
-                        }
-                        nargv[nargc++] = token;
-                    }
-                    nargv[nargc] = NULL;
-
-                    (void) setsid();
-                    execvp(tmlogname, nargv);
-                    exit(127);
-                }
-
-                if (pid > 0) {
-                    /* In parent: set logfd to the pipe's write side. */
-                    close(pipefds[0]);
-                    logfd = pipefds[1];
-                }
-            }
-            if (logfd < 0) {
-                fprintf(stderr,
-                    "%s: can't pipe to trace-malloc child process %s: %s\n",
-                    argv[0], tmlogname, strerror(errno));
-                exit(1);
-            }
-            break;
-#endif /*XP_UNIX*/
-          case '-':
-            /* Don't log from startup, but do prepare to log later. */
-            /* XXX traditional meaning of '-' as option argument is "stdin" or "stdout" */
-            if (tmlogname[1] == '\0')
-                break;
-            /* FALL THROUGH */
-
-          default:
-            logflags = O_CREAT | O_WRONLY | O_TRUNC;
-#if defined(XP_WIN32)
-            /*
-             * Avoid translations on WIN32.
-             */
-            logflags |= O_BINARY;
-#endif
-            logfd = open(tmlogname, logflags, 0644);
-            if (logfd < 0) {
-                fprintf(stderr,
-                    "%s: can't create trace-malloc log named %s: %s\n",
-                    argv[0], tmlogname, strerror(errno));
-                exit(1);
-            }
-            break;
-        }
-    }
-
-    if (sdlogname_local) {
-        strncpy(sdlogname, sdlogname_local, sizeof(sdlogname));
-        sdlogname[sizeof(sdlogname) - 1] = '\0';
-    }
-
-    NS_TraceMallocStartup(logfd);
-    return argc;
-}
-
-PR_IMPLEMENT(PRBool)
-NS_TraceMallocHasStarted(void)
-{
-    return tmlock ? PR_TRUE : PR_FALSE;
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocShutdown(void)
-{
-    logfile *fp;
-
-    if (sdlogname[0])
-        NS_TraceMallocDumpAllocations(sdlogname);
-
-    if (tmstats.backtrace_failures) {
-        fprintf(stderr,
-                "TraceMalloc backtrace failures: %lu (malloc %lu dladdr %lu)\n",
-                (unsigned long) tmstats.backtrace_failures,
-                (unsigned long) tmstats.btmalloc_failures,
-                (unsigned long) tmstats.dladdr_failures);
-    }
-    while ((fp = logfile_list) != NULL) {
-        logfile_list = fp->next;
-        log_tmstats(fp);
-        flush_logfile(fp);
-        if (fp->fd >= 0) {
-            MozillaUnRegisterDebugFD(fp->fd);
-            close(fp->fd);
-            fp->fd = -1;
-        }
-        if (fp != &default_logfile) {
-            if (fp == logfp)
-                logfp = &default_logfile;
-            free((void*) fp);
-        }
-    }
-    if (tmlock) {
-        PRLock *lock = tmlock;
-        tmlock = NULL;
-        PR_DestroyLock(lock);
-    }
-    if (tracing_enabled) {
-        tracing_enabled = 0;
-        ShutdownHooker();
-    }
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocDisable(void)
-{
-    tm_thread *t = tm_get_thread();
-    logfile *fp;
-    uint32_t sample;
-
-    /* Robustify in case of duplicate call. */
-    PR_ASSERT(tracing_enabled);
-    if (tracing_enabled == 0)
-        return;
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    for (fp = logfile_list; fp; fp = fp->next)
-        flush_logfile(fp);
-    sample = --tracing_enabled;
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-    if (sample == 0)
-        ShutdownHooker();
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocEnable(void)
-{
-    tm_thread *t = tm_get_thread();
-    uint32_t sample;
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    sample = ++tracing_enabled;
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-    if (sample == 1)
-        StartupHooker();
-}
-
-PR_IMPLEMENT(int)
-NS_TraceMallocChangeLogFD(int fd)
-{
-    logfile *oldfp, *fp;
-    struct stat sb;
-    tm_thread *t = tm_get_thread();
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    oldfp = logfp;
-    if (oldfp->fd != fd) {
-        flush_logfile(oldfp);
-        fp = get_logfile(fd);
-        if (!fp) {
-            TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-            return -2;
-        }
-        if (fd >= 0 && fstat(fd, &sb) == 0 && sb.st_size == 0)
-            log_header(fd);
-        logfp = fp;
-    }
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-    return oldfp->fd;
-}
-
-static int
-lfd_clr_enumerator(PLHashEntry *he, int i, void *arg)
-{
-    lfdset_entry *le = (lfdset_entry*) he;
-    logfile *fp = (logfile*) arg;
-
-    LFD_CLR(fp->lfd, &le->lfdset);
-    return HT_ENUMERATE_NEXT;
-}
-
-static void
-lfd_clr_walk(callsite *site, logfile *fp)
-{
-    callsite *kid;
-
-    LFD_CLR(fp->lfd, &site->lfdset);
-    for (kid = site->kids; kid; kid = kid->siblings)
-        lfd_clr_walk(kid, fp);
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocCloseLogFD(int fd)
-{
-    logfile *fp;
-    tm_thread *t = tm_get_thread();
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-
-    fp = get_logfile(fd);
-    if (fp) {
-        flush_logfile(fp);
-        if (fp == &default_logfile) {
-            /* Leave default_logfile in logfile_list with an fd of -1. */
-            fp->fd = -1;
-
-            /* NB: we can never free lfd 0, it belongs to default_logfile. */
-            PR_ASSERT(fp->lfd == 0);
-        } else {
-            /* Clear fp->lfd in all possible lfdsets. */
-            PL_HashTableEnumerateEntries(libraries, lfd_clr_enumerator, fp);
-            PL_HashTableEnumerateEntries(methods, lfd_clr_enumerator, fp);
-            lfd_clr_walk(&calltree_root, fp);
-
-            /* Unlink fp from logfile_list, freeing lfd for reallocation. */
-            *fp->prevp = fp->next;
-            if (!fp->next) {
-                PR_ASSERT(logfile_tail == &fp->next);
-                logfile_tail = fp->prevp;
-            }
-
-            /* Reset logfp if we must, then free fp. */
-            if (fp == logfp)
-                logfp = &default_logfile;
-            free((void*) fp);
-        }
-    }
-
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-    MozillaUnRegisterDebugFD(fd);
-    close(fd);
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocLogTimestamp(const char *caption)
-{
-    logfile *fp;
-#ifdef XP_UNIX
-    struct timeval tv;
-#endif
-#ifdef XP_WIN32
-    struct _timeb tb;
-#endif
-    tm_thread *t = tm_get_thread();
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-
-    fp = logfp;
-    log_byte(fp, TM_EVENT_TIMESTAMP);
-
-#ifdef XP_UNIX
-    gettimeofday(&tv, NULL);
-    log_uint32(fp, (uint32_t) tv.tv_sec);
-    log_uint32(fp, (uint32_t) tv.tv_usec);
-#endif
-#ifdef XP_WIN32
-    _ftime(&tb);
-    log_uint32(fp, (uint32_t) tb.time);
-    log_uint32(fp, (uint32_t) tb.millitm);
-#endif
-    log_string(fp, caption);
-
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-static void
-print_stack(FILE *ofp, callsite *site)
-{
-    while (site) {
-        if (site->name || site->parent) {
-            fprintf(ofp, "%s[%s +0x%X]\n",
-                    site->name, site->library, site->offset);
-        }
-        site = site->parent;
-    }
-}
-
-static const char *allocation_format =
-  (sizeof(void*) == 4) ? "\t0x%08zX\n" :
-  (sizeof(void*) == 8) ? "\t0x%016zX\n" :
-  "UNEXPECTED sizeof(void*)";
-
-static int
-allocation_enumerator(PLHashEntry *he, int i, void *arg)
-{
-    allocation *alloc = (allocation*) he;
-    FILE *ofp = (FILE*) arg;
-    callsite *site = (callsite*) he->value;
-
-    size_t *p, *end;
-
-    fprintf(ofp, "%p <%s> (%lu)\n",
-            he->key,
-            nsGetTypeName(he->key),
-            (unsigned long) alloc->size);
-
-    for (p   = (size_t*) he->key,
-         end = (size_t*) ((char*)he->key + alloc->size);
-         p < end; ++p) {
-        fprintf(ofp, allocation_format, *p);
-    }
-
-    print_stack(ofp, site);
-    fputc('\n', ofp);
-    return HT_ENUMERATE_NEXT;
-}
-
-PR_IMPLEMENT(void)
-NS_TraceStack(int skip, FILE *ofp)
-{
-    callsite *site;
-    tm_thread *t = tm_get_thread();
-    int immediate_abort;
-
-    site = backtrace(t, skip + 1, &immediate_abort);
-    while (site) {
-        if (site->name || site->parent) {
-            fprintf(ofp, "%s[%s +0x%X]\n",
-                    site->name, site->library, site->offset);
-        }
-        site = site->parent;
-    }
-}
-
-PR_IMPLEMENT(int)
-NS_TraceMallocDumpAllocations(const char *pathname)
-{
-    FILE *ofp;
-    int rv;
-    int fd;
-
-    tm_thread *t = tm_get_thread();
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-
-    ofp = fopen(pathname, WRITE_FLAGS);
-    if (ofp) {
-        MozillaRegisterDebugFD(fileno(ofp));
-        if (allocations) {
-            PL_HashTableEnumerateEntries(allocations, allocation_enumerator,
-                                         ofp);
-        }
-        rv = ferror(ofp) ? -1 : 0;
-        MozillaUnRegisterDebugFILE(ofp);
-        fclose(ofp);
-    } else {
-        rv = -1;
-    }
-
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-
-    return rv;
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocFlushLogfiles(void)
-{
-    logfile *fp;
-    tm_thread *t = tm_get_thread();
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-
-    for (fp = logfile_list; fp; fp = fp->next)
-        flush_logfile(fp);
-
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-PR_IMPLEMENT(void)
-NS_TrackAllocation(void* ptr, FILE *ofp)
-{
-    allocation *alloc;
-    tm_thread *t = tm_get_thread();
-
-    fprintf(ofp, "Trying to track %p\n", (void*) ptr);
-    setlinebuf(ofp);
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    if (get_allocations()) {
-        alloc = (allocation*)
-                *PL_HashTableRawLookup(allocations, hash_pointer(ptr), ptr);
-        if (alloc) {
-            fprintf(ofp, "Tracking %p\n", (void*) ptr);
-            alloc->trackfp = ofp;
-        } else {
-            fprintf(ofp, "Not tracking %p\n", (void*) ptr);
-        }
-    }
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-PR_IMPLEMENT(void)
-MallocCallback(void *ptr, size_t size, uint32_t start, uint32_t end, tm_thread *t)
-{
-    callsite *site;
-    PLHashEntry *he;
-    allocation *alloc;
-    int immediate_abort;
-
-    if (!tracing_enabled || t->suppress_tracing != 0)
-        return;
-
-    site = backtrace(t, 2, &immediate_abort);
-    if (immediate_abort)
-        return;
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    tmstats.malloc_calls++;
-    if (!ptr) {
-        tmstats.malloc_failures++;
-    } else {
-        if (site) {
-            log_event5(logfp, TM_EVENT_MALLOC,
-                       site->serial, start, end - start,
-                       (uint32_t)NS_PTR_TO_INT32(ptr), size);
-        }
-        if (get_allocations()) {
-            he = PL_HashTableAdd(allocations, ptr, site);
-            if (he) {
-                alloc = (allocation*) he;
-                alloc->size = size;
-                alloc->trackfp = NULL;
-            }
-        }
-    }
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-PR_IMPLEMENT(void)
-CallocCallback(void *ptr, size_t count, size_t size, uint32_t start, uint32_t end, tm_thread *t)
-{
-    callsite *site;
-    PLHashEntry *he;
-    allocation *alloc;
-    int immediate_abort;
-
-    if (!tracing_enabled || t->suppress_tracing != 0)
-        return;
-
-    site = backtrace(t, 2, &immediate_abort);
-    if (immediate_abort)
-        return;
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    tmstats.calloc_calls++;
-    if (!ptr) {
-        tmstats.calloc_failures++;
-    } else {
-        size *= count;
-        if (site) {
-            log_event5(logfp, TM_EVENT_CALLOC,
-                       site->serial, start, end - start,
-                       (uint32_t)NS_PTR_TO_INT32(ptr), size);
-        }
-        if (get_allocations()) {
-            he = PL_HashTableAdd(allocations, ptr, site);
-            if (he) {
-                alloc = (allocation*) he;
-                alloc->size = size;
-                alloc->trackfp = NULL;
-            }
-        }
-    }
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-PR_IMPLEMENT(void)
-ReallocCallback(void * oldptr, void *ptr, size_t size,
-                uint32_t start, uint32_t end, tm_thread *t)
-{
-    callsite *oldsite, *site;
-    size_t oldsize;
-    PLHashNumber hash;
-    PLHashEntry **hep, *he;
-    allocation *alloc;
-    FILE *trackfp = NULL;
-    int immediate_abort;
-
-    if (!tracing_enabled || t->suppress_tracing != 0)
-        return;
-
-    site = backtrace(t, 2, &immediate_abort);
-    if (immediate_abort)
-        return;
-
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    tmstats.realloc_calls++;
-    oldsite = NULL;
-    oldsize = 0;
-    hep = NULL;
-    he = NULL;
-    if (oldptr && get_allocations()) {
-        hash = hash_pointer(oldptr);
-        hep = PL_HashTableRawLookup(allocations, hash, oldptr);
-        he = *hep;
-        if (he) {
-            oldsite = (callsite*) he->value;
-            alloc = (allocation*) he;
-            oldsize = alloc->size;
-            trackfp = alloc->trackfp;
-            if (trackfp) {
-                fprintf(alloc->trackfp,
-                        "\nrealloc(%p, %lu), oldsize %lu, alloc site %p\n",
-                        (void*) ptr, (unsigned long) size,
-                        (unsigned long) oldsize, (void*) oldsite);
-                NS_TraceStack(1, trackfp);
-            }
-        }
-    }
-    if (!ptr && size) {
-        /*
-         * When realloc() fails, the original block is not freed or moved, so
-         * we'll leave the allocation entry untouched.
-         */
-        tmstats.realloc_failures++;
-    } else {
-        if (site) {
-            log_event8(logfp, TM_EVENT_REALLOC,
-                       site->serial, start, end - start,
-                       (uint32_t)NS_PTR_TO_INT32(ptr), size,
-                       oldsite ? oldsite->serial : 0,
-                       (uint32_t)NS_PTR_TO_INT32(oldptr), oldsize);
-        }
-        if (ptr && allocations) {
-            if (ptr != oldptr) {
-                /*
-                 * If we're reallocating (not allocating new space by passing
-                 * null to realloc) and realloc moved the block, free oldptr.
-                 */
-                if (he)
-                    PL_HashTableRawRemove(allocations, hep, he);
-
-                /* Record the new allocation now, setting he. */
-                he = PL_HashTableAdd(allocations, ptr, site);
-            } else {
-                /*
-                 * If we haven't yet recorded an allocation (possibly due to a
-                 * temporary memory shortage), do it now.
-                 */
-                if (!he)
-                    he = PL_HashTableAdd(allocations, ptr, site);
-            }
-            if (he) {
-                alloc = (allocation*) he;
-                alloc->size = size;
-                alloc->trackfp = trackfp;
-            }
-        }
-    }
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-PR_IMPLEMENT(void)
-FreeCallback(void * ptr, uint32_t start, uint32_t end, tm_thread *t)
-{
-    PLHashEntry **hep, *he;
-    callsite *site;
-    allocation *alloc;
-
-    if (!tracing_enabled || t->suppress_tracing != 0)
-        return;
-
-    /*
-     * FIXME: Perhaps we should call backtrace() so we can check for
-     * immediate_abort. However, the only current contexts where
-     * immediate_abort will be true do not call free(), so for now,
-     * let's avoid the cost of backtrace().  See bug 478195.
-     */
-    TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t);
-    tmstats.free_calls++;
-    if (!ptr) {
-        tmstats.null_free_calls++;
-    } else {
-        if (get_allocations()) {
-            hep = PL_HashTableRawLookup(allocations, hash_pointer(ptr), ptr);
-            he = *hep;
-            if (he) {
-                site = (callsite*) he->value;
-                if (site) {
-                    alloc = (allocation*) he;
-                    if (alloc->trackfp) {
-                        fprintf(alloc->trackfp, "\nfree(%p), alloc site %p\n",
-                                (void*) ptr, (void*) site);
-                        NS_TraceStack(1, alloc->trackfp);
-                    }
-                    log_event5(logfp, TM_EVENT_FREE,
-                               site->serial, start, end - start,
-                               (uint32_t)NS_PTR_TO_INT32(ptr), alloc->size);
-                }
-                PL_HashTableRawRemove(allocations, hep, he);
-            }
-        }
-    }
-    TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t);
-}
-
-PR_IMPLEMENT(nsTMStackTraceID)
-NS_TraceMallocGetStackTrace(void)
-{
-    callsite *site;
-    int dummy;
-    tm_thread *t = tm_get_thread();
-
-    PR_ASSERT(t->suppress_tracing == 0);
-
-    site = backtrace(t, 2, &dummy);
-    return (nsTMStackTraceID) site;
-}
-
-PR_IMPLEMENT(void)
-NS_TraceMallocPrintStackTrace(FILE *ofp, nsTMStackTraceID id)
-{
-    print_stack(ofp, (callsite *)id);
-}
-
-#endif /* NS_TRACE_MALLOC */
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsTraceMalloc.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef nsTraceMalloc_h___
-#define nsTraceMalloc_h___
-
-#include <stdint.h>
-#include <stdio.h> /* for FILE */
-#include "prtypes.h"
-
-#ifdef XP_WIN
-#define setlinebuf(stream) setvbuf((stream), (char *)NULL, _IOLBF, 0)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Magic "number" at start of a trace-malloc log file.  Inspired by the PNG
- * magic string, which inspired XPCOM's typelib (.xpt) file magic.  See the
- * NS_TraceMallocStartup comment (below) for magic number differences in log
- * file structure.
- */
-#define NS_TRACE_MALLOC_MAGIC           "XPCOM\nTMLog08\r\n\032"
-#define NS_TRACE_MALLOC_MAGIC_SIZE      16
-
-/**
- * Trace-malloc stats, traced via the 'Z' event at the end of a log file.
- */
-typedef struct nsTMStats {
-    uint32_t calltree_maxstack;
-    uint32_t calltree_maxdepth;
-    uint32_t calltree_parents;
-    uint32_t calltree_maxkids;
-    uint32_t calltree_kidhits;
-    uint32_t calltree_kidmisses;
-    uint32_t calltree_kidsteps;
-    uint32_t callsite_recurrences;
-    uint32_t backtrace_calls;
-    uint32_t backtrace_failures;
-    uint32_t btmalloc_failures;
-    uint32_t dladdr_failures;
-    uint32_t malloc_calls;
-    uint32_t malloc_failures;
-    uint32_t calloc_calls;
-    uint32_t calloc_failures;
-    uint32_t realloc_calls;
-    uint32_t realloc_failures;
-    uint32_t free_calls;
-    uint32_t null_free_calls;
-} nsTMStats;
-
-#define NS_TMSTATS_STATIC_INITIALIZER {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
-
-/**
- * Call NS_TraceMallocStartup with a valid file descriptor to enable logging
- * of compressed malloc traces, including callsite chains.  Integers may be
- * unsigned serial numbers, sizes, or offsets, and require at most 32 bits.
- * They're encoded as follows:
- *   0-127                  0xxxxxxx (binary, one byte)
- *   128-16383              10xxxxxx xxxxxxxx
- *   16384-0x1fffff         110xxxxx xxxxxxxx xxxxxxxx
- *   0x200000-0xfffffff     1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
- *   0x10000000-0xffffffff  11110000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
- * Strings are NUL-terminated ASCII.
- *
- * Event Operands (magic TMLog01)
- *   'L' library serial, shared object filename string
- *   'N' method serial, library serial, demangled name string
- *   'S' site serial, parent serial, method serial, calling pc offset
- *   'M' site serial, malloc size
- *   'C' site serial, calloc size
- *   'R' site serial, realloc oldsize, realloc size
- *   'F' site serial, free size
- *
- * Event Operands (magic TMLog02)
- *   'Z' serialized struct tmstats (20 unsigned integers),
- *       maxkids parent callsite serial,
- *       maxstack top callsite serial
- *
- * Event Operands (magic TMLog03)
- *   'T' seconds, microseconds, caption
- *
- * Event Operands (magic TMLog04)
- *   'R' site serial, realloc size, old site serial, realloc oldsize
- *
- * Event Operands (magic TMLog05)
- *   'M' site serial, address, malloc size
- *   'C' site serial, address, calloc size
- *   'R' site serial, address, realloc size, old site serial,
- *         old address, old size
- *   'F' site serial, address, free size
- *
- * Event Operands (magic TMLog06)
- *   'M' site serial, interval time (end), address, malloc size
- *   'C' site serial, interval time (end), address, calloc size
- *   'R' site serial, interval time (end), address, realloc size,
- *         old site serial, old address, old size
- *   'F' site serial, interval time (end), address, free size
- *
- * Event Operands (magic TMLog07)
- *   'M' site serial, interval time (start), duration, address, malloc size
- *   'C' site serial, interval time (start), duration, address, calloc size
- *   'R' site serial, interval time (start), duration, address, realloc size,
- *         old site serial, old address, old size
- *   'F' site serial, interval time (start), duration, address, free size
- *
- * Event Operands (magic TMLog08)
- *   'G' filename serial, source filename string.
- *   'N' method serial, library serial, source filename serial,
- *         source file linenumber, demangled name string
- *
- * See tools/trace-malloc/bloatblame.c for an example log-file reader.
- */
-#define TM_EVENT_LIBRARY        'L'
-#define TM_EVENT_FILENAME       'G'
-#define TM_EVENT_METHOD         'N'
-#define TM_EVENT_CALLSITE       'S'
-#define TM_EVENT_MALLOC         'M'
-#define TM_EVENT_CALLOC         'C'
-#define TM_EVENT_REALLOC        'R'
-#define TM_EVENT_FREE           'F'
-#define TM_EVENT_STATS          'Z'
-#define TM_EVENT_TIMESTAMP      'T'
-
-PR_EXTERN(void) NS_TraceMallocStartup(int logfd);
-
-/**
- * Initialize malloc tracing, using the ``standard'' startup arguments.
- */
-PR_EXTERN(int) NS_TraceMallocStartupArgs(int argc, char* argv[]);
-
-/**
- * Return PR_TRUE iff |NS_TraceMallocStartup[Args]| has been successfully called.
- */
-PR_EXTERN(PRBool) NS_TraceMallocHasStarted(void);
-
-/**
- * Stop all malloc tracing, flushing any buffered events to the logfile.
- */
-PR_EXTERN(void) NS_TraceMallocShutdown(void);
-
-/**
- * Disable malloc tracing.
- */
-PR_EXTERN(void) NS_TraceMallocDisable(void);
-
-/**
- * Enable malloc tracing.
- */
-PR_EXTERN(void) NS_TraceMallocEnable(void);
-
-/**
- * Change the log file descriptor, flushing any buffered output to the old
- * fd, and writing NS_TRACE_MALLOC_MAGIC to the new file if it is zero length.
- * Return the old fd, so the caller can swap open fds.  Return -2 on failure,
- * which means malloc failure.
- */
-PR_EXTERN(int) NS_TraceMallocChangeLogFD(int fd);
-
-/**
- * Close the file descriptor fd and forget any bookkeeping associated with it.
- * Do nothing if fd is -1.
- */
-PR_EXTERN(void) NS_TraceMallocCloseLogFD(int fd);
-
-/**
- * Emit a timestamp event with the given caption to the current log file. 
- */
-PR_EXTERN(void) NS_TraceMallocLogTimestamp(const char *caption);
-
-/**
- * Walk the stack, dumping frames in standard form to ofp.  If skip is 0,
- * exclude the frames for NS_TraceStack and anything it calls to do the walk.
- * If skip is less than 0, include -skip such frames.  If skip is positive,
- * exclude that many frames leading to the call to NS_TraceStack.
- */
-PR_EXTERN(void)
-NS_TraceStack(int skip, FILE *ofp);
-
-/**
- * Dump a human-readable listing of current allocations and their compressed
- * stack backtraces to the file named by pathname.  Beware this file may have
- * very long lines.
- *
- * Return -1 on error with errno set by the system, 0 on success.
- */
-PR_EXTERN(int)
-NS_TraceMallocDumpAllocations(const char *pathname);
-
-/**
- * Flush all logfile buffers.
- */
-PR_EXTERN(void)
-NS_TraceMallocFlushLogfiles(void);
-
-/**
- * Track all realloc and free calls operating on a given allocation.
- */
-PR_EXTERN(void)
-NS_TrackAllocation(void* ptr, FILE *ofp);
-
-/* opaque type for API */
-typedef struct nsTMStackTraceIDStruct *nsTMStackTraceID;
-
-/**
- * Get an identifier for the stack trace of the current thread (to this
- * function's callsite) that can be used to print that stack trace later.
- */
-PR_EXTERN(nsTMStackTraceID)
-NS_TraceMallocGetStackTrace(void);
-
-/**
- * Print the stack trace identified.
- */
-PR_EXTERN(void)
-NS_TraceMallocPrintStackTrace(FILE *ofp, nsTMStackTraceID id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* nsTraceMalloc_h___ */
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsTraceMallocCallbacks.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* declarations needed by both nsTraceMalloc.c and nsWinTraceMalloc.cpp */
-
-#ifndef NSTRACEMALLOCCALLBACKS_H
-#define NSTRACEMALLOCCALLBACKS_H
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Used by backtrace. */
-typedef struct stack_buffer_info {
-    void **buffer;
-    size_t size;
-    size_t entries;
-} stack_buffer_info;
-
-typedef struct tm_thread tm_thread;
-struct tm_thread {
-    /*
-     * This counter suppresses tracing, in case any tracing code needs
-     * to malloc.
-     */
-    uint32_t suppress_tracing;
-
-    /* buffer for backtrace, below */
-    stack_buffer_info backtrace_buf;
-};
-
-/* implemented in nsTraceMalloc.c */
-tm_thread * tm_get_thread(void);
-
-/* implemented in nsTraceMalloc.c */
-PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize, uint32_t start, uint32_t end, tm_thread *t);
-PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize, uint32_t start, uint32_t end, tm_thread *t);
-PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize, uint32_t start, uint32_t end, tm_thread *t);
-PR_EXTERN(void) FreeCallback(void *aPtr, uint32_t start, uint32_t end, tm_thread *t);
-
-#ifdef XP_WIN32
-/* implemented in nsTraceMalloc.c */
-PR_EXTERN(void) StartupHooker();
-PR_EXTERN(void) ShutdownHooker();
-
-/* implemented in nsWinTraceMalloc.cpp */
-void* dhw_orig_malloc(size_t);
-void* dhw_orig_calloc(size_t, size_t);
-void* dhw_orig_realloc(void*, size_t);
-void dhw_orig_free(void*);
-
-#endif /* defined(XP_WIN32) */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !defined(NSTRACEMALLOCCALLBACKS_H) */
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsTypeInfo.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-  typeinfo.cpp
-	
-  Speculatively use RTTI on a random object. If it contains a pointer at offset 0
-  that is in the current process' address space, and that so on, then attempt to
-  use C++ RTTI's typeid operation to obtain the name of the type.
-  
-  by Patrick C. Beard.
- */
-
-#include <exception> /* Needed for MSVC2010 due to bug 1055675 */
-#include <typeinfo>
-#include <ctype.h>
-
-#include "nsTypeInfo.h"
-
-extern "C" void NS_TraceMallocShutdown();
-
-struct TraceMallocShutdown {
-    TraceMallocShutdown() {}
-    ~TraceMallocShutdown() {
-        NS_TraceMallocShutdown();
-    }
-};
-
-extern "C" void RegisterTraceMallocShutdown() {
-    // This instanciates the dummy class above, and will trigger the class
-    // destructor when libxul is unloaded. This is equivalent to atexit(),
-    // but gracefully handles dlclose().
-    static TraceMallocShutdown t;
-}
-
-class IUnknown {
-public:
-    virtual long QueryInterface() = 0;
-    virtual long AddRef() = 0;
-    virtual long Release() = 0;
-};
-
-#if defined(MACOS)
-
-#include <Processes.h>
-
-class AddressSpace {
-public:
-    AddressSpace();
-    Boolean contains(void* ptr);
-private:
-    ProcessInfoRec mInfo;
-};
-
-AddressSpace::AddressSpace()
-{
-    ProcessSerialNumber psn = { 0, kCurrentProcess };
-    mInfo.processInfoLength = sizeof(mInfo);
-    ::GetProcessInformation(&psn, &mInfo);
-}
-
-Boolean AddressSpace::contains(void* ptr)
-{
-    UInt32 start = UInt32(mInfo.processLocation);
-    return (UInt32(ptr) >= start && UInt32(ptr) < (start + mInfo.processSize));
-}
-
-const char* nsGetTypeName(void* ptr)
-{
-    // construct only one of these per process.
-    static AddressSpace space;
-	
-    // sanity check the vtable pointer, before trying to use RTTI on the object.
-    void** vt = *(void***)ptr;
-    if (vt && !(unsigned(vt) & 0x3) && space.contains(vt) && space.contains(*vt)) {
-	IUnknown* u = static_cast<IUnknown*>(ptr);
-	const char* type = typeid(*u).name();
-        // make sure it looks like a C++ identifier.
-	if (type && (isalnum(type[0]) || type[0] == '_'))
-	    return type;
-    }
-    return "void*";
-}
-
-#endif
-
-// New, more "portable" Linux code is below, but this might be a useful
-// model for other platforms, so keeping.
-//#if defined(linux)
-#if 0
-
-#include <signal.h>
-#include <setjmp.h>
-
-static jmp_buf context;
-
-static void handler(int signum)
-{
-    longjmp(context, signum);
-}
-
-#define attempt() setjmp(context)
-
-class Signaller {
-public:
-    Signaller(int signum);
-    ~Signaller();
-
-private:
-    typedef void (*handler_t) (int signum);
-    int mSignal;
-    handler_t mOldHandler;
-};
-
-Signaller::Signaller(int signum)
-    : mSignal(signum), mOldHandler(signal(signum, &handler))
-{
-}
-
-Signaller::~Signaller()
-{
-    signal(mSignal, mOldHandler);
-}
-
-// The following are pointers that bamboozle our otherwise feeble
-// attempts to "safely" collect type names.
-//
-// XXX this kind of sucks because it means that anyone trying to use
-// this without NSPR will get unresolved symbols when this library
-// loads. It's also not very extensible. Oh well: FIX ME!
-extern "C" {
-    // from nsprpub/pr/src/io/priometh.c (libnspr4.so)
-    extern void* _pr_faulty_methods;
-};
-
-static inline int
-sanity_check_vtable_i386(void** vt)
-{
-    // Now that we're "safe" inside the signal handler, we can
-    // start poking around. If we're really an object with
-    // RTTI, then the second entry in the vtable should point
-    // to a function.
-    //
-    // Let's see if the second entry:
-    //
-    // 1) looks like a 4-byte aligned pointer
-    //
-    // 2) points to something that looks like the following
-    //    i386 instructions:
-    //
-    //    55     push %ebp
-    //    89e5   mov  %esp,%ebp
-    //    53     push %ebx
-    //
-    //    or
-    //
-    //    55     push %ebp
-    //    89e5   mov  %esp,%ebp
-    //    56     push %esi
-    //
-    //    (which is the standard function prologue generated
-    //    by egcs, plus a ``signature'' instruction that appears
-    //    in the typeid() function's implementation).
-    unsigned char** fp1 = reinterpret_cast<unsigned char**>(vt) + 1;
-
-    // Does it look like an address?
-    unsigned char* ip = *fp1;
-    if ((unsigned(ip) & 3) != 0)
-        return 0;
-
-    // Does it look like it refers to the standard prologue?
-    static unsigned char prologue[] = { 0x55, 0x89, 0xE5 };
-    for (unsigned i = 0; i < sizeof(prologue); ++i)
-        if (*ip++ != prologue[i])
-            return 0;
-
-    // Is the next instruction a `push %ebx' or `push %esi'?
-    if (*ip == 0x53 || *ip == 0x56) {
-        return 1;
-    }
-
-    // Nope.  There's another variant that has a `sub' instruction,
-    // followed by a `cmpl' and a `jne'.  Check for that.
-    if (ip[0] == 0x83 && ip[1] == 0xec     // sub
-        && ip[3] == 0x83 && ip[4] == 0x3d  // cmpl
-        && ip[10] == 0x75                  // jne
-        ) {
-        return 1;
-    }
-
-    return 0;
-}
-
-static inline int
-sanity_check_vtable_ppc(void** vt)
-{
-    // XXX write me!
-    return 1;
-}
-
-#if defined(__i386)
-#  define SANITY_CHECK_VTABLE(vt) (sanity_check_vtable_i386(vt))
-#elif defined(PPC)
-#  define SANITY_CHECK_VTABLE(vt) (sanity_check_vtable_ppc(vt))
-#else
-#  define SANITY_CHECK_VTABLE(vt) (1)
-#endif
-
-const char* nsGetTypeName(void* ptr)
-{
-    // sanity check the vtable pointer, before trying to use RTTI on the object.
-    void** vt = *(void***)ptr;
-    if (vt && !(unsigned(vt) & 3) && (vt != &_pr_faulty_methods)) {
-        Signaller s1(SIGSEGV);
-        if (attempt() == 0) {
-            if (SANITY_CHECK_VTABLE(vt)) {
-                // Looks like a function: what the hell, let's call it.
-                IUnknown* u = static_cast<IUnknown*>(ptr);
-                const char* type = typeid(*u).name();
-                // EGCS seems to prefix a length string.
-                while (isdigit(*type)) ++type;
-                return type;
-            }
-        }
-    }
-    return "void*";
-}
-
-#endif
-
-#if defined(linux) || defined(XP_MACOSX)
-
-#define __USE_GNU
-#include <dlfcn.h>
-#include <ctype.h>
-#include <string.h>
-
-const char* nsGetTypeName(void* ptr)
-{
-#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
-    const int expected_offset = 8;
-    const char vtable_sym_start[] = "_ZTV";
-    const int vtable_sym_start_length = sizeof(vtable_sym_start) - 1;
-#else
-    const int expected_offset = 0;
-    const char vtable_sym_start[] = "__vt_";
-    const int vtable_sym_start_length = sizeof(vtable_sym_start) - 1;
-#endif
-    void* vt = *(void**)ptr;
-    Dl_info info;
-    // If dladdr fails, if we're not at the expected offset in the vtable,
-    // or if the symbol name isn't a vtable symbol name, return "void*".
-    if ( !dladdr(vt, &info) ||
-         ((char*)info.dli_saddr) + expected_offset != vt ||
-         !info.dli_sname ||
-         strncmp(info.dli_sname, vtable_sym_start, vtable_sym_start_length))
-        return "void*";
-
-    // skip the garbage at the beginning of things like
-    // __vt_14nsRootBoxFrame (gcc 2.96) or _ZTV14nsRootBoxFrame (gcc 3.0)
-    const char* rv = info.dli_sname + vtable_sym_start_length;
-    while (*rv && isdigit(*rv))
-        ++rv;
-    return rv;
-}
-
-#endif
-
-#ifdef XP_WIN32
-const char* nsGetTypeName(void* ptr)
-{
-  //TODO: COMPLETE THIS
-    return "void*";
-}
-
-#endif //XP_WIN32
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsTypeInfo.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef trace_malloc_nsTypeInfo_h_
-#define trace_malloc_nsTypeInfo_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern const char* nsGetTypeName(void* ptr);
-
-extern void RegisterTraceMallocShutdown();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* trace_malloc_nsTypeInfo_h_ */
deleted file mode 100644
--- a/tools/trace-malloc/lib/nsWinTraceMalloc.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "prinrval.h"
-#include "prlock.h"
-#include "nscore.h"
-
-#include "nsDebugHelpWin32.h"
-#include "nsTraceMallocCallbacks.h"
-
-/***************************************************************************/
-// shows how to use the dhw stuff to hook imported functions
-
-#if _MSC_VER == 1600
-#define NS_DEBUG_CRT "msvcr100d.dll"
-#elif _MSC_VER == 1700
-#define NS_DEBUG_CRT "msvcr110d.dll"
-#elif _MSC_VER == 1800
-#define NS_DEBUG_CRT "msvcr120d.dll"
-#else
-#error "Don't know filename of MSVC debug library."
-#endif
-
-decltype(malloc) dhw_malloc;
-
-DHWImportHooker &getMallocHooker()
-{
-  static DHWImportHooker gMallocHooker(NS_DEBUG_CRT, "malloc", (PROC) dhw_malloc);
-  return gMallocHooker;
-}
-
-void * __cdecl dhw_malloc( size_t size )
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    void* result = DHW_ORIGINAL(malloc, getMallocHooker())(size);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    MallocCallback(result, size, start, end, t);
-    return result;    
-}
-
-decltype(calloc) dhw_calloc;
-
-DHWImportHooker &getCallocHooker()
-{
-  static DHWImportHooker gCallocHooker(NS_DEBUG_CRT, "calloc", (PROC) dhw_calloc);
-  return gCallocHooker;
-}
-
-void * __cdecl dhw_calloc( size_t count, size_t size )
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    void* result = DHW_ORIGINAL(calloc, getCallocHooker())(count,size);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    CallocCallback(result, count, size, start, end, t);
-    return result;    
-}
-
-decltype(free) dhw_free;
-DHWImportHooker &getFreeHooker()
-{
-  static DHWImportHooker gFreeHooker(NS_DEBUG_CRT, "free", (PROC) dhw_free);
-  return gFreeHooker;
-}
-
-void __cdecl dhw_free( void* p )
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    DHW_ORIGINAL(free, getFreeHooker())(p);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    /* FIXME bug 392008: We could race with reallocation of p. */
-    FreeCallback(p, start, end, t);
-}
-
-
-decltype(realloc) dhw_realloc;
-DHWImportHooker &getReallocHooker()
-{
-  static DHWImportHooker gReallocHooker(NS_DEBUG_CRT, "realloc", (PROC) dhw_realloc);
-  return gReallocHooker;
-}
-
-void * __cdecl dhw_realloc(void * pin, size_t size)
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    void* pout = DHW_ORIGINAL(realloc, getReallocHooker())(pin, size);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    /* FIXME bug 392008: We could race with reallocation of pin. */
-    ReallocCallback(pin, pout, size, start, end, t);
-    return pout;
-}
-
-// Note the mangled name!
-void * __cdecl dhw_new(size_t size);
-DHWImportHooker &getNewHooker()
-{
-  static DHWImportHooker gNewHooker(NS_DEBUG_CRT, "??2@YAPAXI@Z", (PROC) dhw_new);
-  return gNewHooker;
-}
-
-void * __cdecl dhw_new(size_t size)
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    void* result = DHW_ORIGINAL(dhw_new, getNewHooker())(size);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    MallocCallback(result, size, start, end, t);//do we need a different one for new?
-    return result;
-}
-
-// Note the mangled name!
-void __cdecl dhw_delete(void* p);
-DHWImportHooker &getDeleteHooker()
-{
-  static DHWImportHooker gDeleteHooker(NS_DEBUG_CRT, "??3@YAXPAX@Z", (PROC) dhw_delete);
-  return gDeleteHooker;
-}
-
-void __cdecl dhw_delete(void* p)
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    DHW_ORIGINAL(dhw_delete, getDeleteHooker())(p);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    FreeCallback(p, start, end, t);
-}
-
-// Note the mangled name!
-void * __cdecl dhw_vec_new(size_t size);
-DHWImportHooker &getVecNewHooker()
-{
-  static DHWImportHooker gVecNewHooker(NS_DEBUG_CRT, "??_U@YAPAXI@Z", (PROC) dhw_vec_new);
-  return gVecNewHooker;
-}
-
-void * __cdecl dhw_vec_new(size_t size)
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing; // need to suppress since new[] calls new
-    uint32_t start = PR_IntervalNow();
-    void* result = DHW_ORIGINAL(dhw_vec_new, getVecNewHooker())(size);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    MallocCallback(result, size, start, end, t);//do we need a different one for new[]?
-    return result;
-}
-
-// Note the mangled name!
-void __cdecl dhw_vec_delete(void* p);
-DHWImportHooker &getVecDeleteHooker()
-{
-  static DHWImportHooker gVecDeleteHooker(NS_DEBUG_CRT, "??_V@YAXPAX@Z", (PROC) dhw_vec_delete);
-  return gVecDeleteHooker;
-}
-
-void __cdecl dhw_vec_delete(void* p)
-{
-    tm_thread *t = tm_get_thread();
-    ++t->suppress_tracing;
-    uint32_t start = PR_IntervalNow();
-    DHW_ORIGINAL(dhw_vec_delete, getVecDeleteHooker())(p);
-    uint32_t end = PR_IntervalNow();
-    --t->suppress_tracing;
-    FreeCallback(p, start, end, t);
-}
-
-/*C Callbacks*/
-PR_IMPLEMENT(void)
-StartupHooker()
-{
-  //run through get all hookers
-  DHWImportHooker &loadlibraryW = DHWImportHooker::getLoadLibraryWHooker();
-  DHWImportHooker &loadlibraryExW = DHWImportHooker::getLoadLibraryExWHooker();
-  DHWImportHooker &loadlibraryA = DHWImportHooker::getLoadLibraryAHooker();
-  DHWImportHooker &loadlibraryExA = DHWImportHooker::getLoadLibraryExAHooker();
-  DHWImportHooker &mallochooker = getMallocHooker();
-  DHWImportHooker &reallochooker = getReallocHooker();
-  DHWImportHooker &callochooker = getCallocHooker();
-  DHWImportHooker &freehooker = getFreeHooker();
-  DHWImportHooker &newhooker = getNewHooker();
-  DHWImportHooker &deletehooker = getDeleteHooker();
-  DHWImportHooker &vecnewhooker = getVecNewHooker();
-  DHWImportHooker &vecdeletehooker = getVecDeleteHooker();
-  printf("Startup Hooker\n");
-}
-
-PR_IMPLEMENT(void)
-ShutdownHooker()
-{
-}
-
-extern "C" {
-  void* dhw_orig_malloc(size_t);
-  void* dhw_orig_calloc(size_t, size_t);
-  void* dhw_orig_realloc(void*, size_t);
-  void dhw_orig_free(void*);
-}
-
-void*
-dhw_orig_malloc(size_t size)
-{
-    return DHW_ORIGINAL(malloc, getMallocHooker())(size);
-}
-
-void*
-dhw_orig_calloc(size_t count, size_t size)
-{
-    return DHW_ORIGINAL(calloc, getCallocHooker())(count,size);
-}
-
-void*
-dhw_orig_realloc(void* pin, size_t size)
-{
-    return DHW_ORIGINAL(realloc, getReallocHooker())(pin, size);
-}
-
-void
-dhw_orig_free(void* p)
-{
-    DHW_ORIGINAL(free, getFreeHooker())(p);
-}
deleted file mode 100644
--- a/tools/trace-malloc/lib/tm.def
+++ /dev/null
@@ -1,19 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-LIBRARY tracemalloc.dll
-
-EXPORTS
-
-NS_TraceMallocStartup
-NS_TraceMallocStartupArgs
-NS_TraceMallocShutdown
-NS_TraceMallocDisable
-NS_TraceMallocEnable
-NS_TraceMallocChangeLogFD
-NS_TraceMallocCloseLogFD
-NS_TraceMallocLogTimestamp
-NS_TraceStack
-NS_TraceMallocDumpAllocations
-NS_TraceMallocFlushLogfiles
deleted file mode 100644
--- a/tools/trace-malloc/live-bloat.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<html>
-<head>
-<title>Live Bloat Dump</title>
-</head>
-<body>
-<button onclick="window.TraceMallocDumpAllocations('allocations.log');">Dump to allocations.log</button>
-</body>
-</html>
\ No newline at end of file
deleted file mode 100755
--- a/tools/trace-malloc/merge.pl
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/perl
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-$argv = $ARGV[0];
-open( bloatFile, $argv ) or die "Can't open $argv: $!\n";
-while (<bloatFile>) {
-    if (/name=/) {
-        ($td,$name,$func,$a,$ntd) = split(/>/, $_);
-        ($fname, $memSize) = split( /&nbsp;/, $func );
-        ($trash, $linkName) = split( /"/, $name );
-        $namesLinks{$fname} = $linkName;
-        if ($namesSizes{$fname}) {
-            $namesSizes{$fname} = $namesSizes{$fname} + $memSize;
-        }
-        else {
-            $namesSizes{$fname} = $memSize;
-        }
-    }
-}
-
-$argv = $ARGV[1];
-if ($argv)
-{
-    open( bloatFile, $argv ) or die "Can't open $argv: $!\n";
-    while (<bloatFile>) {
-        if (/name=/) {
-            ($td,$name,$func,$a,$ntd) = split(/>/, $_);
-            ($fname, $memSize) = split( /&nbsp;/, $func );
-            $namesSizes{$fname} = $namesSizes{$fname} - $memSize;
-        }
-    }
-}
-
-sub byvalue { $namesSizes{$b} <=> $namesSizes{$a} }
-
-
-print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">';
-print "\n<html><head>\n";
-print "<title>Bloat Blame Delta</title>\n";
-print '<link rel="stylesheet" type="text/css" href="blame.css">';
-print "\n</head>\n<body>\n<table>\n";
-print "<thead><tr><td>Memory Allocated</td><td>Function Name</td><td>Link</td></tr></thead>\n";
-
-foreach $key (sort byvalue keys %namesSizes) {
-    if ($namesSizes{$key}) 
-    {
-        print "<tr>\n";
-        print '  <td>', $namesSizes{$key},"</td>\n"; 
-        print "  <td> <a href=\"$ARGV[0]#$namesLinks{$key}\">", $key,  "</a></td>\n";
-        print "</tr>\n"
-    }
-}
-
-print "</table>\n</body></html>";
deleted file mode 100644
--- a/tools/trace-malloc/moz.build
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-if not CONFIG['MOZ_PROFILE_GENERATE']:
-    Program('spacetrace')
-    SOURCES += [
-        'formdata.c',
-        'spacecategory.c',
-        'spacetrace.c',
-    ]
-
-bin_suffix = CONFIG['BIN_SUFFIX']
-
-
-SOURCES += [
-    'tmreader.c',
-]
-
-SimplePrograms([
-    'leakstats',
-    'tmstats',
-], ext='.c')
-
-GeckoSimplePrograms([
-    'bloatblame',
-    'leaksoup',
-])
-
-RESOURCE_FILES += [
-    'spacetrace.css'
-]
deleted file mode 100644
--- a/tools/trace-malloc/rules.txt
+++ /dev/null
@@ -1,442 +0,0 @@
-# Categorization rules for spacetrace
-#
-# This file defines the stack frame rules that will categorize
-# allocations that spacetrace processes. The format of this file is
-#
-#       <categoryname>
-#       initial string match for stack frame n
-#       initial string match for stack frame n+1
-#       initial string match for stack frame n+2
-#
-# The key in the matching rule is that for every rule, we provide a
-# snippet of the stack frame - contiguous substring matches.
-# categorynames and rules substring matches are case sensitive
-#
-# Predefined Categories
-# "All"           - All allocations [default]
-# "uncategorized" - All allocations that don't match any category
-#
-#
-# Suresh Duddi <dp@netscape.com>
-###########################################################################
-# NOTE: This is still under definition
-###########################################################################
-# General principle of categorization:
-#
-# - Each category, in general, denotes a module or feature.
-#
-# - We assign each allocation to the module/feature that directly
-#   caused the allocation irrespective of which higher level module
-#   caused the allocation. There are very few exceptions usually when
-#   an allocation belongs both to a feature-category and to a
-#   module-category.
-#
-# bookmarks
-#       Bookmarks. Mainly initialization. Does not include menu cost.
-# css
-#       Cascading style sheets
-# dom
-#       Memory held by DOM.
-# font
-#       All font stuff
-# global-history
-# html
-#       html parsing and layout
-# layout
-#       reflow, frames, line, view
-# images
-#       All images.
-# jar
-#       jar, zip
-# js
-#       javascript
-# necko
-#       All protocol and uri stuff. All urls created accounted here
-# preferences
-#       Preferences stuff. All js cost for preferences is included here.
-## rdf
-#       Most of the rdf allocations. rdf cost from xul, chromeregistry,
-#       is assigned to xul. 
-#
-# wallet
-#       Form cache.
-#
-# xbl
-#       xbl stuff. Includes js in xbl.
-# xpcom
-#       xpcom, xpt. Allocations for creations of objects are assigned
-#       onto the respective modules 
-# xul
-#       XUL parsing and layout. Includes rdf overhead from xul like
-#       nsChromeRegistry
-# 
-
-
-#
-
-# ===========================================================================
-# Leaf rules. We categorize them out first.
-# All allocations matching these rules DO belong to the category.
-# ===========================================================================
-
-<js>
-nsXULPrototypeScript::Deserialize
-
-<X>
-XSupportsLocale
-
-<X>
-/usr/X11R6/lib/libX11.so
-
-<js>
-JS_Init
-
-<atoms>
-NS_NewPermanentAtom
-
-<images>
-gif_write
-
-<images>
-imgRequest::OnDataAvailable
-
-<images>
-imgLoader::
-
-<images>
-jinit_master_decompress
-
-<images>
-jinit_marker_reader
-
-<images>
-jinit_marker_decompress
-
-<images>
-nsJPEGDecoder::
-
-<images>
-nsGIFDecoder2::
-
-<jar>
-nsZipArchive::BuildFileList
-
-<jar>
-nsZipArchive::ReadInit
-
-<jar>
-nsJARChannel::Open
-
-<xpcom>
-NS_InitXPCOM2
-
-# xpt file loads
-<xpcom>
-xptiInterfaceInfoManager::LoadFile
-
-<xpcom>
-nsGenericModule::Initialize
-
-<intl>
-nsStringBundle
-
-<intl>
-nsLocale::
-
-<intl>
-nsCharsetConverterManager::
-
-<necko>
-nsDiskCacheDevice::Init
-
-<necko>
-nsCacheEntryDescriptor::nsTransportWrapper::OpenOutputStream
-
-<necko>
-nsSocketTransport::
-
-<necko>
-nsCacheService::
-
-<necko>
-nsDiskCacheStreamIO::
-
-<necko>
-nsHttpResponseHead::
-
-<wallet>
-WLLT
-
-<xul>
-nsXULElement::Create
-
-<xul>
-nsXULAttribute::Create
-
-<xul>
-nsXULDocument::AddElementToMap
-
-<xul>
-XULContentSinkImpl::AddAttributes
-
-<xul>
-XULContentSinkImpl::CreateElement
-
-<xul>
-nsXULElement::SetAttr
-
-<xul>
-nsXULDocument::InsertElement
-
-<xul>
-NS_NewXULContentBuilder
-
-<xul>
-nsXULElement::AppendChildTo
-
-<xbl>
-nsXBLPrototypeHandler::AppendHandlerText(
-
-<html>
-FrameArena::AllocateFrame
-
-<global-history>
-nsGlobalHistory::OpenDB
-
-<font>
-nsFontCache::
-
-<font>
-nsFont::nsFont
-
-<gtk>
-gtk_init
-
-<rdf>
-RDFServiceImpl::GetResource
-
-<rdf>
-RDFContentSinkImpl::AddProperties
-
-<rdf>
-RDFContainerImpl::AppendElement
-
-<rdf>
-RDFXMLDataSourceImpl::Assert
-
-<rdf>
-NS_NewRDFInMemoryDataSource
-
-<css>
-CSSLoaderImpl::ParseSheet
-
-<css>
-CSSParserImpl::Parse(
-
-<css>
-NS_NewCSS
-
-<css>
-RuleHash::AppendRule
-
-<css>
-nsRuleNode::GetStyleData
-
-<CSS>
-SelectorList::
-
-<css>
-CSSRuleProcessor::RulesMatching
-
-<css>
-CSSStyleSheetImpl::Clone
-
-<necko>
-nsHttpHeaderArray::
-
-<html>
-nsScanner::Append
-
-<html>
-nsHTMLTokenizer::
-
-<html>
-NS_NewHTMLTokenizer
-
-<html>
-nsSlidingString::
-
-<html>
-nsParser::
-
-<html>
-nsIParserService::
-
-<html>
-nsCParserNode::
-
-<html>
-CNavDTD::CNavDTD
-
-<html>
-nsHTMLDocument::
-
-<layout>
-IncrementalReflow::AddCommand
-
-<layout>
-nsBlockFrame::
-
-<layout>
-nsBoxFrame::
-
-<layout>
-nsImageFrame::
-
-<layout>
-nsInlineFrame::
-
-<layout>
-nsLeafFrame::
-
-<layout>
-nsLineLayout::
-
-<layout>
-nsReflowPath::EnsureSubtreeFor
-
-<layout>
-nsSliderFrame::
-
-<layout>
-nsScrollBoxFrame::
-
-<layout>
-nsTextFrame::
-
-<layout>
-nsTableRowFrame::
-
-<layout>
-nsTableRowGroupFrame::
-
-<layout>
-nsViewManager::
-
-<layout>
-PresShell::ProcessReflowCommands
-
-
-# ======================================================================
-# Rules that match higher up on the stack
-# These go later.
-# ======================================================================
-
-<preferences>
-PREF_
-
-<bookmarks>
-nsBookmarksService::
-
-<xbl>
-nsXBLService::LoadBindings
-
-<xbl>
-nsXBLBinding::ExecuteAttachedHandler
-
-<js>
-nsXULDocument::LoadScript
-
-<js>
-nsXULDocument::ExecuteScript
-
-<xul>
-XULContentSinkImpl::Open
-
-<rdf>
-RDFContentSinkImpl::HandleEndElement
-
-<html>
-HTMLContentSink::AddAttributes
-
-<html>
-HTMLContentSink::OpenContainer
-
-<html>
-HTMLContentSink::CloseContainer
-
-# XXX whom to account LoadImage to? I am going with images.
-<images>
-imgLoader::LoadImage
-
-<html>
-StackArena::
-
-# ======================================================================
-# Even more genralized rules. There could be lots of activity that
-# happens below them in the stack. But we are sure we have categorized
-# a lot of them by using the rules above and know the category of the
-# most of the rest.
-# ======================================================================
-
-<rdf>
-RDFContentSinkImpl::
-
-<dom>
-nsGenericDOMDataNode::
-
-<dom>
-nsDOMClassInfo::
-
-<dom>
-nsDOMSOFactory::
-
-<xul>
-nsXULTemplateBuilder::
-
-<xul>
-XULContentSinkImpl::HandleEndElement
-
-<xul>
-nsChromeRegistry::
-
-<js>
-nsJSContext::EvaluateString
-
-# Almost all of what is left with XULContentSink belongs to xul
-# Also, this was roughly 0.3% of startup memory
-<xul>
-XULContentSinkImpl::
-
-# XXX this is a wild guess -> html What remains here is about
-# XXX 1.5% of startup footprint
-<html>
-HTMLContentSink::
-
-<xbl>
-nsXBLContentSink::
-
-<xbl>
-nsXBLStreamListener::OnDataAvailable
-
-<necko>
-nsIOService::NewURI
-
-<necko>
-nsIOService::NewChannelFromURI
-
-<necko>
-nsSegmentedBuffer::AppendNewSegment
-
-<necko>
-nsHttpChannel::
-
-# Catchalls to help categorize
-# ----------------------------------------------------------------------
-<js-catchall>
-js_
-
-# Everything else
-# ----------------------------------------------------------------------
-# <uncategorized>
-# This is a predefined category. Don't create it yourself.
deleted file mode 100644
--- a/tools/trace-malloc/spacecategory.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-** spacecategory.c
-**
-** Cagtegorizes each allocation using a predefined set of rules
-** and presents a tree of categories for browsing.
-*/
-
-/*
-** Required include files.
-*/
-#include "spacetrace.h"
-#include <ctype.h>
-#include <string.h>
-
-#include "nsQuickSort.h"
-
-#if defined(HAVE_BOUTELL_GD)
-/*
-** See http://www.boutell.com/gd for the GD graphics library.
-** Ports for many platorms exist.
-** Your box may already have the lib (mine did, redhat 7.1 workstation).
-*/
-#include <gd.h>
-#include <gdfontt.h>
-#include <gdfonts.h>
-#include <gdfontmb.h>
-#endif /* HAVE_BOUTELL_GD */
-
-/*
-** AddRule
-**
-** Add a rule into the list of rules maintainted in global
-*/
-int
-AddRule(STGlobals * g, STCategoryRule * rule)
-{
-    if (g->mNRules % ST_ALLOC_STEP == 0) {
-        /* Need more space */
-        STCategoryRule **newrules;
-
-        newrules = (STCategoryRule **) realloc(g->mCategoryRules,
-                                               (g->mNRules +
-                                                ST_ALLOC_STEP) *
-                                               sizeof(STCategoryRule *));
-        if (!newrules) {
-            REPORT_ERROR(__LINE__, AddRule_No_Memory);
-            return -1;
-        }
-        g->mCategoryRules = newrules;
-    }
-    g->mCategoryRules[g->mNRules++] = rule;
-    return 0;
-}
-
-/*
-** AddChild
-**
-** Add the node as a child of the parent node
-*/
-int
-AddChild(STCategoryNode * parent, STCategoryNode * child)
-{
-    if (parent->nchildren % ST_ALLOC_STEP == 0) {
-        /* need more space */
-        STCategoryNode **newnodes;
-
-        newnodes = (STCategoryNode **) realloc(parent->children,
-                                               (parent->nchildren +
-                                                ST_ALLOC_STEP) *
-                                               sizeof(STCategoryNode *));
-        if (!newnodes) {
-            REPORT_ERROR(__LINE__, AddChild_No_Memory);
-            return -1;
-        }
-        parent->children = newnodes;
-    }
-    parent->children[parent->nchildren++] = child;
-    return 0;
-}
-
-int
-Reparent(STCategoryNode * parent, STCategoryNode * child)
-{
-    uint32_t i;
-
-    if (child->parent == parent)
-        return 0;
-
-    /* Remove child from old parent */
-    if (child->parent) {
-        for (i = 0; i < child->parent->nchildren; i++) {
-            if (child->parent->children[i] == child) {
-                /* Remove child from list */
-                if (i + 1 < child->parent->nchildren)
-                    memmove(&child->parent->children[i],
-                            &child->parent->children[i + 1],
-                            (child->parent->nchildren - i -
-                             1) * sizeof(STCategoryNode *));
-                child->parent->nchildren--;
-                break;
-            }
-        }
-    }
-
-    /* Add child into new parent */
-    AddChild(parent, child);
-
-    return 0;
-}
-
-/*
-** findCategoryNode
-**
-** Given a category name, finds the Node corresponding to the category
-*/
-STCategoryNode *
-findCategoryNode(const char *catName, STGlobals * g)
-{
-    uint32_t i;
-
-    for (i = 0; i < g->mNCategoryMap; i++) {
-        if (!strcmp(g->mCategoryMap[i]->categoryName, catName))
-            return g->mCategoryMap[i]->node;
-    }
-
-    /* Check if we are looking for the root node */
-    if (!strcmp(catName, ST_ROOT_CATEGORY_NAME))
-        return &g->mCategoryRoot;
-
-    return NULL;
-}
-
-/*
-** AddCategoryNode
-**
-** Adds a mapping between a category and its Node into the categoryMap
-*/
-int
-AddCategoryNode(STCategoryNode * node, STGlobals * g)
-{
-    if (g->mNCategoryMap % ST_ALLOC_STEP == 0) {
-        /* Need more space */
-        STCategoryMapEntry **newmap =
-            (STCategoryMapEntry **) realloc(g->mCategoryMap,
-                                            (g->mNCategoryMap +
-                                             ST_ALLOC_STEP) *
-                                            sizeof(STCategoryMapEntry *));
-        if (!newmap) {
-            REPORT_ERROR(__LINE__, AddCategoryNode_No_Memory);
-            return -1;
-        }
-        g->mCategoryMap = newmap;
-
-    }
-    g->mCategoryMap[g->mNCategoryMap] =
-        (STCategoryMapEntry *) calloc(1, sizeof(STCategoryMapEntry));
-    if (!g->mCategoryMap[g->mNCategoryMap]) {
-        REPORT_ERROR(__LINE__, AddCategoryNode_No_Memory);
-        return -1;
-    }
-    g->mCategoryMap[g->mNCategoryMap]->categoryName = node->categoryName;
-    g->mCategoryMap[g->mNCategoryMap]->node = node;
-    g->mNCategoryMap++;
-    return 0;
-}
-
-/*
-** NewCategoryNode
-**
-** Creates a new category node for category name 'catname' and makes
-** 'parent' its parent.
-*/
-STCategoryNode *
-NewCategoryNode(const char *catName, STCategoryNode * parent, STGlobals * g)
-{
-    STCategoryNode *node;
-
-    node = (STCategoryNode *) calloc(1, sizeof(STCategoryNode));
-    if (!node)
-        return NULL;
-
-    node->runs =
-        (STRun **) calloc(g->mCommandLineOptions.mContexts, sizeof(STRun *));
-    if (NULL == node->runs) {
-        free(node);
-        return NULL;
-    }
-
-    node->categoryName = catName;
-
-    /* Set parent of child */
-    node->parent = parent;
-
-    /* Set child in parent */
-    AddChild(parent, node);
-
-    /* Add node into mapping table */
-    AddCategoryNode(node, g);
-
-    return node;
-}
-
-/*
-** ProcessCategoryLeafRule
-**
-** Add this into the tree as a leaf node. It doesn't know who its parent is. For now we make
-** root as its parent
-*/
-int
-ProcessCategoryLeafRule(STCategoryRule * leafRule, STCategoryNode * root,
-                        STGlobals * g)
-{
-    STCategoryRule *rule;
-    STCategoryNode *node;
-
-    rule = (STCategoryRule *) calloc(1, sizeof(STCategoryRule));
-    if (!rule)
-        return -1;
-
-    /* Take ownership of all elements of rule */
-    *rule = *leafRule;
-
-    /* Find/Make a STCategoryNode and add it into the tree */
-    node = findCategoryNode(rule->categoryName, g);
-    if (!node)
-        node = NewCategoryNode(rule->categoryName, root, g);
-
-    /* Make sure rule knows which node to access */
-    rule->node = node;
-
-    /* Add rule into rulelist */
-    AddRule(g, rule);
-
-    return 0;
-}
-
-/*
-** ProcessCategoryParentRule
-**
-** Rule has all the children of category as patterns. Sets up the tree so that
-** the parent child relationship is honored.
-*/
-int
-ProcessCategoryParentRule(STCategoryRule * parentRule, STCategoryNode * root,
-                          STGlobals * g)
-{
-    STCategoryNode *node;
-    STCategoryNode *child;
-    uint32_t i;
-
-    /* Find the parent node in the tree. If not make one and add it into the tree */
-    node = findCategoryNode(parentRule->categoryName, g);
-    if (!node) {
-        node = NewCategoryNode(parentRule->categoryName, root, g);
-        if (!node)
-            return -1;
-    }
-
-    /* For every child node, Find/Create it and make it the child of this node */
-    for (i = 0; i < parentRule->npats; i++) {
-        child = findCategoryNode(parentRule->pats[i], g);
-        if (!child) {
-            child = NewCategoryNode(parentRule->pats[i], node, g);
-            if (!child)
-                return -1;
-        }
-        else {
-            /* Reparent child to node. This is because when we created the node
-             ** we would have created it as the child of root. Now we need to
-             ** remove it from root's child list and add it into this node
-             */
-            Reparent(node, child);
-        }
-    }
-
-    return 0;
-}
-
-/*
-** initCategories
-**
-** Initialize all categories. This reads in a file that says how to categorize
-** each callsite, creates a tree of these categories and makes a list of these
-** patterns in order for matching
-*/
-int
-initCategories(STGlobals * g)
-{
-    FILE *fp;
-    char buf[1024], *in;
-    int n;
-    PRBool inrule, leaf;
-    STCategoryRule rule;
-
-    fp = fopen(g->mCommandLineOptions.mCategoryFile, "r");
-    if (!fp) {
-        /* It isn't an error to not have a categories file */
-        REPORT_INFO("No categories file.");
-        return -1;
-    }
-
-    inrule = PR_FALSE;
-    leaf = PR_FALSE;
-
-    memset(&rule, 0, sizeof(rule));
-
-    while (fgets(buf, sizeof(buf), fp) != NULL) {
-        /* Lose the \n */
-        n = strlen(buf);
-        if (buf[n - 1] == '\n')
-            buf[--n] = '\0';
-        in = buf;
-
-        /* skip comments */
-        if (*in == '#')
-            continue;
-
-        /* skip empty lines. If we are in a rule, end the rule. */
-        while (*in && isspace(*in))
-            in++;
-        if (*in == '\0') {
-            if (inrule) {
-                /* End the rule : leaf or non-leaf */
-                if (leaf)
-                    ProcessCategoryLeafRule(&rule, &g->mCategoryRoot, g);
-                else
-                    /* non-leaf */
-                    ProcessCategoryParentRule(&rule, &g->mCategoryRoot, g);
-                inrule = PR_FALSE;
-                memset(&rule, 0, sizeof(rule));
-            }
-            continue;
-        }
-
-        /* if we are in a rule acculumate */
-        if (inrule) {
-            rule.pats[rule.npats] = strdup(in);
-            rule.patlen[rule.npats++] = strlen(in);
-        }
-        else if (*in == '<') {
-            /* Start a category */
-            inrule = PR_TRUE;
-            leaf = PR_TRUE;
-
-            /* Get the category name */
-            in++;
-            n = strlen(in);
-            if (in[n - 1] == '>')
-                in[n - 1] = '\0';
-            rule.categoryName = strdup(in);
-        }
-        else {
-            /* this is a non-leaf category. Should be of the form CategoryName
-             ** followed by list of child category names one per line
-             */
-            inrule = PR_TRUE;
-            leaf = PR_FALSE;
-            rule.categoryName = strdup(in);
-        }
-    }
-
-    /* If we were in a rule when processing the last line, end the rule */
-    if (inrule) {
-        /* End the rule : leaf or non-leaf */
-        if (leaf)
-            ProcessCategoryLeafRule(&rule, &g->mCategoryRoot, g);
-        else
-            /* non-leaf */
-            ProcessCategoryParentRule(&rule, &g->mCategoryRoot, g);
-    }
-
-    /* Add the final "uncategorized" category. We make new memory locations
-     ** for all these to conform to the general principle of all strings are allocated
-     ** so it makes release logic very simple.
-     */
-    memset(&rule, 0, sizeof(rule));
-    rule.categoryName = strdup("uncategorized");
-    rule.pats[0] = strdup("");
-    rule.patlen[0] = 0;
-    rule.npats = 1;
-    ProcessCategoryLeafRule(&rule, &g->mCategoryRoot, g);
-
-    return 0;
-}
-
-/*
-** callsiteMatchesRule
-**
-** Returns the corresponding node if callsite matches the rule. Rule is a sequence
-** of patterns that must match contiguously the callsite.
-*/
-int
-callsiteMatchesRule(tmcallsite * aCallsite, STCategoryRule * aRule)
-{
-    uint32_t patnum = 0;
-    const char *methodName = NULL;
-
-    while (patnum < aRule->npats && aCallsite && aCallsite->method) {
-        methodName = tmmethodnode_name(aCallsite->method);
-        if (!methodName)
-            return 0;
-        if (!*aRule->pats[patnum]
-            || !strncmp(methodName, aRule->pats[patnum],
-                        aRule->patlen[patnum])) {
-            /* We have matched so far. Proceed up the stack and to the next pattern */
-            patnum++;
-            aCallsite = aCallsite->parent;
-        }
-        else {
-            /* Deal with mismatch */
-            if (patnum > 0) {
-                /* contiguous mismatch. Stop */
-                return 0;
-            }
-            /* We still haven't matched the first pattern. Proceed up the stack without
-             ** moving to the next pattern.
-             */
-            aCallsite = aCallsite->parent;
-        }
-    }
-
-    if (patnum == aRule->npats) {
-        /* all patterns matched. We have a winner. */
-#if defined(DEBUG_dp) && 0
-        fprintf(stderr, "[%s] match\n", aRule->categoryName);
-#endif
-        return 1;
-    }
-
-    return 0;
-}
-
-#ifdef DEBUG_dp
-PRIntervalTime _gMatchTime = 0;
-uint32_t _gMatchCount = 0;
-uint32_t _gMatchRules = 0;
-#endif
-
-/*
-** matchAllocation
-**
-** Runs through all rules and returns the node corresponding to
-** a match of the allocation.
-*/
-STCategoryNode *
-matchAllocation(STGlobals * g, STAllocation * aAllocation)
-{
-#ifdef DEBUG_dp
-    PRIntervalTime start = PR_IntervalNow();
-#endif
-    uint32_t rulenum;
-    STCategoryNode *node = NULL;
-    STCategoryRule *rule;
-
-    for (rulenum = 0; rulenum < g->mNRules; rulenum++) {
-#ifdef DEBUG_dp
-        _gMatchRules++;
-#endif
-        rule = g->mCategoryRules[rulenum];
-        if (callsiteMatchesRule(aAllocation->mEvents[0].mCallsite, rule)) {
-            node = rule->node;
-            break;
-        }
-    }
-#ifdef DEBUG_dp
-    _gMatchCount++;
-    _gMatchTime += PR_IntervalNow() - start;
-#endif
-    return node;
-}
-
-/*
-** categorizeAllocation
-**
-** Given an allocation, it adds it into the category tree at the right spot
-** by comparing the allocation to the rules and adding into the right node.
-** Also, does propogation of cost upwards in the tree.
-** The root of the tree is in the globls as the tree is dependent on the
-** category file (options) rather than the run.
-*/
-int
-categorizeAllocation(STOptions * inOptions, STContext * inContext,
-                     STAllocation * aAllocation, STGlobals * g)
-{
-    /* Run through the rules in order to see if this allcation matches
-     ** any of them.
-     */
-    STCategoryNode *node;
-
-    node = matchAllocation(g, aAllocation);
-    if (!node) {
-        /* ugh! it should atleast go into the "uncategorized" node. wierd!
-         */
-        REPORT_ERROR(__LINE__, categorizeAllocation);
-        return -1;
-    }
-
-    /* Create run for node if not already */
-    if (!node->runs[inContext->mIndex]) {
-        /*
-         ** Create run with positive timestamp as we can harvest it later
-         ** for callsite details summarization
-         */
-        node->runs[inContext->mIndex] =
-            createRun(inContext, PR_IntervalNow());
-        if (!node->runs[inContext->mIndex]) {
-            REPORT_ERROR(__LINE__, categorizeAllocation_No_Memory);
-            return -1;
-        }
-    }
-
-    /* Add allocation into node. We expand the table of allocations in steps */
-    if (node->runs[inContext->mIndex]->mAllocationCount % ST_ALLOC_STEP == 0) {
-        /* Need more space */
-        STAllocation **allocs;
-
-        allocs =
-            (STAllocation **) realloc(node->runs[inContext->mIndex]->
-                                      mAllocations,
-                                      (node->runs[inContext->mIndex]->
-                                       mAllocationCount +
-                                       ST_ALLOC_STEP) *
-                                      sizeof(STAllocation *));
-        if (!allocs) {
-            REPORT_ERROR(__LINE__, categorizeAllocation_No_Memory);
-            return -1;
-        }
-        node->runs[inContext->mIndex]->mAllocations = allocs;
-    }
-    node->runs[inContext->mIndex]->mAllocations[node->
-                                                runs[inContext->mIndex]->
-                                                mAllocationCount++] =
-        aAllocation;
-
-    /*
-     ** Make sure run's stats are calculated. We don't go update the parents of allocation
-     ** at this time. That will happen when we focus on this category. This updating of
-     ** stats will provide us fast categoryreports.
-     */
-    recalculateAllocationCost(inOptions, inContext,
-                              node->runs[inContext->mIndex], aAllocation,
-                              PR_FALSE);
-
-    /* Propagate upwards the statistics */
-    /* XXX */
-#if defined(DEBUG_dp) && 0
-    fprintf(stderr, "DEBUG: [%s] match\n", node->categoryName);
-#endif
-    return 0;
-}
-
-typedef PRBool STCategoryNodeProcessor(STRequest * inRequest,
-                                       STOptions * inOptions,
-                                       STContext * inContext,
-                                       void *clientData,
-                                       STCategoryNode * node);
-
-PRBool
-freeNodeRunProcessor(STRequest * inRequest, STOptions * inOptions,
-                     STContext * inContext, void *clientData,
-                     STCategoryNode * node)
-{
-    if (node->runs && node->runs[inContext->mIndex]) {
-        freeRun(node->runs[inContext->mIndex]);
-        node->runs[inContext->mIndex] = NULL;
-    }
-    return PR_TRUE;
-}
-
-PRBool
-freeNodeRunsProcessor(STRequest * inRequest, STOptions * inOptions,
-                      STContext * inContext, void *clientData,
-                      STCategoryNode * node)
-{
-    if (node->runs) {
-        uint32_t loop = 0;
-
-        for (loop = 0; loop < globals.mCommandLineOptions.mContexts; loop++) {
-            if (node->runs[loop]) {
-                freeRun(node->runs[loop]);
-                node->runs[loop] = NULL;
-            }
-        }
-
-        free(node->runs);
-        node->runs = NULL;
-    }
-
-    return PR_TRUE;
-}
-
-#if defined(DEBUG_dp)
-PRBool
-printNodeProcessor(STRequest * inRequest, STOptions * inOptions,
-                   STContext * inContext, void *clientData,
-                   STCategoryNode * node)
-{
-    STCategoryNode *root = (STCategoryNode *) clientData;
-
-    fprintf(stderr, "%-25s [ %9s size", node->categoryName,
-            FormatNumber(node->run ? node->run->mStats[inContext->mIndex].
-                         mSize : 0));
-    fprintf(stderr, ", %5.1f%%",
-            node->run ? ((double) node->run->mStats[inContext->mIndex].mSize /
-                         root->run->mStats[inContext->mIndex].mSize *
-                         100) : 0);
-    fprintf(stderr, ", %7s allocations ]\n",
-            FormatNumber(node->run ? node->run->mStats[inContext->mIndex].
-                         mCompositeCount : 0));
-    return PR_TRUE;
-}
-
-#endif
-
-typedef struct __struct_optcon
-{
-    STOptions *mOptions;
-    STContext *mContext;
-}
-optcon;
-
-/*
-** compareNode
-**
-** qsort callback.
-** Compare the nodes as specified by the options.
-*/
-int
-compareNode(const void *aNode1, const void *aNode2, void *aContext)
-{
-    int retval = 0;
-    STCategoryNode *node1, *node2;
-    uint32_t a, b;
-    optcon *oc = (optcon *) aContext;
-
-    if (!aNode1 || !aNode2 || !oc->mOptions || !oc->mContext)
-        return 0;
-
-    node1 = *((STCategoryNode **) aNode1);
-    node2 = *((STCategoryNode **) aNode2);
-
-    if (node1 && node2) {
-        if (oc->mOptions->mOrderBy == ST_COUNT) {
-            a = (node1->runs[oc->mContext->mIndex]) ? node1->runs[oc->
-                                                                  mContext->
-                                                                  mIndex]->
-                mStats[oc->mContext->mIndex].mCompositeCount : 0;
-            b = (node2->runs[oc->mContext->mIndex]) ? node2->runs[oc->
-                                                                  mContext->
-                                                                  mIndex]->
-                mStats[oc->mContext->mIndex].mCompositeCount : 0;
-        }
-        else {
-            /* Default is by size */
-            a = (node1->runs[oc->mContext->mIndex]) ? node1->runs[oc->
-                                                                  mContext->
-                                                                  mIndex]->
-                mStats[oc->mContext->mIndex].mSize : 0;
-            b = (node2->runs[oc->mContext->mIndex]) ? node2->runs[oc->
-                                                                  mContext->
-