Bug 665247 - Remove unused metering code (r=igor)
authorLuke Wagner <luke@mozilla.com>
Tue, 21 Jun 2011 10:26:22 -0700
changeset 71849 580ad572687b96b6743a4166c06319bb66b108b0
parent 71848 56ea7c0ebe16921f952d0ccf3a835380ea67f08b
child 71850 11d5e81d190f3f2180514383c5e9298230b5fe7b
push idunknown
push userunknown
push dateunknown
reviewersigor
bugs665247
milestone7.0a1
Bug 665247 - Remove unused metering code (r=igor)
js/src/jsapi.cpp
js/src/jsarena.cpp
js/src/jsarena.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsemit.cpp
js/src/jsemit.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcinlines.h
js/src/jsgcmark.cpp
js/src/jsgcstats.cpp
js/src/jsgcstats.h
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jslock.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsparse.cpp
js/src/jspropertytree.cpp
js/src/jspropertytree.h
js/src/jsscope.cpp
js/src/jsscope.h
js/src/jsscopeinlines.h
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jsutil.h
js/src/jsxml.cpp
js/src/prmjtime.cpp
js/src/prmjtime.h
js/src/shell/js.cpp
js/src/tests/js1_5/Regress/jstests.list
js/src/tests/js1_5/Regress/regress-281487.js
js/src/tests/js1_5/Regress/regress-286216.js
js/src/vm/String-inl.h
js/src/vm/String.cpp
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -653,28 +653,16 @@ JSRuntime::JSRuntime()
 
 bool
 JSRuntime::init(uint32 maxbytes)
 {
 #ifdef JS_METHODJIT_SPEW
     JMCheckLogging();
 #endif
 
-#ifdef DEBUG
-    functionMeterFilename = getenv("JS_FUNCTION_STATFILE");
-    if (functionMeterFilename) {
-        if (!methodReadBarrierCountMap.init())
-            return false;
-        if (!unjoinedFunctionCountMap.init())
-            return false;
-    }
-    propTreeStatFilename = getenv("JS_PROPTREE_STATFILE");
-    propTreeDumpFilename = getenv("JS_PROPTREE_DUMPFILE");
-#endif
-
 #ifdef JS_TRACER
     InitJIT();
 #endif
 
     if (!js_InitGC(this, maxbytes))
         return false;
 
     if (!(atomsCompartment = this->new_<JSCompartment>(this)) ||
@@ -811,38 +799,23 @@ JS_NewRuntime(uint32 maxbytes)
 }
 
 JS_PUBLIC_API(void)
 JS_DestroyRuntime(JSRuntime *rt)
 {
     Foreground::delete_(rt);
 }
 
-#ifdef JS_REPRMETER
-namespace reprmeter {
-    extern void js_DumpReprMeter();
-}
-#endif
-
 JS_PUBLIC_API(void)
 JS_ShutDown(void)
 {
 #ifdef MOZ_TRACEVIS
     StopTraceVis();
 #endif
 
-#ifdef JS_OPMETER
-    extern void js_DumpOpMeters();
-    js_DumpOpMeters();
-#endif
-
-#ifdef JS_REPRMETER
-    reprmeter::js_DumpReprMeter();
-#endif
-
 #ifdef JS_THREADSAFE
     js_CleanupLocks();
 #endif
     PRMJ_NowShutdown();
 }
 
 JS_PUBLIC_API(void *)
 JS_GetRuntimePrivate(JSRuntime *rt)
@@ -4798,27 +4771,16 @@ CompileUCFunctionForPrincipalsCommon(JSC
             goto out2;
         }
 
         if (obj && funAtom &&
             !obj->defineProperty(cx, ATOM_TO_JSID(funAtom), ObjectValue(*fun),
                                  NULL, NULL, JSPROP_ENUMERATE)) {
             fun = NULL;
         }
-
-#ifdef JS_SCOPE_DEPTH_METER
-        if (fun && obj) {
-            JSObject *pobj = obj;
-            uintN depth = 1;
-
-            while ((pobj = pobj->getParent()) != NULL)
-                ++depth;
-            JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
-        }
-#endif
     }
 
   out2:
     LAST_FRAME_CHECKS(cx, fun);
     return fun;
 }
 JS_PUBLIC_API(JSFunction *)
 JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj,
--- a/js/src/jsarena.cpp
+++ b/js/src/jsarena.cpp
@@ -48,44 +48,30 @@
 #include "jstypes.h"
 #include "jsstdint.h"
 #include "jsbit.h"
 #include "jsarena.h"
 #include "jsprvtd.h"
 
 using namespace js;
 
-#ifdef JS_ARENAMETER
-static JSArenaStats *arena_stats_list;
-
-#define COUNT(pool,what)  (pool)->stats.what++
-#else
-#define COUNT(pool,what)  /* nothing */
-#endif
-
 #define JS_ARENA_DEFAULT_ALIGN  sizeof(double)
 
 JS_PUBLIC_API(void)
 JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
                  size_t align)
 {
     if (align == 0)
         align = JS_ARENA_DEFAULT_ALIGN;
     pool->mask = JS_BITMASK(JS_CeilingLog2(align));
     pool->first.next = NULL;
     pool->first.base = pool->first.avail = pool->first.limit =
         JS_ARENA_ALIGN(pool, &pool->first + 1);
     pool->current = &pool->first;
     pool->arenasize = size;
-#ifdef JS_ARENAMETER
-    memset(&pool->stats, 0, sizeof pool->stats);
-    pool->stats.name = strdup(name);
-    pool->stats.next = arena_stats_list;
-    arena_stats_list = &pool->stats;
-#endif
 }
 
 /*
  * An allocation that consumes more than pool->arenasize also has a header
  * pointing back to its previous arena's next member.  This header is not
  * included in [a->base, a->limit), so its space can't be wrongly claimed.
  *
  * As the header is a pointer, it must be well-aligned.  If pool->mask is
@@ -160,18 +146,16 @@ JS_ArenaAllocate(JSArenaPool *pool, size
             if (gross < nb)
                 return NULL;
             b = (JSArena *) OffTheBooks::malloc_(gross);
             if (!b)
                 return NULL;
 
             b->next = NULL;
             b->limit = (jsuword)b + gross;
-            JS_COUNT_ARENA(pool,++);
-            COUNT(pool, nmallocs);
 
             /* If oversized, store ap in the header, just before a->base. */
             *ap = a = b;
             JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a));
             if (extra) {
                 a->base = a->avail =
                     ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
                 SET_HEADER(pool, a, ap);
@@ -214,19 +198,16 @@ JS_ArenaRealloc(JSArenaPool *pool, void 
     JS_ASSERT(aoff > pool->arenasize);
     extra = HEADER_SIZE(pool);                  /* oversized header holds ap */
     hdrsz = sizeof *a + extra + pool->mask;     /* header and alignment slop */
     gross = hdrsz + aoff;
     JS_ASSERT(gross > aoff);
     a = (JSArena *) OffTheBooks::realloc_(a, gross);
     if (!a)
         return NULL;
-#ifdef JS_ARENAMETER
-    pool->stats.nreallocs++;
-#endif
 
     if (a != *ap) {
         /* Oops, realloc moved the allocation: update other pointers to a. */
         if (pool->current == *ap)
             pool->current = a;
         b = a->next;
         if (b && b->avail - b->base > pool->arenasize) {
             JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next);
@@ -290,17 +271,16 @@ FreeArenaList(JSArenaPool *pool, JSArena
         JS_CLEAR_UNUSED(a);
     } while ((a = a->next) != NULL);
     a = *ap;
 #endif
 
     do {
         *ap = a->next;
         JS_CLEAR_ARENA(a);
-        JS_COUNT_ARENA(pool,--);
         UnwantedForeground::free_(a);
     } while ((a = *ap) != NULL);
 
     pool->current = head;
 }
 
 JS_PUBLIC_API(void)
 JS_ArenaRelease(JSArenaPool *pool, char *mark)
@@ -318,114 +298,25 @@ JS_ArenaRelease(JSArenaPool *pool, char 
         }
     }
 }
 
 JS_PUBLIC_API(void)
 JS_FreeArenaPool(JSArenaPool *pool)
 {
     FreeArenaList(pool, &pool->first);
-    COUNT(pool, ndeallocs);
 }
 
 JS_PUBLIC_API(void)
 JS_FinishArenaPool(JSArenaPool *pool)
 {
     FreeArenaList(pool, &pool->first);
-#ifdef JS_ARENAMETER
-    {
-        JSArenaStats *stats, **statsp;
-
-        if (pool->stats.name) {
-            UnwantedForeground::free_(pool->stats.name);
-            pool->stats.name = NULL;
-        }
-        for (statsp = &arena_stats_list; (stats = *statsp) != 0;
-             statsp = &stats->next) {
-            if (stats == &pool->stats) {
-                *statsp = stats->next;
-                return;
-            }
-        }
-    }
-#endif
 }
 
 JS_PUBLIC_API(void)
 JS_ArenaFinish()
 {
 }
 
 JS_PUBLIC_API(void)
 JS_ArenaShutDown(void)
 {
 }
-
-#ifdef JS_ARENAMETER
-JS_PUBLIC_API(void)
-JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb)
-{
-    pool->stats.nallocs++;
-    pool->stats.nbytes += nb;
-    if (nb > pool->stats.maxalloc)
-        pool->stats.maxalloc = nb;
-    pool->stats.variance += nb * nb;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr)
-{
-    pool->stats.ninplace++;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr)
-{
-    pool->stats.ngrows++;
-    pool->stats.nbytes += incr;
-    pool->stats.variance -= size * size;
-    size += incr;
-    if (size > pool->stats.maxalloc)
-        pool->stats.maxalloc = size;
-    pool->stats.variance += size * size;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountRelease(JSArenaPool *pool, char *mark)
-{
-    pool->stats.nreleases++;
-}
-
-JS_PUBLIC_API(void)
-JS_ArenaCountRetract(JSArenaPool *pool, char *mark)
-{
-    pool->stats.nfastrels++;
-}
-
-#include <stdio.h>
-
-JS_PUBLIC_API(void)
-JS_DumpArenaStats(FILE *fp)
-{
-    JSArenaStats *stats;
-    double mean, sigma;
-
-    for (stats = arena_stats_list; stats; stats = stats->next) {
-        mean = JS_MeanAndStdDev(stats->nallocs, stats->nbytes, stats->variance,
-                                &sigma);
-
-        fprintf(fp, "\n%s allocation statistics:\n", stats->name);
-        fprintf(fp, "              number of arenas: %u\n", stats->narenas);
-        fprintf(fp, "         number of allocations: %u\n", stats->nallocs);
-        fprintf(fp, "        number of malloc calls: %u\n", stats->nmallocs);
-        fprintf(fp, "       number of deallocations: %u\n", stats->ndeallocs);
-        fprintf(fp, "  number of allocation growths: %u\n", stats->ngrows);
-        fprintf(fp, "    number of in-place growths: %u\n", stats->ninplace);
-        fprintf(fp, " number of realloc'ing growths: %u\n", stats->nreallocs);
-        fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
-        fprintf(fp, "       number of fast releases: %u\n", stats->nfastrels);
-        fprintf(fp, "         total bytes allocated: %u\n", stats->nbytes);
-        fprintf(fp, "          mean allocation size: %g\n", mean);
-        fprintf(fp, "            standard deviation: %g\n", sigma);
-        fprintf(fp, "       maximum allocation size: %u\n", stats->maxalloc);
-    }
-}
-#endif /* JS_ARENAMETER */
--- a/js/src/jsarena.h
+++ b/js/src/jsarena.h
@@ -57,45 +57,21 @@ typedef struct JSArenaPool JSArenaPool;
 
 struct JSArena {
     JSArena     *next;          /* next arena for this lifetime */
     jsuword     base;           /* aligned base address, follows this header */
     jsuword     limit;          /* one beyond last byte in arena */
     jsuword     avail;          /* points to next available byte */
 };
 
-#ifdef JS_ARENAMETER
-typedef struct JSArenaStats JSArenaStats;
-
-struct JSArenaStats {
-    JSArenaStats *next;         /* next in arenaStats list */
-    char        *name;          /* name for debugging */
-    uint32      narenas;        /* number of arenas in pool */
-    uint32      nallocs;        /* number of JS_ARENA_ALLOCATE() calls */
-    uint32      nmallocs;       /* number of malloc() calls */
-    uint32      ndeallocs;      /* number of lifetime deallocations */
-    uint32      ngrows;         /* number of JS_ARENA_GROW() calls */
-    uint32      ninplace;       /* number of in-place growths */
-    uint32      nreallocs;      /* number of arena grow extending reallocs */
-    uint32      nreleases;      /* number of JS_ARENA_RELEASE() calls */
-    uint32      nfastrels;      /* number of "fast path" releases */
-    size_t      nbytes;         /* total bytes allocated */
-    size_t      maxalloc;       /* maximum allocation size in bytes */
-    double      variance;       /* size variance accumulator */
-};
-#endif
-
 struct JSArenaPool {
     JSArena     first;          /* first arena in pool list */
     JSArena     *current;       /* arena from which to allocate space */
     size_t      arenasize;      /* net exact size of a new arena */
     jsuword     mask;           /* alignment mask (power-of-2 - 1) */
-#ifdef JS_ARENAMETER
-    JSArenaStats stats;
-#endif
 };
 
 #define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
 
 #define JS_ARENA_ALLOCATE(p, pool, nb)                                        \
     JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb)
 
 #define JS_ARENA_ALLOCATE_TYPE(p, type, pool)                                 \
@@ -119,42 +95,39 @@ struct JSArenaPool {
         JSArena *_a = (pool)->current;                                        \
         size_t _nb = JS_ARENA_ALIGN(pool, nb);                                \
         jsuword _p = _a->avail;                                               \
         if ((guard) || _p > _a->limit - _nb)                                  \
             _p = (jsuword)JS_ArenaAllocate(pool, _nb);                        \
         else                                                                  \
             _a->avail = _p + _nb;                                             \
         p = (type) _p;                                                        \
-        STATIC_ASSUME(!p || ubound((char *)p) >= nb)                          \
-        JS_ArenaCountAllocation(pool, nb);                                    \
+        STATIC_ASSUME(!p || ubound((char *)p) >= nb);                         \
     JS_END_MACRO
 
 #define JS_ARENA_GROW(p, pool, size, incr)                                    \
     JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
 
 #define JS_ARENA_GROW_CAST(p, type, pool, size, incr)                         \
     JS_BEGIN_MACRO                                                            \
         JSArena *_a = (pool)->current;                                        \
         if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) {         \
             size_t _nb = (size) + (incr);                                     \
             _nb = JS_ARENA_ALIGN(pool, _nb);                                  \
             if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) {        \
                 _a->avail = (jsuword)(p) + _nb;                               \
-                JS_ArenaCountInplaceGrowth(pool, size, incr);                 \
             } else if ((jsuword)(p) == _a->base) {                            \
                 p = (type) JS_ArenaRealloc(pool, p, size, incr);              \
             } else {                                                          \
                 p = (type) JS_ArenaGrow(pool, p, size, incr);                 \
             }                                                                 \
         } else {                                                              \
             p = (type) JS_ArenaGrow(pool, p, size, incr);                     \
         }                                                                     \
         STATIC_ASSUME(!p || ubound((char *)p) >= size + incr);                \
-        JS_ArenaCountGrowth(pool, size, incr);                                \
     JS_END_MACRO
 
 #define JS_ARENA_MARK(pool)     ((void *) (pool)->current->avail)
 #define JS_UPTRDIFF(p,q)        ((jsuword)(p) - (jsuword)(q))
 
 /*
  * Check if the mark is inside arena's allocated area.
  */
@@ -175,29 +148,21 @@ struct JSArenaPool {
 #define JS_ARENA_RELEASE(pool, mark)                                          \
     JS_BEGIN_MACRO                                                            \
         char *_m = (char *)(mark);                                            \
         JSArena *_a = (pool)->current;                                        \
         if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) {            \
             _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m);                    \
             JS_ASSERT(_a->avail <= _a->limit);                                \
             JS_CLEAR_UNUSED(_a);                                              \
-            JS_ArenaCountRetract(pool, _m);                                   \
         } else {                                                              \
             JS_ArenaRelease(pool, _m);                                        \
         }                                                                     \
-        JS_ArenaCountRelease(pool, _m);                                       \
     JS_END_MACRO
 
-#ifdef JS_ARENAMETER
-#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
-#else
-#define JS_COUNT_ARENA(pool,op)
-#endif
-
 #define JS_ARENA_DESTROY(pool, a, pnext)                                      \
     JS_BEGIN_MACRO                                                            \
         JS_COUNT_ARENA(pool,--);                                              \
         if ((pool)->current == (a)) (pool)->current = &(pool)->first;         \
         *(pnext) = (a)->next;                                                 \
         JS_CLEAR_ARENA(a);                                                    \
         js::UnwantedForeground::free_(a);                                      \
         (a) = NULL;                                                           \
@@ -246,43 +211,11 @@ extern JS_PUBLIC_API(void *)
 JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr);
 
 extern JS_PUBLIC_API(void *)
 JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr);
 
 extern JS_PUBLIC_API(void)
 JS_ArenaRelease(JSArenaPool *pool, char *mark);
 
-#ifdef JS_ARENAMETER
-
-#include <stdio.h>
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
-
-extern JS_PUBLIC_API(void)
-JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
-
-extern JS_PUBLIC_API(void)
-JS_DumpArenaStats(FILE *fp);
-
-#else  /* !JS_ARENAMETER */
-
-#define JS_ArenaCountAllocation(ap, nb)                 /* nothing */
-#define JS_ArenaCountInplaceGrowth(ap, size, incr)      /* nothing */
-#define JS_ArenaCountGrowth(ap, size, incr)             /* nothing */
-#define JS_ArenaCountRelease(ap, mark)                  /* nothing */
-#define JS_ArenaCountRetract(ap, mark)                  /* nothing */
-
-#endif /* !JS_ARENAMETER */
-
 JS_END_EXTERN_C
 
 #endif /* jsarena_h___ */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -403,131 +403,16 @@ js_NewContext(JSRuntime *rt, size_t stac
     if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
         js_DestroyContext(cx, JSDCM_NEW_FAILED);
         return NULL;
     }
 
     return cx;
 }
 
-#if defined DEBUG && defined XP_UNIX
-# include <stdio.h>
-
-class JSAutoFile {
-public:
-    JSAutoFile() : mFile(NULL) {}
-
-    ~JSAutoFile() {
-        if (mFile)
-            fclose(mFile);
-    }
-
-    FILE *open(const char *fname, const char *mode) {
-        return mFile = fopen(fname, mode);
-    }
-    operator FILE *() {
-        return mFile;
-    }
-
-private:
-    FILE *mFile;
-};
-
-static void
-DumpEvalCacheMeter(JSContext *cx)
-{
-    if (const char *filename = getenv("JS_EVALCACHE_STATFILE")) {
-        struct {
-            const char *name;
-            ptrdiff_t  offset;
-        } table[] = {
-#define frob(x) { #x, offsetof(JSEvalCacheMeter, x) }
-            EVAL_CACHE_METER_LIST(frob)
-#undef frob
-        };
-        JSEvalCacheMeter *ecm = &cx->compartment->evalCacheMeter;
-
-        static JSAutoFile fp;
-        if (!fp && !fp.open(filename, "w"))
-            return;
-
-        fprintf(fp, "eval cache meter (%p):\n",
-#ifdef JS_THREADSAFE
-                (void *) cx->thread()
-#else
-                (void *) cx->runtime
-#endif
-                );
-        for (uintN i = 0; i < JS_ARRAY_LENGTH(table); ++i) {
-            fprintf(fp, "%-8.8s  %llu\n",
-                    table[i].name,
-                    (unsigned long long int) *(uint64 *)((uint8 *)ecm + table[i].offset));
-        }
-        fprintf(fp, "hit ratio %g%%\n", ecm->hit * 100. / ecm->probe);
-        fprintf(fp, "avg steps %g\n", double(ecm->step) / ecm->probe);
-        fflush(fp);
-    }
-}
-# define DUMP_EVAL_CACHE_METER(cx) DumpEvalCacheMeter(cx)
-
-static void
-DumpFunctionCountMap(const char *title, JSRuntime::FunctionCountMap &map, FILE *fp)
-{
-    fprintf(fp, "\n%s count map:\n", title);
-
-    for (JSRuntime::FunctionCountMap::Range r = map.all(); !r.empty(); r.popFront()) {
-        JSFunction *fun = r.front().key;
-        int32 count = r.front().value;
-
-        fprintf(fp, "%10d %s:%u\n", count, fun->script()->filename, fun->script()->lineno);
-    }
-}
-
-static void
-DumpFunctionMeter(JSContext *cx)
-{
-    if (const char *filename = cx->runtime->functionMeterFilename) {
-        struct {
-            const char *name;
-            ptrdiff_t  offset;
-        } table[] = {
-#define frob(x) { #x, offsetof(JSFunctionMeter, x) }
-            FUNCTION_KIND_METER_LIST(frob)
-#undef frob
-        };
-        JSFunctionMeter *fm = &cx->runtime->functionMeter;
-
-        static JSAutoFile fp;
-        if (!fp && !fp.open(filename, "w"))
-            return;
-
-        fprintf(fp, "function meter (%s):\n", cx->runtime->lastScriptFilename);
-        for (uintN i = 0; i < JS_ARRAY_LENGTH(table); ++i)
-            fprintf(fp, "%-19.19s %d\n", table[i].name, *(int32 *)((uint8 *)fm + table[i].offset));
-
-        DumpFunctionCountMap("method read barrier", cx->runtime->methodReadBarrierCountMap, fp);
-        DumpFunctionCountMap("unjoined function", cx->runtime->unjoinedFunctionCountMap, fp);
-
-        putc('\n', fp);
-        fflush(fp);
-    }
-}
-
-# define DUMP_FUNCTION_METER(cx)   DumpFunctionMeter(cx)
-
-#endif /* DEBUG && XP_UNIX */
-
-#ifndef DUMP_EVAL_CACHE_METER
-# define DUMP_EVAL_CACHE_METER(cx) ((void) 0)
-#endif
-
-#ifndef DUMP_FUNCTION_METER
-# define DUMP_FUNCTION_METER(cx)   ((void) 0)
-#endif
-
 void
 js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
 {
     JSRuntime *rt;
     JSContextCallback cxCallback;
     JSBool last;
 
     JS_ASSERT(!cx->enumerators);
@@ -624,18 +509,16 @@ js_DestroyContext(JSContext *cx, JSDestr
          */
         while (cx->outstandingRequests != 0)
             JS_EndRequest(cx);
 #endif
 
         if (last) {
             GCREASON(LASTCONTEXT);
             js_GC(cx, NULL, GC_LAST_CONTEXT);
-            DUMP_EVAL_CACHE_METER(cx);
-            DUMP_FUNCTION_METER(cx);
 
             /* Take the runtime down, now that it has no contexts or atoms. */
             JS_LOCK_GC(rt);
             rt->state = JSRTS_DOWN;
             JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
         } else {
             if (mode == JSDCM_FORCE_GC) {
                 GCREASON(DESTROYCONTEXT);
@@ -650,19 +533,16 @@ js_DestroyContext(JSContext *cx, JSDestr
     }
 #ifdef JS_THREADSAFE
 #ifdef DEBUG
     JSThread *t = cx->thread();
 #endif
     js_ClearContextThread(cx);
     JS_ASSERT_IF(JS_CLIST_IS_EMPTY(&t->contextList), !t->data.requestDepth);
 #endif
-#ifdef JS_METER_DST_OFFSET_CACHING
-    cx->dstOffsetCache.dumpStats();
-#endif
     JS_UNLOCK_GC(rt);
 #ifdef JS_THREADSAFE
     rt->gcHelperThread.waitBackgroundSweepEnd(rt);
 #endif
     Foreground::delete_(cx);
 }
 
 JSContext *
@@ -1213,22 +1093,16 @@ js_ReportValueErrorFlags(JSContext *cx, 
         return JS_FALSE;
 
     ok = JS_ReportErrorFlagsAndNumber(cx, flags, js_GetErrorMessage,
                                       NULL, errorNumber, bytes, arg1, arg2);
     cx->free_(bytes);
     return ok;
 }
 
-#if defined DEBUG && defined XP_UNIX
-/* For gdb usage. */
-void js_logon(JSContext *cx)  { cx->logfp = stderr; cx->logPrevPc = NULL; }
-void js_logoff(JSContext *cx) { cx->logfp = NULL; }
-#endif
-
 JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {
 #define MSG_DEF(name, number, count, exception, format) \
     { format, count, exception } ,
 #include "js.msg"
 #undef MSG_DEF
 };
 
 JS_FRIEND_API(const JSErrorFormatString *)
@@ -1417,25 +1291,16 @@ DSTOffsetCache::purge()
      *     miss on first use given the range of possible values.  Be careful
      *     to keep these values and the caching algorithm in sync!
      */
     offsetMilliseconds = 0;
     rangeStartSeconds = rangeEndSeconds = INT64_MIN;
     oldOffsetMilliseconds = 0;
     oldRangeStartSeconds = oldRangeEndSeconds = INT64_MIN;
 
-#ifdef JS_METER_DST_OFFSET_CACHING
-    totalCalculations = 0;
-    hit = 0;
-    missIncreasing = missDecreasing = 0;
-    missIncreasingOffsetChangeExpand = missIncreasingOffsetChangeUpper = 0;
-    missDecreasingOffsetChangeExpand = missDecreasingOffsetChangeLower = 0;
-    missLargeIncrease = missLargeDecrease = 0;
-#endif
-
     sanityCheck();
 }
 
 /*
  * Since getDSTOffsetMilliseconds guarantees that all times seen will be
  * positive, we can initialize the range at construction time with large
  * negative numbers to ensure the first computation is always a cache miss and
  * doesn't return a bogus offset.
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -128,28 +128,16 @@ class WeakMapBase;
 struct GSNCache {
     typedef HashMap<jsbytecode *,
                     jssrcnote *,
                     PointerHasher<jsbytecode *, 0>,
                     SystemAllocPolicy> Map;
 
     jsbytecode      *code;
     Map             map;
-#ifdef JS_GSNMETER
-    struct Stats {
-        uint32          hits;
-        uint32          misses;
-        uint32          fills;
-        uint32          purges;
-
-        Stats() : hits(0), misses(0), fills(0), purges(0) { }
-    };
-
-    Stats           stats;
-#endif
 
     GSNCache() : code(NULL) { }
 
     void purge();
 };
  
 inline GSNCache *
 GetGSNCache(JSContext *cx);
@@ -306,37 +294,16 @@ js_InitContextThreadAndLockGC(JSContext 
 /*
  * On entrance the GC lock must be held and it will be held on exit.
  */
 extern void
 js_ClearContextThread(JSContext *cx);
 
 #endif /* JS_THREADSAFE */
 
-#ifdef DEBUG
-# define FUNCTION_KIND_METER_LIST(_)                                          \
-                        _(allfun), _(heavy), _(nofreeupvar), _(onlyfreevar),  \
-                        _(flat), _(badfunarg),                                \
-                        _(joinedsetmethod), _(joinedinitmethod),              \
-                        _(joinedreplace), _(joinedsort), _(joinedmodulepat),  \
-                        _(mreadbarrier), _(mwritebarrier), _(mwslotbarrier),  \
-                        _(unjoined), _(indynamicscope)
-# define identity(x)    x
-
-struct JSFunctionMeter {
-    int32 FUNCTION_KIND_METER_LIST(identity);
-};
-
-# undef identity
-
-# define JS_FUNCTION_METER(cx,x) JS_RUNTIME_METER((cx)->runtime, functionMeter.x)
-#else
-# define JS_FUNCTION_METER(cx,x) ((void)0)
-#endif
-
 typedef enum JSDestroyContextMode {
     JSDCM_NO_GC,
     JSDCM_MAYBE_GC,
     JSDCM_FORCE_GC,
     JSDCM_NEW_FAILED
 } JSDestroyContextMode;
 
 typedef enum JSRuntimeState {
@@ -642,100 +609,16 @@ struct JSRuntime {
      * disabled until a triggered GC at some later moment compresses live
      * types, minimizing rt->shapeGen in the process.
      */
     volatile uint32     shapeGen;
 
     /* Literal table maintained by jsatom.c functions. */
     JSAtomState         atomState;
 
-    /*
-     * Various metering fields are defined at the end of JSRuntime. In this
-     * way there is no need to recompile all the code that refers to other
-     * fields of JSRuntime after enabling the corresponding metering macro.
-     */
-#ifdef JS_DUMP_ENUM_CACHE_STATS
-    int32               nativeEnumProbes;
-    int32               nativeEnumMisses;
-# define ENUM_CACHE_METER(name)     JS_ATOMIC_INCREMENT(&cx->runtime->name)
-#else
-# define ENUM_CACHE_METER(name)     ((void) 0)
-#endif
-
-#ifdef DEBUG
-    /*
-     * NB: emptyShapes (in JSCompartment) is init'ed iff at least one
-     * of these envars is set:
-     *
-     *  JS_PROPTREE_STATFILE  statistics on the property tree forest
-     *  JS_PROPTREE_DUMPFILE  all paths in the property tree forest
-     */
-    const char          *propTreeStatFilename;
-    const char          *propTreeDumpFilename;
-
-    bool meterEmptyShapes() const { return propTreeStatFilename || propTreeDumpFilename; }
-
-    /* String instrumentation. */
-    jsrefcount          liveStrings;
-    jsrefcount          totalStrings;
-    jsrefcount          liveDependentStrings;
-    jsrefcount          totalDependentStrings;
-    jsrefcount          badUndependStrings;
-    double              lengthSum;
-    double              lengthSquaredSum;
-    double              strdepLengthSum;
-    double              strdepLengthSquaredSum;
-
-    /* Script instrumentation. */
-    jsrefcount          liveScripts;
-    jsrefcount          totalScripts;
-    jsrefcount          liveEmptyScripts;
-    jsrefcount          totalEmptyScripts;
-    jsrefcount          highWaterLiveScripts;
-#endif /* DEBUG */
-
-#ifdef JS_SCOPE_DEPTH_METER
-    /*
-     * Stats on runtime prototype chain lookups and scope chain depths, i.e.,
-     * counts of objects traversed on a chain until the wanted id is found.
-     */
-    JSBasicStats        protoLookupDepthStats;
-    JSBasicStats        scopeSearchDepthStats;
-
-    /*
-     * Stats on compile-time host environment and lexical scope chain lengths
-     * (maximum depths).
-     */
-    JSBasicStats        hostenvScopeDepthStats;
-    JSBasicStats        lexicalScopeDepthStats;
-#endif
-
-#ifdef JS_GCMETER
-    js::gc::JSGCStats           gcStats;
-    js::gc::JSGCArenaStats      globalArenaStats[js::gc::FINALIZE_LIMIT];
-#endif
-
-#ifdef DEBUG
-    /*
-     * If functionMeterFilename, set from an envariable in JSRuntime's ctor, is
-     * null, the remaining members in this ifdef'ed group are not initialized.
-     */
-    const char          *functionMeterFilename;
-    JSFunctionMeter     functionMeter;
-    char                lastScriptFilename[1024];
-
-    typedef js::HashMap<JSFunction *,
-                        int32,
-                        js::DefaultHasher<JSFunction *>,
-                        js::SystemAllocPolicy> FunctionCountMap;
-
-    FunctionCountMap    methodReadBarrierCountMap;
-    FunctionCountMap    unjoinedFunctionCountMap;
-#endif
-
     JSWrapObjectCallback wrapObjectCallback;
     JSPreWrapCallback    preWrapObjectCallback;
 
 #ifdef JS_METHODJIT
     /* This measures the size of JITScripts, native maps and IC structs. */
     size_t               mjitDataSize;
 #endif
 
@@ -881,24 +764,16 @@ struct JSRuntime {
      * The function must be called outside the GC lock.
      */
     JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes, JSContext *cx);
 };
 
 /* Common macros to access thread-local caches in JSThread or JSRuntime. */
 #define JS_PROPERTY_CACHE(cx)   (JS_THREAD_DATA(cx)->propertyCache)
 
-#ifdef DEBUG
-# define JS_RUNTIME_METER(rt, which)    JS_ATOMIC_INCREMENT(&(rt)->which)
-# define JS_RUNTIME_UNMETER(rt, which)  JS_ATOMIC_DECREMENT(&(rt)->which)
-#else
-# define JS_RUNTIME_METER(rt, which)    /* nothing */
-# define JS_RUNTIME_UNMETER(rt, which)  /* nothing */
-#endif
-
 #define JS_KEEP_ATOMS(rt)   JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
 #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
 
 #ifdef JS_ARGUMENT_FORMATTER_DEFINED
 /*
  * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
  * formatter functions.  Elements are sorted in non-increasing format string
  * length order.
@@ -1114,20 +989,16 @@ struct JSContext
     JSSharpObjectMap    sharpObjectMap;
     js::BusyArraysSet   busyArrays;
 
     /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
     JSArgumentFormatMap *argumentFormatMap;
 
     /* Last message string and log file for debugging. */
     char                *lastMessage;
-#ifdef DEBUG
-    void                *logfp;
-    jsbytecode          *logPrevPc;
-#endif
 
     /* Per-context optional error reporter. */
     JSErrorReporter     errorReporter;
 
     /* Branch callback. */
     JSOperationCallback operationCallback;
 
     /* Client opaque pointers. */
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -126,23 +126,16 @@ JSCompartment::init()
 {
     chunk = NULL;
     for (unsigned i = 0; i < FINALIZE_LIMIT; i++)
         arenas[i].init();
     freeLists.init();
     if (!crossCompartmentWrappers.init())
         return false;
 
-#ifdef DEBUG
-    if (rt->meterEmptyShapes()) {
-        if (!emptyShapes.init())
-            return false;
-    }
-#endif
-
     regExpAllocator = rt->new_<WTF::BumpPointerAllocator>();
     if (!regExpAllocator)
         return false;
 
     if (!backEdgeTable.init())
         return false;
 
     return true;
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -294,27 +294,16 @@ class JaegerCompartment;
 }
 
 /* Number of potentially reusable scriptsToGC to search for the eval cache. */
 #ifndef JS_EVAL_CACHE_SHIFT
 # define JS_EVAL_CACHE_SHIFT        6
 #endif
 #define JS_EVAL_CACHE_SIZE          JS_BIT(JS_EVAL_CACHE_SHIFT)
 
-#ifdef DEBUG
-# define EVAL_CACHE_METER_LIST(_)   _(probe), _(hit), _(step), _(noscope)
-# define identity(x)                x
-
-struct JSEvalCacheMeter {
-    uint64 EVAL_CACHE_METER_LIST(identity);
-};
-
-# undef identity
-#endif
-
 namespace js {
 
 class NativeIterCache {
     static const size_t SIZE = size_t(1) << 8;
     
     /* Cached native iterators. */
     JSObject            *data[SIZE];
 
@@ -398,20 +387,16 @@ struct JS_FRIEND_API(JSCompartment) {
      */
     js::TraceMonitor             *traceMonitor_;
 #endif
 
   public:
     /* Hashed lists of scripts created by eval to garbage-collect. */
     JSScript                     *scriptsToGC[JS_EVAL_CACHE_SIZE];
 
-#ifdef DEBUG
-    JSEvalCacheMeter             evalCacheMeter;
-#endif
-
     void                         *data;
     bool                         active;  // GC flag, whether there are active frames
     js::WrapperMap               crossCompartmentWrappers;
 
 #ifdef JS_METHODJIT
   private:
     /* This is created lazily because many compartments don't need it. */
     js::mjit::JaegerCompartment  *jaegerCompartment_;
@@ -550,22 +535,16 @@ struct JS_FRIEND_API(JSCompartment) {
 
     size_t backEdgeCount(jsbytecode *pc) const;
     size_t incBackEdgeCount(jsbytecode *pc);
 };
 
 #define JS_SCRIPTS_TO_GC(cx)    ((cx)->compartment->scriptsToGC)
 #define JS_PROPERTY_TREE(cx)    ((cx)->compartment->propertyTree)
 
-#ifdef DEBUG
-#define JS_COMPARTMENT_METER(x) x
-#else
-#define JS_COMPARTMENT_METER(x)
-#endif
-
 /*
  * N.B. JS_ON_TRACE(cx) is true if JIT code is on the stack in the current
  * thread, regardless of whether cx is the context in which that trace is
  * executing. cx must be a context on the current thread.
  */
 static inline bool
 JS_ON_TRACE(JSContext *cx)
 {
@@ -632,22 +611,16 @@ TRACE_PROFILER(JSContext *cx)
 namespace js {
 static inline MathCache *
 GetMathCache(JSContext *cx)
 {
     return cx->compartment->getMathCache(cx);
 }
 }
 
-#ifdef DEBUG
-# define EVAL_CACHE_METER(x)    (cx->compartment->evalCacheMeter.x++)
-#else
-# define EVAL_CACHE_METER(x)    ((void) 0)
-#endif
-
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 namespace js {
 
 class PreserveCompartment {
   protected:
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -1610,17 +1610,16 @@ js_PopStatement(JSTreeContext *tc)
     JSStmtInfo *stmt;
 
     stmt = tc->topStmt;
     tc->topStmt = stmt->down;
     if (STMT_LINKS_SCOPE(stmt)) {
         tc->topScopeStmt = stmt->downScope;
         if (stmt->flags & SIF_SCOPE) {
             tc->blockChainBox = stmt->blockBox->parent;
-            JS_SCOPE_DEPTH_METERING(--tc->scopeDepth);
         }
     }
 }
 
 JSBool
 js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg)
 {
     JSStmtInfo *stmt;
@@ -4639,17 +4638,16 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
          * jsparse.cpp:SetStaticLevel limited static nesting depth to fit in 16
          * bits and to reserve the all-ones value, thereby reserving the magic
          * FREE_UPVAR_COOKIE value. Note the cg2->staticLevel assignment below.
          */
         JS_ASSERT(cg->staticLevel < JS_BITMASK(16) - 1);
         cg2->staticLevel = cg->staticLevel + 1;
 
         /* We measured the max scope depth when we parsed the function. */
-        JS_SCOPE_DEPTH_METERING(cg2->maxScopeDepth = uint16(-1));
         if (!js_EmitFunctionScript(cx, cg2, pn->pn_body))
             pn = NULL;
 
         cg2->~JSCodeGenerator();
         JS_ARENA_RELEASE(cg->codePool, cg2mark);
         cg2 = NULL;
         if (!pn)
             return JS_FALSE;
--- a/js/src/jsemit.h
+++ b/js/src/jsemit.h
@@ -150,24 +150,16 @@ struct JSStmtInfo {
  */
 #define CATCHNOTE(stmt)  ((stmt).update)
 #define GOSUBS(stmt)     ((stmt).breaks)
 #define GUARDJUMP(stmt)  ((stmt).continues)
 
 #define SET_STATEMENT_TOP(stmt, top)                                          \
     ((stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1))
 
-#ifdef JS_SCOPE_DEPTH_METER
-# define JS_SCOPE_DEPTH_METERING(code) ((void) (code))
-# define JS_SCOPE_DEPTH_METERING_IF(cond, code) ((cond) ? (void) (code) : (void) 0)
-#else
-# define JS_SCOPE_DEPTH_METERING(code) ((void) 0)
-# define JS_SCOPE_DEPTH_METERING_IF(code, x) ((void) 0)
-#endif
-
 #define TCF_COMPILING           0x01 /* JSTreeContext is JSCodeGenerator */
 #define TCF_IN_FUNCTION         0x02 /* parsing inside function body */
 #define TCF_RETURN_EXPR         0x04 /* function has 'return expr;' */
 #define TCF_RETURN_VOID         0x08 /* function has 'return;' */
 #define TCF_IN_FOR_INIT         0x10 /* parsing init expr of for; exclude 'in' */
 #define TCF_FUN_SETS_OUTER_NAME 0x20 /* function set outer name (lexical or free) */
 #define TCF_FUN_PARAM_ARGUMENTS 0x40 /* function has parameter named arguments */
 #define TCF_FUN_USES_ARGUMENTS  0x80 /* function uses arguments except as a
@@ -356,49 +348,37 @@ struct JSTreeContext {              /* t
                                        Compiler::compileFunctionBody */
     JSFunctionBox   *functionList;
 
     JSParseNode     *innermostWith; /* innermost WITH parse node */
 
     js::Bindings    bindings;       /* bindings in this code, including
                                        arguments if we're compiling a function */
 
-#ifdef JS_SCOPE_DEPTH_METER
-    uint16          scopeDepth;     /* current lexical scope chain depth */
-    uint16          maxScopeDepth;  /* maximum lexical scope chain depth */
-#endif
-
     void trace(JSTracer *trc);
 
     JSTreeContext(js::Parser *prs)
       : flags(0), bodyid(0), blockidGen(0), parenDepth(0), yieldCount(0), argumentsCount(0),
         topStmt(NULL), topScopeStmt(NULL),
         blockChainBox(NULL), blockNode(NULL), parser(prs),
         yieldNode(NULL), argumentsNode(NULL),
         scopeChain_(NULL), parent(prs->tc), staticLevel(0), funbox(NULL), functionList(NULL),
         innermostWith(NULL), bindings(prs->context, prs->emptyCallShape),
         sharpSlotBase(-1)
     {
         prs->tc = this;
-        JS_SCOPE_DEPTH_METERING(scopeDepth = maxScopeDepth = 0);
     }
 
     /*
      * For functions the tree context is constructed and destructed a second
      * time during code generation. To avoid a redundant stats update in such
      * cases, we store uint16(-1) in maxScopeDepth.
      */
     ~JSTreeContext() {
         parser->tc = this->parent;
-        JS_SCOPE_DEPTH_METERING_IF((maxScopeDepth != uint16(-1)),
-                                   JS_BASIC_STATS_ACCUM(&parser
-                                                          ->context
-                                                          ->runtime
-                                                          ->lexicalScopeDepthStats,
-                                                        maxScopeDepth));
     }
 
     uintN blockid() { return topStmt ? topStmt->blockid : bodyid; }
 
     JSObject *blockChain() {
         return blockChainBox ? blockChainBox->object : NULL;
     }
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -111,27 +111,16 @@ JS_STATIC_ASSERT(JSTRACE_SHAPE  == 2);
 JS_STATIC_ASSERT(JSTRACE_XML    == 3);
 
 /*
  * JS_IS_VALID_TRACE_KIND assumes that JSTRACE_SHAPE is the last non-xml
  * trace kind when JS_HAS_XML_SUPPORT is false.
  */
 JS_STATIC_ASSERT(JSTRACE_SHAPE + 1 == JSTRACE_XML);
 
-#ifdef JS_GCMETER
-# define METER(x)               ((void) (x))
-# define METER_IF(condition, x) ((void) ((condition) && (x)))
-#else
-# define METER(x)               ((void) 0)
-# define METER_IF(condition, x) ((void) 0)
-#endif
-
-# define METER_UPDATE_MAX(maxLval, rval)                                       \
-    METER_IF((maxLval) < (rval), (maxLval) = (rval))
-
 namespace js {
 namespace gc {
 
 /* This array should be const, but that doesn't link right under GCC. */
 FinalizeKind slotsToThingKind[] = {
     /* 0 */  FINALIZE_OBJECT0,  FINALIZE_OBJECT2,  FINALIZE_OBJECT2,  FINALIZE_OBJECT4,
     /* 4 */  FINALIZE_OBJECT4,  FINALIZE_OBJECT8,  FINALIZE_OBJECT8,  FINALIZE_OBJECT8,
     /* 8 */  FINALIZE_OBJECT8,  FINALIZE_OBJECT12, FINALIZE_OBJECT12, FINALIZE_OBJECT12,
@@ -377,36 +366,32 @@ Chunk::allocateArena(JSContext *cx, unsi
     ArenaHeader *aheader = info.emptyArenaListHead;
     info.emptyArenaListHead = aheader->next;
     aheader->init(comp, thingKind, thingSize);
     --info.numFree;
 
     JSRuntime *rt = info.runtime;
     JS_ATOMIC_ADD(&rt->gcBytes, ArenaSize);
     JS_ATOMIC_ADD(&comp->gcBytes, ArenaSize);
-    METER(JS_ATOMIC_INCREMENT(&rt->gcStats.nallarenas));
     if (comp->gcBytes >= comp->gcTriggerBytes)
         TriggerCompartmentGC(comp);
 
     return aheader;
 }
 
 void
 Chunk::releaseArena(ArenaHeader *aheader)
 {
     JSRuntime *rt = info.runtime;
 #ifdef JS_THREADSAFE
     Maybe<AutoLockGC> maybeLock;
     if (rt->gcHelperThread.sweeping)
         maybeLock.construct(info.runtime);
 #endif
     JSCompartment *comp = aheader->compartment;
-    METER(rt->gcStats.afree++);
-    JS_ASSERT(rt->gcStats.nallarenas != 0);
-    METER(JS_ATOMIC_DECREMENT(&rt->gcStats.nallarenas));
 
     JS_ASSERT(size_t(rt->gcBytes) >= ArenaSize);
     JS_ASSERT(size_t(comp->gcBytes) >= ArenaSize);
 #ifdef JS_THREADSAFE
     if (rt->gcHelperThread.sweeping) {
         rt->reduceGCTriggerBytes(GC_HEAP_GROWTH_FACTOR * ArenaSize);
         comp->reduceGCTriggerBytes(GC_HEAP_GROWTH_FACTOR * ArenaSize);
     }
@@ -430,55 +415,48 @@ Chunk::getRuntime()
 inline jsuword
 GetGCChunk(JSRuntime *rt)
 {
     void *p = rt->gcChunkAllocator->alloc();
 #ifdef MOZ_GCTIMER
     if (p)
         JS_ATOMIC_INCREMENT(&newChunkCount);
 #endif
-    METER_IF(p, rt->gcStats.nchunks++);
-    METER_UPDATE_MAX(rt->gcStats.maxnchunks, rt->gcStats.nchunks);
     return reinterpret_cast<jsuword>(p);
 }
 
 inline void
 ReleaseGCChunk(JSRuntime *rt, jsuword chunk)
 {
     void *p = reinterpret_cast<void *>(chunk);
     JS_ASSERT(p);
 #ifdef MOZ_GCTIMER
     JS_ATOMIC_INCREMENT(&destroyChunkCount);
 #endif
-    JS_ASSERT(rt->gcStats.nchunks != 0);
-    METER(rt->gcStats.nchunks--);
     rt->gcChunkAllocator->free_(p);
 }
 
 inline Chunk *
 AllocateGCChunk(JSRuntime *rt)
 {
     Chunk *p = (Chunk *)rt->gcChunkAllocator->alloc();
 #ifdef MOZ_GCTIMER
     if (p)
         JS_ATOMIC_INCREMENT(&newChunkCount);
 #endif
-    METER_IF(p, rt->gcStats.nchunks++);
     return p;
 }
 
 inline void
 ReleaseGCChunk(JSRuntime *rt, Chunk *p)
 {
     JS_ASSERT(p);
 #ifdef MOZ_GCTIMER
     JS_ATOMIC_INCREMENT(&destroyChunkCount);
 #endif
-    JS_ASSERT(rt->gcStats.nchunks != 0);
-    METER(rt->gcStats.nchunks--);
     rt->gcChunkAllocator->free_(p);
 }
 
 inline Chunk *
 PickChunk(JSContext *cx)
 {
     Chunk *chunk = cx->compartment->chunk;
     if (chunk && chunk->hasAvailableArenas())
@@ -613,18 +591,16 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes
 
     /*
      * The assigned value prevents GC from running when GC memory is too low
      * (during JS engine start).
      */
     rt->setGCLastBytes(8192, GC_NORMAL);
 
     rt->gcJitReleaseTime = PRMJ_Now() + JIT_SCRIPT_EIGHTH_LIFETIME;
-
-    METER(PodZero(&rt->gcStats));
     return true;
 }
 
 namespace js {
 
 inline bool
 InFreeList(ArenaHeader *aheader, uintptr_t addr)
 {
@@ -677,23 +653,23 @@ MarkArenaPtrConservatively(JSTracer *trc
      */
     if (InFreeList(aheader, addr))
         return CGCT_NOTLIVE;
 
     T *thing = reinterpret_cast<T *>(addr);
     MarkRoot(trc, thing, "machine stack");
 
 #ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS
-    if (IS_GC_MARKING_TRACER(trc) && static_cast<GCMarker *>(trc)->conservativeDumpFileName)
-        static_cast<GCMarker *>(trc)->conservativeRoots.append(thing);
-#endif
-
-#if defined JS_DUMP_CONSERVATIVE_GC_ROOTS || defined JS_GCMETER
-    if (IS_GC_MARKING_TRACER(trc) && shift)
-        static_cast<GCMarker *>(trc)->conservativeStats.unaligned++;
+    if (IS_GC_MARKING_TRACER(trc)) {
+        GCMarker *marker = static_cast<GCMarker *>(trc);
+        if (marker->conservativeDumpFileName)
+            marker->conservativeRoots.append(thing);
+        if (shift)
+            marker->conservativeStats.unaligned++;
+    }
 #endif
     return CGCT_VALID;
 }
 
 /*
  * Returns CGCT_VALID and mark it if the w can be a  live GC thing and sets
  * thingKind accordingly. Otherwise returns the reason for rejection.
  */
@@ -917,24 +893,16 @@ RecordNativeStackTopForGC(JSContext *cx)
 #ifdef DEBUG
 static void
 CheckLeakedRoots(JSRuntime *rt);
 #endif
 
 void
 js_FinishGC(JSRuntime *rt)
 {
-#ifdef JS_ARENAMETER
-    JS_DumpArenaStats(stdout);
-#endif
-#ifdef JS_GCMETER
-    if (JS_WANT_GC_METER_PRINT)
-        js_DumpGCStats(rt, stdout);
-#endif
-
     /* Delete all remaining Compartments. */
     for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
         JSCompartment *comp = *c;
         comp->finishArenaLists();
         Foreground::delete_(comp);
     }
     rt->compartments.clear();
     rt->atomsCompartment = NULL;
@@ -1221,19 +1189,17 @@ ArenaList::getArenaWithFreeList(JSContex
 
 template<typename T>
 void
 ArenaList::finalizeNow(JSContext *cx)
 {
 #ifdef JS_THREADSAFE
     JS_ASSERT(backgroundFinalizeState == BFS_DONE);
 #endif
-    METER(stats.narenas = uint32(ArenaHeader::CountListLength(head)));
     FinalizeArenas<T>(cx, &head);
-    METER(stats.livearenas = uint32(ArenaHeader::CountListLength(head)));
     cursor = &head;
 }
 
 #ifdef JS_THREADSAFE
 template<typename T>
 inline void
 ArenaList::finalizeLater(JSContext *cx)
 {
@@ -1268,17 +1234,16 @@ ArenaList::finalizeLater(JSContext *cx)
 
 /*static*/ void
 ArenaList::backgroundFinalize(JSContext *cx, ArenaHeader *listHead)
 {
     JS_ASSERT(listHead);
     unsigned thingKind = listHead->getThingKind();
     JSCompartment *comp = listHead->compartment;
     ArenaList *al = &comp->arenas[thingKind];
-    METER(al->stats.narenas = uint32(ArenaHeader::CountListLength(listHead)));
 
     switch (thingKind) {
       default:
         JS_NOT_REACHED("wrong kind");
         break;
       case FINALIZE_OBJECT0_BACKGROUND:
         FinalizeArenas<JSObject>(cx, &listHead);
         break;
@@ -1301,36 +1266,29 @@ ArenaList::backgroundFinalize(JSContext 
         FinalizeArenas<JSString>(cx, &listHead);
         break;
       case FINALIZE_SHORT_STRING:
         FinalizeArenas<JSShortString>(cx, &listHead);
         break;
     }
 
     /*
-     * In stats we should not reflect the arenas allocated after the GC has
-     * finished. So we do not add to livearenas the arenas from al->head.
-     */
-    METER(al->stats.livearenas = uint32(ArenaHeader::CountListLength(listHead)));
-
-    /*
      * After we finish the finalization al->cursor must point to the end of
      * the head list as we emptied the list before the background finalization
      * and the allocation adds new arenas before the cursor.
      */
     AutoLockGC lock(cx->runtime);
     JS_ASSERT(al->backgroundFinalizeState == BFS_RUN);
     JS_ASSERT(!*al->cursor);
     if (listHead) {
         *al->cursor = listHead;
         al->backgroundFinalizeState = BFS_JUST_FINISHED;
     } else {
         al->backgroundFinalizeState = BFS_DONE;
     }
-    METER(UpdateCompartmentGCStats(comp, thingKind));
 }
 
 #endif /* JS_THREADSAFE */
 
 #ifdef DEBUG
 bool
 CheckAllocation(JSContext *cx)
 {
@@ -1352,17 +1310,16 @@ NeedLastDitchGC(JSContext *cx)
 /*
  * Return false only if the GC run but could not bring its memory usage under
  * JSRuntime::gcMaxBytes.
  */
 static bool
 RunLastDitchGC(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
-    METER(rt->gcStats.lastditch++);
 #ifdef JS_THREADSAFE
     Maybe<AutoUnlockAtomsCompartment> maybeUnlockAtomsCompartment;
     if (cx->compartment == rt->atomsCompartment && rt->atomsCompartmentIsLocked)
         maybeUnlockAtomsCompartment.construct(cx);
 #endif
     /* The last ditch GC preserves all atoms. */
     AutoKeepAtoms keep(rt);
     GCREASON(LASTDITCH);
@@ -1424,17 +1381,16 @@ RefillTypedFreeList(JSContext *cx, unsig
          * We failed to allocate any arena. Run the GC if we can unless we
          * have done it already.
          */
         if (!canGC || runGC)
             break;
         runGC = true;
     }
 
-    METER(cx->runtime->gcStats.fail++);
     js_ReportOutOfMemory(cx);
     return NULL;
 }
 
 Cell *
 RefillFinalizableFreeList(JSContext *cx, unsigned thingKind)
 {
     switch (thingKind) {
@@ -1487,40 +1443,37 @@ js_GetGCThingTraceKind(void *thing)
 
 JSBool
 js_LockGCThingRT(JSRuntime *rt, void *thing)
 {
     if (!thing)
         return true;
 
     AutoLockGC lock(rt);
-    if (GCLocks::Ptr p = rt->gcLocksHash.lookupWithDefault(thing, 0))
+    if (GCLocks::Ptr p = rt->gcLocksHash.lookupWithDefault(thing, 0)) {
         p->value++;
-    else
-        return false;
-
-    METER(rt->gcStats.lock++);
-    return true;
+        return true;
+    }
+
+    return false;
 }
 
 void
 js_UnlockGCThingRT(JSRuntime *rt, void *thing)
 {
     if (!thing)
         return;
 
     AutoLockGC lock(rt);
     GCLocks::Ptr p = rt->gcLocksHash.lookup(thing);
 
     if (p) {
         rt->gcPoke = true;
         if (--p->value == 0)
             rt->gcLocksHash.remove(p);
-
-        METER(rt->gcStats.unlock++);
     }
 }
 
 namespace js {
 
 /*
  * When the native stack is low, the GC does not call JS_TraceChildren to mark
  * the reachable "children" of the thing. Rather the thing is put aside and
@@ -1553,35 +1506,32 @@ GCMarker::GCMarker(JSContext *cx)
 #endif
 }
 
 GCMarker::~GCMarker()
 {
 #ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS
     dumpConservativeRoots();
 #endif
-#ifdef JS_GCMETER
-    /* Update total stats. */
-    context->runtime->gcStats.conservative.add(conservativeStats);
-#endif
 }
 
 void
 GCMarker::delayMarkingChildren(const void *thing)
 {
     const Cell *cell = reinterpret_cast<const Cell *>(thing);
     ArenaHeader *aheader = cell->arenaHeader();
     if (aheader->getMarkingDelay()->link) {
         /* Arena already scheduled to be marked later */
         return;
     }
     aheader->getMarkingDelay()->link = unmarkedArenaStackTop;
     unmarkedArenaStackTop = aheader;
-    METER(markLaterArenas++);
-    METER_UPDATE_MAX(cell->compartment()->rt->gcStats.maxunmarked, markLaterArenas);
+#ifdef DEBUG
+    markLaterArenas++;
+#endif
 }
 
 static void
 MarkDelayedChildren(JSTracer *trc, ArenaHeader *aheader)
 {
     unsigned traceKind = GetFinalizableTraceKind(aheader->getThingKind());
     size_t thingSize = aheader->getThingSize();
     Arena *a = aheader->getArena();
@@ -1869,29 +1819,16 @@ MarkRuntime(JSTracer *trc)
     }
 
     /*
      * We mark extra roots at the end so additional colors can be used
      * to implement cycle collection.
      */
     if (rt->gcExtraRootsTraceOp)
         rt->gcExtraRootsTraceOp(trc, rt->gcExtraRootsData);
-
-#ifdef DEBUG
-    if (rt->functionMeterFilename) {
-        for (int k = 0; k < 2; k++) {
-            typedef JSRuntime::FunctionCountMap HM;
-            HM &h = (k == 0) ? rt->methodReadBarrierCountMap : rt->unjoinedFunctionCountMap;
-            for (HM::Range r = h.all(); !r.empty(); r.popFront()) {
-                JSFunction *fun = r.front().key;
-                JS_CALL_OBJECT_TRACER(trc, fun, "FunctionCountMap key");
-            }
-        }
-    }
-#endif
 }
 
 void
 TriggerGC(JSRuntime *rt)
 {
     JS_ASSERT(!rt->gcRunning);
     if (rt->gcIsNeeded)
         return;
@@ -2264,23 +2201,16 @@ MarkAndSweep(JSContext *cx, JSCompartmen
 
     /* Clear gcIsNeeded now, when we are about to start a normal GC cycle. */
     rt->gcIsNeeded = false;
     rt->gcTriggerCompartment = NULL;
 
     /* Reset malloc counter. */
     rt->resetGCMallocBytes();
 
-#ifdef JS_DUMP_SCOPE_METERS
-    {
-        extern void js_DumpScopeMeters(JSRuntime *rt);
-        js_DumpScopeMeters(rt);
-    }
-#endif
-
     /*
      * Reset the property cache's type id generator so we can compress ids.
      * Same for the protoHazardShape proxy-shape standing in for all object
      * prototypes having readonly or setter properties.
      */
     if (rt->shapeGen & SHAPE_OVERFLOW_BIT || (rt->gcZeal() && !rt->gcCurrentCompartment)) {
         rt->gcRegenShapes = true;
         rt->shapeGen = 0;
@@ -2389,25 +2319,16 @@ MarkAndSweep(JSContext *cx, JSCompartmen
             (*c)->finalizeStringArenaLists(cx);
 
         GCTIMESTAMP(sweepStringEnd);
 
         for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
             (*c)->finalizeShapeArenaLists(cx);
 
         GCTIMESTAMP(sweepShapeEnd);
-
-#ifdef DEBUG
-        for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c)
-            (*c)->propertyTree.dumpShapeStats();
-#endif
-#ifdef JS_GCMETER
-        for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c)
-            UpdateAllCompartmentGCStats(*c);
-#endif
     }
 
 #ifdef DEBUG
      PropertyTree::dumpShapes(cx);
 #endif
 
     if (!comp) {
         SweepCompartments(cx, gckind);
@@ -2752,19 +2673,16 @@ js_GC(JSContext *cx, JSCompartment *comp
          * On shutdown, iterate until finalizers or the JSGC_END callback
          * stop creating garbage.
          */
     } while (gckind == GC_LAST_CONTEXT && rt->gcPoke);
 
     rt->gcNextFullGCTime = PRMJ_Now() + GC_IDLE_FULL_SPAN;
 
     rt->gcChunkAllocationSinceLastGC = false;
-#ifdef JS_GCMETER
-    js_DumpGCStats(cx->runtime, stderr);
-#endif
     GCTIMER_END(gckind == GC_LAST_CONTEXT);
 }
 
 namespace js {
 
 class AutoCopyFreeListToArenas {
     JSRuntime *rt;
 
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -283,25 +283,16 @@ struct ArenaHeader {
 
     size_t getThingSize() const {
         return GCThingSizeMap[getThingKind()];
     }
 
 #ifdef DEBUG
     void checkSynchronizedWithFreeList() const;
 #endif
-
-#if defined DEBUG || defined JS_GCMETER
-    static size_t CountListLength(const ArenaHeader *aheader) {
-        size_t n = 0;
-        for (; aheader; aheader = aheader->next)
-            ++n;
-        return n;
-    }
-#endif
 };
 
 struct Arena {
     /*
      * Layout of an arena:
      * An arena is 4K in size and 4K-aligned. It starts with the ArenaHeader
      * descriptor followed by some pad bytes. The remainder of the arena is
      * filled with the array of T things. The pad bytes ensure that the thing
@@ -708,29 +699,22 @@ class ArenaList {
         BFS_RUN,
         BFS_JUST_FINISHED
     };
 
     volatile BackgroundFinalizeState backgroundFinalizeState;
 #endif
 
   public:
-#ifdef JS_GCMETER
-    JSGCArenaStats  stats;
-#endif
-
     void init() {
         head = NULL;
         cursor = &head;
 #ifdef JS_THREADSAFE
         backgroundFinalizeState = BFS_DONE;
 #endif
-#ifdef JS_GCMETER
-        PodZero(&stats);
-#endif
     }
 
     ArenaHeader *getHead() { return head; }
 
     inline ArenaHeader *searchForFreeArena();
 
     template <size_t thingSize>
     inline ArenaHeader *getArenaWithFreeList(JSContext *cx, unsigned thingKind);
@@ -1285,24 +1269,20 @@ struct GCMarker : public JSTracer {
 
   public:
     /* See comments before delayMarkingChildren is jsgc.cpp. */
     js::gc::ArenaHeader *unmarkedArenaStackTop;
 #ifdef DEBUG
     size_t              markLaterArenas;
 #endif
 
-#if defined(JS_DUMP_CONSERVATIVE_GC_ROOTS) || defined(JS_GCMETER)
+#ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS
     js::gc::ConservativeGCStats conservativeStats;
-#endif
-
-#ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS
     Vector<void *, 0, SystemAllocPolicy> conservativeRoots;
     const char *conservativeDumpFileName;
-
     void dumpConservativeRoots();
 #endif
 
     MarkStack<JSObject *> objStack;
     MarkStack<JSRope *> ropeStack;
     MarkStack<JSXML *> xmlStack;
     MarkStack<LargeMarkItem> largeStack;
 
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -44,24 +44,16 @@
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsscope.h"
 #include "jsxml.h"
 
 #include "jslock.h"
 #include "jstl.h"
 
-#ifdef JS_GCMETER
-# define METER(x)               ((void) (x))
-# define METER_IF(condition, x) ((void) ((condition) && (x)))
-#else
-# define METER(x)               ((void) 0)
-# define METER_IF(condition, x) ((void) 0)
-#endif
-
 inline bool
 JSAtom::isUnitString(const void *ptr)
 {
     jsuword delta = reinterpret_cast<jsuword>(ptr) -
                     reinterpret_cast<jsuword>(unitStaticTable);
     if (delta >= UNIT_STATIC_LIMIT * sizeof(JSString))
         return false;
 
@@ -206,24 +198,20 @@ NewGCThing(JSContext *cx, unsigned thing
 #endif
     JS_ASSERT(!cx->runtime->gcRunning);
 
 #ifdef JS_GC_ZEAL
     if (cx->runtime->needZealousGC())
         js::gc::RunDebugGC(cx);
 #endif
 
-    METER(cx->compartment->arenas[thingKind].stats.alloc++);
     js::gc::Cell *cell = cx->compartment->freeLists.getNext(thingKind, thingSize);
     return static_cast<T *>(cell ? cell : js::gc::RefillFinalizableFreeList(cx, thingKind));
 }
 
-#undef METER
-#undef METER_IF
-
 inline JSObject *
 js_NewGCObject(JSContext *cx, js::gc::FinalizeKind kind)
 {
     JS_ASSERT(kind >= js::gc::FINALIZE_OBJECT0 && kind <= js::gc::FINALIZE_OBJECT_LAST);
     JSObject *obj = NewGCThing<JSObject>(cx, kind, js::gc::GCThingSizeMap[kind]);
     if (obj) {
         obj->capacity = js::gc::GetGCKindSlots(kind);
         obj->lastProp = NULL; /* Stops obj from being scanned until initializated. */
--- a/js/src/jsgcmark.cpp
+++ b/js/src/jsgcmark.cpp
@@ -601,20 +601,16 @@ ScanObject(GCMarker *gcmarker, JSObject 
         int count = FINALIZE_OBJECT_LAST - FINALIZE_OBJECT0 + 1;
         for (int i = 0; i < count; i++) {
             if (obj->emptyShapes[i])
                 PushMarkStack(gcmarker, obj->emptyShapes[i]);
         }
     }
 
     if (obj->isNative()) {
-#ifdef JS_DUMP_SCOPE_METERS
-        js::MeterEntryCount(obj->propertyCount);
-#endif
-
         js::Shape *shape = obj->lastProp;
         PushMarkStack(gcmarker, shape);
 
         if (gcmarker->context->runtime->gcRegenShapes) {
             /* We need to regenerate our shape if hasOwnShape(). */
             uint32 newShape = shape->shapeid;
             if (obj->hasOwnShape()) {
                 newShape = js_RegenerateShapeForGC(gcmarker->context->runtime);
@@ -696,20 +692,16 @@ MarkChildren(JSTracer *trc, JSObject *ob
         }
     }
 
     Class *clasp = obj->getClass();
     if (clasp->trace)
         clasp->trace(trc, obj);
 
     if (obj->isNative()) {
-#ifdef JS_DUMP_SCOPE_METERS
-        js::MeterEntryCount(obj->propertyCount);
-#endif
-
         MarkShape(trc, obj->lastProp, "shape");
 
         if (obj->slotSpan() > 0)
             MarkObjectSlots(trc, obj);
     }
 }
 
 void
--- a/js/src/jsgcstats.cpp
+++ b/js/src/jsgcstats.cpp
@@ -50,17 +50,17 @@ using namespace js;
 using namespace js::gc;
 
 #define UL(x)       ((unsigned long)(x))
 #define PERCENT(x,y)  (100.0 * (double) (x) / (double) (y))
 
 namespace js {
 namespace gc {
 
-#if defined(JS_DUMP_CONSERVATIVE_GC_ROOTS) || defined(JS_GCMETER)
+#if defined(JS_DUMP_CONSERVATIVE_GC_ROOTS)
 
 void
 ConservativeGCStats::dump(FILE *fp)
 {
     size_t words = 0;
     for (size_t i = 0; i != JS_ARRAY_LENGTH(counter); ++i)
         words += counter[i];
    
@@ -74,160 +74,16 @@ ConservativeGCStats::dump(FILE *fp)
     fprintf(fp, "        excluded, wrong tag: %lu\n", ULSTAT(counter[CGCT_WRONGTAG]));
     fprintf(fp, "         excluded, not live: %lu\n", ULSTAT(counter[CGCT_NOTLIVE]));
     fprintf(fp, "            valid GC things: %lu\n", ULSTAT(counter[CGCT_VALID]));
     fprintf(fp, "      valid but not aligned: %lu\n", ULSTAT(unaligned));
 #undef ULSTAT
 }
 #endif
 
-#ifdef JS_GCMETER
-void
-UpdateCompartmentGCStats(JSCompartment *comp, unsigned thingKind)
-{
-    JSGCArenaStats *compSt = &comp->arenas[thingKind].stats;
-    JSGCArenaStats *globSt = &comp->rt->globalArenaStats[thingKind];
-    JS_ASSERT(compSt->narenas >= compSt->livearenas);
-    compSt->newarenas     = compSt->narenas - compSt->livearenas;
-    if (compSt->maxarenas < compSt->narenas)
-        compSt->maxarenas = compSt->narenas;
-    compSt->totalarenas  += compSt->narenas;
-
-    if (compSt->maxthings < compSt->nthings)
-        compSt->maxthings = compSt->nthings;
-    compSt->totalthings  += compSt->nthings;
-    globSt->newarenas    += compSt->newarenas;
-    globSt->narenas      += compSt->narenas;
-    globSt->livearenas   += compSt->livearenas;
-    globSt->totalarenas  += compSt->totalarenas;
-    globSt->nthings      += compSt->nthings;
-    globSt->totalthings  += compSt->totalthings;
-    if (globSt->maxarenas < compSt->maxarenas)
-        globSt->maxarenas = compSt->maxarenas;
-    if (globSt->maxthings < compSt->maxthings)
-        globSt->maxthings = compSt->maxthings;
-}
-
-void
-UpdateAllCompartmentGCStats(JSCompartment *comp)
-{
-    /*
-     * The stats for the list arenas scheduled for the background finalization
-     * are updated after that finishes.
-     */
-    JS_ASSERT(comp->rt->gcRunning);
-    for (unsigned i = 0; i != JS_ARRAY_LENGTH(comp->arenas); ++i) {
-#ifdef JS_THREADSAFE
-        if (comp->arenas[i].willBeFinalizedLater())
-            continue;
-#endif
-        UpdateCompartmentGCStats(comp, i);
-    }
-}
-
-static const char *const GC_ARENA_NAMES[] = {
-    "object_0",
-    "object_0_background",
-    "object_2",
-    "object_2_background",
-    "object_4",
-    "object_4_background",
-    "object_8",
-    "object_8_background",
-    "object_12",
-    "object_12_background",
-    "object_16",
-    "object_16_background",
-    "function",
-    "shape",
-#if JS_HAS_XML_SUPPORT
-    "xml",
-#endif
-    "short string",
-    "string",
-    "external_string",
-};
-JS_STATIC_ASSERT(JS_ARRAY_LENGTH(GC_ARENA_NAMES) == FINALIZE_LIMIT);
-
-void
-DumpArenaStats(JSGCArenaStats *stp, FILE *fp)
-{
-    size_t sumArenas = 0, sumTotalArenas = 0, sumThings =0,  sumMaxThings = 0;
-    size_t sumThingSize = 0, sumTotalThingSize = 0, sumArenaCapacity = 0;
-    size_t sumTotalArenaCapacity = 0, sumAlloc = 0, sumLocalAlloc = 0;
-
-    for (int i = 0; i < (int) FINALIZE_LIMIT; i++) {
-        JSGCArenaStats *st = &stp[i];
-        if (st->maxarenas == 0)
-            continue;
-        size_t thingSize = GCThingSizeMap[i];
-        size_t thingsPerArena = Arena::thingsPerArena(thingSize);
-
-        fprintf(fp, "%s arenas (thing size %lu, %lu things per arena):\n",
-                GC_ARENA_NAMES[i], UL(thingSize), UL(thingsPerArena));
-        fprintf(fp, "           arenas before GC: %lu\n", UL(st->narenas));
-        fprintf(fp, "            arenas after GC: %lu (%.1f%%)\n",
-                UL(st->livearenas), PERCENT(st->livearenas, st->narenas));
-        fprintf(fp, "                 max arenas: %lu\n", UL(st->maxarenas));
-        fprintf(fp, "                     things: %lu\n", UL(st->nthings));
-        fprintf(fp, "        GC cell utilization: %.1f%%\n",
-                PERCENT(st->nthings, thingsPerArena * st->narenas));
-        fprintf(fp, "   average cell utilization: %.1f%%\n",
-                PERCENT(st->totalthings, thingsPerArena * st->totalarenas));
-        fprintf(fp, "                 max things: %lu\n", UL(st->maxthings));
-        fprintf(fp, "             alloc attempts: %lu\n", UL(st->alloc));
-        fprintf(fp, "        alloc without locks: %lu  (%.1f%%)\n",
-                UL(st->localalloc), PERCENT(st->localalloc, st->alloc));
-        sumArenas += st->narenas;
-        sumTotalArenas += st->totalarenas;
-        sumThings += st->nthings;
-        sumMaxThings += st->maxthings;
-        sumThingSize += thingSize * st->nthings;
-        sumTotalThingSize += size_t(thingSize * st->totalthings);
-        sumArenaCapacity += thingSize * thingsPerArena * st->narenas;
-        sumTotalArenaCapacity += thingSize * thingsPerArena * st->totalarenas;
-        sumAlloc += st->alloc;
-        sumLocalAlloc += st->localalloc;
-        putc('\n', fp);
-    }
-
-    fputs("Never used arenas:\n", fp);
-    for (int i = 0; i < (int) FINALIZE_LIMIT; i++) {
-        JSGCArenaStats *st = &stp[i];
-        if (st->maxarenas != 0)
-            continue;
-        fprintf(fp, "%s\n", GC_ARENA_NAMES[i]);
-    }
-    fprintf(fp, "\nTOTAL STATS:\n");
-    fprintf(fp, "            total GC arenas: %lu\n", UL(sumArenas));
-    fprintf(fp, "            total GC things: %lu\n", UL(sumThings));
-    fprintf(fp, "        max total GC things: %lu\n", UL(sumMaxThings));
-    fprintf(fp, "        GC cell utilization: %.1f%%\n",
-            PERCENT(sumThingSize, sumArenaCapacity));
-    fprintf(fp, "   average cell utilization: %.1f%%\n",
-            PERCENT(sumTotalThingSize, sumTotalArenaCapacity));
-    fprintf(fp, "             alloc attempts: %lu\n", UL(sumAlloc));
-    fprintf(fp, "        alloc without locks: %lu  (%.1f%%)\n",
-            UL(sumLocalAlloc), PERCENT(sumLocalAlloc, sumAlloc));
-}
-
-void
-DumpCompartmentStats(JSCompartment *comp, FILE *fp)
-{
-    if (comp->rt->atomsCompartment == comp)
-        fprintf(fp, "\n**** AtomsCompartment Allocation Statistics: %p ****\n\n", (void *) comp);
-    else
-        fprintf(fp, "\n**** Compartment Allocation Statistics: %p ****\n\n", (void *) comp);
-
-    for (unsigned i = 0; i != FINALIZE_LIMIT; ++i)
-        DumpArenaStats(&comp->arenas[i].stats, fp);
-}
-
-#endif
-
 } //gc
 } //js
 
 #ifdef JSGC_TESTPILOT
 typedef JSRuntime::GCData GCData;
 
 JS_PUBLIC_API(bool)
 JS_GetGCInfoEnabled(JSRuntime *rt)
@@ -266,47 +122,16 @@ JS_GCInfoPopFront(JSRuntime *rt)
 
     data.start = (data.start + 1) % GCData::INFO_LIMIT;
     data.count -= 1;
     return false;
 }
 #endif
 
 
-#ifdef JS_GCMETER
-
-JS_FRIEND_API(void)
-js_DumpGCStats(JSRuntime *rt, FILE *fp)
-{
-#define ULSTAT(x)   UL(rt->gcStats.x)
-    if (JS_WANT_GC_METER_PRINT) {
-        fprintf(fp, "\n**** Global Arena Allocation Statistics: ****\n");
-        DumpArenaStats(&rt->globalArenaStats[0], fp);
-        fprintf(fp, "            bytes allocated: %lu\n", UL(rt->gcBytes));
-        fprintf(fp, "        allocation failures: %lu\n", ULSTAT(fail));
-        fprintf(fp, "         last ditch GC runs: %lu\n", ULSTAT(lastditch));
-        fprintf(fp, "           valid lock calls: %lu\n", ULSTAT(lock));
-        fprintf(fp, "         valid unlock calls: %lu\n", ULSTAT(unlock));
-        fprintf(fp, "      delayed tracing calls: %lu\n", ULSTAT(unmarked));
-#ifdef DEBUG
-        fprintf(fp, "      max trace later count: %lu\n", ULSTAT(maxunmarked));
-#endif
-        fprintf(fp, "  thing arenas freed so far: %lu\n\n", ULSTAT(afree));
-    }
-
-    if (JS_WANT_GC_PER_COMPARTMENT_PRINT)
-        for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c)
-            DumpCompartmentStats(*c, fp);
-    PodZero(&rt->globalArenaStats);
-    if (JS_WANT_CONSERVATIVE_GC_PRINT)
-        rt->gcStats.conservative.dump(fp);
-#undef ULSTAT
-}
-#endif
-
 namespace js {
 
 #ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS
 void
 GCMarker::dumpConservativeRoots()
 {
     if (!conservativeDumpFileName)
         return;
--- a/js/src/jsgcstats.h
+++ b/js/src/jsgcstats.h
@@ -38,28 +38,16 @@
 
 #ifndef jsgcstats_h___
 #define jsgcstats_h___
 
 #if !defined JS_DUMP_CONSERVATIVE_GC_ROOTS && defined DEBUG
 # define JS_DUMP_CONSERVATIVE_GC_ROOTS 1
 #endif
 
-/* Define JS_GCMETER here if wanted */
-#if defined JS_GCMETER
-const bool JS_WANT_GC_METER_PRINT = true;
-const bool JS_WANT_GC_PER_COMPARTMENT_PRINT = true;
-const bool JS_WANT_CONSERVATIVE_GC_PRINT = true;
-#elif defined DEBUG
-# define JS_GCMETER 1
-const bool JS_WANT_GC_METER_PRINT = false;
-const bool JS_WANT_GC_PER_COMPARTMENT_PRINT = false;
-const bool JS_WANT_CONSERVATIVE_GC_PRINT = false;
-#endif
-
 #ifdef JSGC_TESTPILOT
 JS_BEGIN_EXTERN_C
 
 struct JSGCInfo
 {
     double appTime, gcTime, waitTime, markTime, sweepTime;
     double sweepObjTime, sweepStringTime, sweepShapeTime, destroyTime, endTime;
     bool isCompartmental;
@@ -125,63 +113,16 @@ struct ConservativeGCStats
     void add(const ConservativeGCStats &another) {
         for (size_t i = 0; i != JS_ARRAY_LENGTH(counter); ++i)
             counter[i] += another.counter[i];
     }
 
     void dump(FILE *fp);
 };
 
-#ifdef JS_GCMETER
-struct JSGCArenaStats
-{
-    uint32  alloc;          /* allocation attempts */
-    uint32  localalloc;     /* allocations from local lists */
-    uint32  nthings;        /* live GC things */
-    uint32  maxthings;      /* maximum of live GC cells */
-    double  totalthings;    /* live GC things the GC scanned so far */
-    uint32  narenas;        /* number of arena in list before the GC */
-    uint32  newarenas;      /* new arenas allocated before the last GC */
-    uint32  livearenas;     /* number of live arenas after the last GC */
-    uint32  maxarenas;      /* maximum of allocated arenas */
-    uint32  totalarenas;    /* total number of arenas with live things that
-                               GC scanned so far */
-};
-#endif
-
-#ifdef JS_GCMETER
-
-struct JSGCStats
-{
-    uint32  lock;       /* valid lock calls */
-    uint32  unlock;     /* valid unlock calls */
-    uint32  unmarked;   /* number of times marking of GC thing's children were
-                           delayed due to a low C stack */
-    uint32  lastditch;  /* number of times the last ditch GC run */
-    uint32  fail;       /* allocation failures */
-#ifdef DEBUG
-    uint32  maxunmarked;/* maximum number of things with children to mark
-                           later */
-#endif
-    uint32  afree;          /* thing arenas freed so far */
-    uint32  nallarenas;     /* number of all allocated arenas */
-    uint32  maxnallarenas;  /* maximum number of all allocated arenas */
-    uint32  nchunks;        /* number of allocated chunks */
-    uint32  maxnchunks;     /* maximum number of allocated chunks */
-
-    ConservativeGCStats conservative;
-};
-
-extern void
-UpdateCompartmentGCStats(JSCompartment *comp, unsigned thingKind);
-
-extern void
-UpdateAllCompartmentGCStats(JSCompartment *comp);
-#endif /* JS_GCMETER */
-
 } //gc
 
 #if defined(MOZ_GCTIMER) || defined(JSGC_TESTPILOT)
 
 const bool JS_WANT_GC_SUITE_PRINT = false;  //false for gnuplot output
 
 extern jsrefcount newChunkCount;
 extern jsrefcount destroyChunkCount;
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1434,421 +1434,20 @@ js::FindUpvarFrame(JSContext *cx, uintN 
         JS_ASSERT(fp && fp->isScriptFrame());
         if (fp->script()->staticLevel == targetLevel)
             break;
         fp = fp->prev();
     }
     return fp;
 }
 
-#ifdef DEBUG
-
-JS_STATIC_INTERPRET JS_REQUIRES_STACK void
-js_LogOpcode(JSContext *cx)
-{
-    FILE *logfp;
-    StackFrame *fp;
-    FrameRegs *regs;
-    intN ndefs, n, nuses;
-    JSOp op;
-
-    logfp = (FILE *) cx->logfp;
-    JS_ASSERT(logfp);
-    fp = cx->fp();
-    regs = &cx->regs();
-
-    /*
-     * Operations in prologues don't produce interesting values, and
-     * js_DecompileValueGenerator isn't set up to handle them anyway.
-     */
-    if (cx->logPrevPc && regs->pc >= fp->script()->main) {
-        JSOp logPrevOp = JSOp(*cx->logPrevPc);
-        ndefs = js_GetStackDefs(cx, &js_CodeSpec[logPrevOp], logPrevOp,
-                                fp->script(), cx->logPrevPc);
-
-        /*
-         * If there aren't that many elements on the stack, then we have
-         * probably entered a new frame, and printing output would just be
-         * misleading.
-         */
-        if (ndefs != 0 &&
-            ndefs < regs->sp - fp->slots()) {
-            for (n = -ndefs; n < 0; n++) {
-                char *bytes = DecompileValueGenerator(cx, n, regs->sp[n], NULL);
-                if (bytes) {
-                    fprintf(logfp, "%s %s",
-                            (n == -ndefs) ? "  output:" : ",",
-                            bytes);
-                    cx->free_(bytes);
-                } else {
-                    JS_ClearPendingException(cx);
-                }
-            }
-            fprintf(logfp, " @ %u\n", (uintN) (regs->sp - fp->base()));
-        }
-        fprintf(logfp, "  stack: ");
-        for (Value *siter = fp->base(); siter < regs->sp; siter++) {
-            if (siter->isObject() && siter->toObject().getClass() == &js_CallClass) {
-                /*
-                 * Call objects have NULL convert ops so that we catch cases
-                 * where they escape. So js_ValueToString doesn't work on them.
-                 */
-                fputs("<call>", logfp);
-            } else {
-                JSString *str = js_ValueToString(cx, *siter);
-                JSLinearString *linearStr = str ? str->ensureLinear(cx) : NULL;
-                if (!linearStr) {
-                    fputs("<null>", logfp);
-                    JS_ClearPendingException(cx);
-                } else {
-                    FileEscapedString(logfp, linearStr, 0);
-                }
-            }
-            fputc(' ', logfp);
-        }
-        fputc('\n', logfp);
-    }
-
-    fprintf(logfp, "%4u: ",
-            js_PCToLineNumber(cx, fp->script(),
-                              fp->hasImacropc() ? fp->imacropc() : regs->pc));
-
-    Sprinter sprinter;
-    void *mark = JS_ARENA_MARK(&cx->tempPool);
-    INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0);
-    js_Disassemble1(cx, fp->script(), regs->pc,
-                    regs->pc - fp->script()->code,
-                    JS_FALSE, &sprinter);
-    fprintf(logfp, "%s", sprinter.base);
-    JS_ARENA_RELEASE(&cx->tempPool, mark);
-
-    op = (JSOp) *regs->pc;
-    nuses = js_GetStackUses(&js_CodeSpec[op], op, regs->pc);
-    if (nuses != 0) {
-        for (n = -nuses; n < 0; n++) {
-            char *bytes = DecompileValueGenerator(cx, n, regs->sp[n], NULL);
-            if (bytes) {
-                fprintf(logfp, "%s %s",
-                        (n == -nuses) ? "  inputs:" : ",",
-                        bytes);
-                cx->free_(bytes);
-            } else {
-                JS_ClearPendingException(cx);
-            }
-        }
-        fprintf(logfp, " @ %u\n", (uintN) (regs->sp - fp->base()));
-    }
-    cx->logPrevPc = regs->pc;
-
-    /* It's nice to have complete logs when debugging a crash.  */
-    fflush(logfp);
-}
-
-#endif /* DEBUG */
-
-#ifdef JS_OPMETER
-
-# include <stdlib.h>
-
-# define HIST_NSLOTS            8
-
-/*
- * The second dimension is hardcoded at 256 because we know that many bits fit
- * in a byte, and mainly to optimize away multiplying by JSOP_LIMIT to address
- * any particular row.
- */
-static uint32 succeeds[JSOP_LIMIT][256];
-static uint32 slot_ops[JSOP_LIMIT][HIST_NSLOTS];
-
-JS_STATIC_INTERPRET void
-js_MeterOpcodePair(JSOp op1, JSOp op2)
-{
-    if (op1 != JSOP_STOP)
-        ++succeeds[op1][op2];
-}
-
-JS_STATIC_INTERPRET void
-js_MeterSlotOpcode(JSOp op, uint32 slot)
-{
-    if (slot < HIST_NSLOTS)
-        ++slot_ops[op][slot];
-}
-
-typedef struct Edge {
-    const char  *from;
-    const char  *to;
-    uint32      count;
-} Edge;
-
-static int
-compare_edges(const void *a, const void *b)
-{
-    const Edge *ea = (const Edge *) a;
-    const Edge *eb = (const Edge *) b;
-
-    return (int32)eb->count - (int32)ea->count;
-}
-
-void
-js_DumpOpMeters()
-{
-    const char *name, *from, *style;
-    FILE *fp;
-    uint32 total, count;
-    uint32 i, j, nedges;
-    Edge *graph;
-
-    name = getenv("JS_OPMETER_FILE");
-    if (!name)
-        name = "/tmp/ops.dot";
-    fp = fopen(name, "w");
-    if (!fp) {
-        perror(name);
-        return;
-    }
-
-    total = nedges = 0;
-    for (i = 0; i < JSOP_LIMIT; i++) {
-        for (j = 0; j < JSOP_LIMIT; j++) {
-            count = succeeds[i][j];
-            if (count != 0) {
-                total += count;
-                ++nedges;
-            }
-        }
-    }
-
-# define SIGNIFICANT(count,total) (200. * (count) >= (total))
-
-    graph = (Edge *) OffTheBooks::calloc_(nedges * sizeof graph[0]);
-    if (!graph)
-        return;
-    for (i = nedges = 0; i < JSOP_LIMIT; i++) {
-        from = js_CodeName[i];
-        for (j = 0; j < JSOP_LIMIT; j++) {
-            count = succeeds[i][j];
-            if (count != 0 && SIGNIFICANT(count, total)) {
-                graph[nedges].from = from;
-                graph[nedges].to = js_CodeName[j];
-                graph[nedges].count = count;
-                ++nedges;
-            }
-        }
-    }
-    qsort(graph, nedges, sizeof(Edge), compare_edges);
-
-# undef SIGNIFICANT
-
-    fputs("digraph {\n", fp);
-    for (i = 0, style = NULL; i < nedges; i++) {
-        JS_ASSERT(i == 0 || graph[i-1].count >= graph[i].count);
-        if (!style || graph[i-1].count != graph[i].count) {
-            style = (i > nedges * .75) ? "dotted" :
-                    (i > nedges * .50) ? "dashed" :
-                    (i > nedges * .25) ? "solid" : "bold";
-        }
-        fprintf(fp, "  %s -> %s [label=\"%lu\" style=%s]\n",
-                graph[i].from, graph[i].to,
-                (unsigned long)graph[i].count, style);
-    }
-    cx->free_(graph);
-    fputs("}\n", fp);
-    fclose(fp);
-
-    name = getenv("JS_OPMETER_HIST");
-    if (!name)
-        name = "/tmp/ops.hist";
-    fp = fopen(name, "w");
-    if (!fp) {
-        perror(name);
-        return;
-    }
-    fputs("bytecode", fp);
-    for (j = 0; j < HIST_NSLOTS; j++)
-        fprintf(fp, "  slot %1u", (unsigned)j);
-    putc('\n', fp);
-    fputs("========", fp);
-    for (j = 0; j < HIST_NSLOTS; j++)
-        fputs(" =======", fp);
-    putc('\n', fp);
-    for (i = 0; i < JSOP_LIMIT; i++) {
-        for (j = 0; j < HIST_NSLOTS; j++) {
-            if (slot_ops[i][j] != 0) {
-                /* Reuse j in the next loop, since we break after. */
-                fprintf(fp, "%-8.8s", js_CodeName[i]);
-                for (j = 0; j < HIST_NSLOTS; j++)
-                    fprintf(fp, " %7lu", (unsigned long)slot_ops[i][j]);
-                putc('\n', fp);
-                break;
-            }
-        }
-    }
-    fclose(fp);
-}
-
-#endif /* JS_OPSMETER */
-
 #endif /* !JS_LONE_INTERPRET ^ defined jsinvoke_cpp___ */
 
 #ifndef  jsinvoke_cpp___
 
-#ifdef JS_REPRMETER
-// jsval representation metering: this measures the kinds of jsvals that
-// are used as inputs to each JSOp.
-namespace reprmeter {
-    enum Repr {
-        NONE,
-        INT,
-        DOUBLE,
-        BOOLEAN_PROPER,
-        BOOLEAN_OTHER,
-        STRING,
-        OBJECT_NULL,
-        OBJECT_PLAIN,
-        FUNCTION_INTERPRETED,
-        FUNCTION_FASTNATIVE,
-        ARRAY_SLOW,
-        ARRAY_DENSE
-    };
-
-    // Return the |repr| value giving the representation of the given jsval.
-    static Repr
-    GetRepr(jsval v)
-    {
-        if (JSVAL_IS_INT(v))
-            return INT;
-        if (JSVAL_IS_DOUBLE(v))
-            return DOUBLE;
-        if (JSVAL_IS_SPECIAL(v)) {
-            return (v == JSVAL_TRUE || v == JSVAL_FALSE)
-                   ? BOOLEAN_PROPER
-                   : BOOLEAN_OTHER;
-        }
-        if (JSVAL_IS_STRING(v))
-            return STRING;
-
-        JS_ASSERT(JSVAL_IS_OBJECT(v));
-
-        JSObject *obj = JSVAL_TO_OBJECT(v);
-        if (VALUE_IS_FUNCTION(cx, v)) {
-            JSFunction *fun = obj->getFunctionPrivate();
-            if (FUN_INTERPRETED(fun))
-                return FUNCTION_INTERPRETED;
-            return FUNCTION_FASTNATIVE;
-        }
-        // This must come before the general array test, because that
-        // one subsumes this one.
-        if (!obj)
-            return OBJECT_NULL;
-        if (obj->isDenseArray())
-            return ARRAY_DENSE;
-        if (obj->isArray())
-            return ARRAY_SLOW;
-        return OBJECT_PLAIN;
-    }
-
-    static const char *reprName[] = { "invalid", "int", "double", "bool", "special",
-                                      "string", "null", "object",
-                                      "fun:interp", "fun:native"
-                                      "array:slow", "array:dense" };
-
-    // Logically, a tuple of (JSOp, repr_1, ..., repr_n) where repr_i is
-    // the |repr| of the ith input to the JSOp.
-    struct OpInput {
-        enum { max_uses = 16 };
-
-        JSOp op;
-        Repr uses[max_uses];
-
-        OpInput() : op(JSOp(255)) {
-            for (int i = 0; i < max_uses; ++i)
-                uses[i] = NONE;
-        }
-
-        OpInput(JSOp op) : op(op) {
-            for (int i = 0; i < max_uses; ++i)
-                uses[i] = NONE;
-        }
-
-        // Hash function
-        operator uint32() const {
-            uint32 h = op;
-            for (int i = 0; i < max_uses; ++i)
-                h = h * 7 + uses[i] * 13;
-            return h;
-        }
-
-        bool operator==(const OpInput &opinput) const {
-            if (op != opinput.op)
-                return false;
-            for (int i = 0; i < max_uses; ++i) {
-                if (uses[i] != opinput.uses[i])
-                    return false;
-            }
-            return true;
-        }
-
-        OpInput &operator=(const OpInput &opinput) {
-            op = opinput.op;
-            for (int i = 0; i < max_uses; ++i)
-                uses[i] = opinput.uses[i];
-            return *this;
-        }
-    };
-
-    typedef HashMap<OpInput, uint64, DefaultHasher<OpInput>, SystemAllocPolicy> OpInputHistogram;
-
-    OpInputHistogram opinputs;
-    bool             opinputsInitialized = false;
-
-    // Record an OpInput for the current op. This should be called just
-    // before executing the op.
-    static void
-    MeterRepr(JSContext *cx)
-    {
-        // Note that we simply ignore the possibility of errors (OOMs)
-        // using the hash map, since this is only metering code.
-
-        if (!opinputsInitialized) {
-            opinputs.init();
-            opinputsInitialized = true;
-        }
-
-        JSOp op = JSOp(*cx->regs->pc);
-        int nuses = js_GetStackUses(&js_CodeSpec[op], op, cx->regs->pc);
-
-        // Build the OpInput.
-        OpInput opinput(op);
-        for (int i = 0; i < nuses; ++i) {
-            jsval v = cx->regs->sp[-nuses+i];
-            opinput.uses[i] = GetRepr(v);
-        }
-
-        if (OpInputHistogram::Ptr p = opinputs.lookupWithDefault(opinput, 0))
-            p->value++;
-    }
-
-    void
-    js_DumpReprMeter()
-    {
-        FILE *f = fopen("/tmp/reprmeter.txt", "w");
-        JS_ASSERT(f);
-        for (OpInputHistogram::Range r = opinputs.all(); !r.empty(); r.popFront()) {
-            const OpInput &o = r.front().key;
-            uint64 c = r.front().value;
-            fprintf(f, "%3d,%s", o.op, js_CodeName[o.op]);
-            for (int i = 0; i < OpInput::max_uses && o.uses[i] != NONE; ++i)
-                fprintf(f, ",%s", reprName[o.uses[i]]);
-            fprintf(f, ",%llu\n", c);
-        }
-        fclose(f);
-    }
-}
-#endif /* JS_REPRMETER */
-
 #define PUSH_COPY(v)             do { *regs.sp++ = v; assertSameCompartment(cx, regs.sp[-1]); } while (0)
 #define PUSH_NULL()              regs.sp++->setNull()
 #define PUSH_UNDEFINED()         regs.sp++->setUndefined()
 #define PUSH_BOOLEAN(b)          regs.sp++->setBoolean(b)
 #define PUSH_DOUBLE(d)           regs.sp++->setDouble(d)
 #define PUSH_INT32(i)            regs.sp++->setInt32(i)
 #define PUSH_STRING(s)           do { regs.sp++->setString(s); assertSameCompartment(cx, regs.sp[-1]); } while (0)
 #define PUSH_OBJECT(obj)         do { regs.sp++->setObject(obj); assertSameCompartment(cx, regs.sp[-1]); } while (0)
@@ -1891,49 +1490,16 @@ namespace reprmeter {
 /* Test whether v is an int in the range [-2^31 + 1, 2^31 - 2] */
 static JS_ALWAYS_INLINE bool
 CanIncDecWithoutOverflow(int32_t i)
 {
     return (i > JSVAL_INT_MIN) && (i < JSVAL_INT_MAX);
 }
 
 /*
- * Define JS_OPMETER to instrument bytecode succession, generating a .dot file
- * on shutdown that shows the graph of significant predecessor/successor pairs
- * executed, where the edge labels give the succession counts.  The .dot file
- * is named by the JS_OPMETER_FILE envariable, and defaults to /tmp/ops.dot.
- *
- * Bonus feature: JS_OPMETER also enables counters for stack-addressing ops
- * such as JSOP_GETLOCAL, JSOP_INCARG, via METER_SLOT_OP. The resulting counts
- * are written to JS_OPMETER_HIST, defaulting to /tmp/ops.hist.
- */
-#ifndef JS_OPMETER
-# define METER_OP_INIT(op)      /* nothing */
-# define METER_OP_PAIR(op1,op2) /* nothing */
-# define METER_SLOT_OP(op,slot) /* nothing */
-#else
-
-/*
- * The second dimension is hardcoded at 256 because we know that many bits fit
- * in a byte, and mainly to optimize away multiplying by JSOP_LIMIT to address
- * any particular row.
- */
-# define METER_OP_INIT(op)      ((op) = JSOP_STOP)
-# define METER_OP_PAIR(op1,op2) (js_MeterOpcodePair(op1, op2))
-# define METER_SLOT_OP(op,slot) (js_MeterSlotOpcode(op, slot))
-
-#endif
-
-#ifdef JS_REPRMETER
-# define METER_REPR(cx)         (reprmeter::MeterRepr(cx))
-#else
-# define METER_REPR(cx)         ((void) 0)
-#endif /* JS_REPRMETER */
-
-/*
  * Threaded interpretation via computed goto appears to be well-supported by
  * GCC 3 and higher.  IBM's C compiler when run with the right options (e.g.,
  * -qlanglvl=extended) also supports threading.  Ditto the SunPro C compiler.
  * Currently it's broken for JS_VERSION < 160, though this isn't worth fixing.
  * Add your compiler support macros here.
  */
 #ifndef JS_THREADED_INTERP
 # if JS_VERSION >= 160 && (                                                   \
@@ -2111,40 +1677,16 @@ namespace js {
 JS_REQUIRES_STACK JS_NEVER_INLINE bool
 Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
 {
 #ifdef MOZ_TRACEVIS
     TraceVisStateObj tvso(cx, S_INTERP);
 #endif
     JSAutoResolveFlags rf(cx, RESOLVE_INFER);
 
-#ifdef DEBUG
-    /*
-     * We call this macro from BEGIN_CASE in threaded interpreters,
-     * and before entering the switch in non-threaded interpreters.
-     * However, reaching such points doesn't mean we've actually
-     * fetched an OP from the instruction stream: some opcodes use
-     * 'op=x; DO_OP()' to let another opcode's implementation finish
-     * their work, and many opcodes share entry points with a run of
-     * consecutive BEGIN_CASEs.
-     *
-     * Take care to trace OP only when it is the opcode fetched from
-     * the instruction stream, so the trace matches what one would
-     * expect from looking at the code.  (We do omit POPs after SETs;
-     * unfortunate, but not worth fixing.)
-     */
-# define LOG_OPCODE(OP)    JS_BEGIN_MACRO                                     \
-                                if (JS_UNLIKELY(cx->logfp != NULL) &&         \
-                                    (OP) == *regs.pc)                         \
-                                    js_LogOpcode(cx);                         \
-                            JS_END_MACRO
-#else
-# define LOG_OPCODE(OP)    ((void) 0)
-#endif
-
 #define COUNT_OP()         JS_BEGIN_MACRO                                     \
                                if (pcCounts && !regs.fp()->hasImacropc())     \
                                    ++pcCounts[regs.pc - script->code];        \
                            JS_END_MACRO
 
     /*
      * Macros for threaded interpreter loop
      */
@@ -2160,40 +1702,36 @@ Interpret(JSContext *cx, StackFrame *ent
 # define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format)              \
         JS_EXTENSION &&interrupt,
 # include "jsopcode.tbl"
 # undef OPDEF
     };
 
     register void * const *jumpTable = normalJumpTable;
 
-    METER_OP_INIT(op);      /* to nullify first METER_OP_PAIR */
-
 # define ENABLE_INTERRUPTS() ((void) (jumpTable = interruptJumpTable))
 
 # ifdef JS_TRACER
 #  define CHECK_RECORDER()                                                    \
     JS_ASSERT_IF(TRACE_RECORDER(cx), jumpTable == interruptJumpTable)
 # else
 #  define CHECK_RECORDER()  ((void)0)
 # endif
 
 # define DO_OP()            JS_BEGIN_MACRO                                    \
                                 CHECK_RECORDER();                             \
                                 COUNT_OP();                                   \
                                 JS_EXTENSION_(goto *jumpTable[op]);           \
                             JS_END_MACRO
 # define DO_NEXT_OP(n)      JS_BEGIN_MACRO                                    \
-                                METER_OP_PAIR(op, JSOp(regs.pc[n]));          \
                                 op = (JSOp) *(regs.pc += (n));                \
-                                METER_REPR(cx);                               \
                                 DO_OP();                                      \
                             JS_END_MACRO
 
-# define BEGIN_CASE(OP)     L_##OP: LOG_OPCODE(OP); CHECK_RECORDER();
+# define BEGIN_CASE(OP)     L_##OP: CHECK_RECORDER();
 # define END_CASE(OP)       DO_NEXT_OP(OP##_LENGTH);
 # define END_VARLEN_CASE    DO_NEXT_OP(len);
 # define ADD_EMPTY_CASE(OP) BEGIN_CASE(OP)                                    \
                                 JS_ASSERT(js_CodeSpec[OP].length == 1);       \
                                 op = (JSOp) *++regs.pc;                       \
                                 DO_OP();
 
 # define END_EMPTY_CASES
@@ -2563,17 +2101,16 @@ Interpret(JSContext *cx, StackFrame *ent
         JS_ASSERT(js_CodeSpec[op].length == 1);
         len = 1;
       advance_pc:
         regs.pc += len;
         op = (JSOp) *regs.pc;
 
       do_op:
         CHECK_RECORDER();
-        LOG_OPCODE(op);
         switchOp = intN(op) | switchMask;
       do_switch:
         switch (switchOp) {
 #endif
 
 #if JS_THREADED_INTERP
   interrupt:
 #else /* !JS_THREADED_INTERP */
@@ -3919,17 +3456,16 @@ BEGIN_CASE(JSOP_ARGDEC)
 BEGIN_CASE(JSOP_INCARG)
     incr =  1; incr2 =  1; goto do_arg_incop;
 BEGIN_CASE(JSOP_ARGINC)
     incr =  1; incr2 =  0;
 
   do_arg_incop:
     slot = GET_ARGNO(regs.pc);
     JS_ASSERT(slot < regs.fp()->numFormalArgs());
-    METER_SLOT_OP(op, slot);
     vp = argv + slot;
     goto do_int_fast_incop;
 
 BEGIN_CASE(JSOP_DECLOCAL)
     incr = -1; incr2 = -1; goto do_local_incop;
 BEGIN_CASE(JSOP_LOCALDEC)
     incr = -1; incr2 =  0; goto do_local_incop;
 BEGIN_CASE(JSOP_INCLOCAL)
@@ -3940,17 +3476,16 @@ BEGIN_CASE(JSOP_LOCALINC)
   /*
    * do_local_incop comes right before do_int_fast_incop as we want to
    * avoid an extra jump for variable cases as local++ is more frequent
    * than arg++.
    */
   do_local_incop:
     slot = GET_SLOTNO(regs.pc);
     JS_ASSERT(slot < regs.fp()->numSlots());
-    METER_SLOT_OP(op, slot);
     vp = regs.fp()->slots() + slot;
 
   do_int_fast_incop:
     int32_t tmp;
     if (JS_LIKELY(vp->isInt32() && CanIncDecWithoutOverflow(tmp = vp->toInt32()))) {
         vp->getInt32Ref() = tmp + incr;
         JS_ASSERT(JSOP_INCARG_LENGTH == js_CodeSpec[op].length);
         SKIP_POP_AFTER_SET(JSOP_INCARG_LENGTH, 0);
@@ -4996,28 +4531,26 @@ BEGIN_CASE(JSOP_ARGCNT)
 }
 END_CASE(JSOP_ARGCNT)
 
 BEGIN_CASE(JSOP_GETARG)
 BEGIN_CASE(JSOP_CALLARG)
 {
     uint32 slot = GET_ARGNO(regs.pc);
     JS_ASSERT(slot < regs.fp()->numFormalArgs());
-    METER_SLOT_OP(op, slot);
     PUSH_COPY(argv[slot]);
     if (op == JSOP_CALLARG)
         PUSH_UNDEFINED();
 }
 END_CASE(JSOP_GETARG)
 
 BEGIN_CASE(JSOP_SETARG)
 {
     uint32 slot = GET_ARGNO(regs.pc);
     JS_ASSERT(slot < regs.fp()->numFormalArgs());
-    METER_SLOT_OP(op, slot);
     argv[slot] = regs.sp[-1];
 }
 END_SET_CASE(JSOP_SETARG)
 
 BEGIN_CASE(JSOP_GETLOCAL)
 {
     uint32 slot = GET_SLOTNO(regs.pc);
     JS_ASSERT(slot < script->nslots);
@@ -5401,29 +4934,27 @@ BEGIN_CASE(JSOP_LAMBDA)
 #ifdef DEBUG
                     const Value &lref = regs.sp[-1];
                     JS_ASSERT(lref.isObject());
                     JSObject *obj2 = &lref.toObject();
                     JS_ASSERT(obj2->getClass() == &js_ObjectClass);
 #endif
 
                     fun->setMethodAtom(script->getAtom(GET_FULL_INDEX(pc2 - regs.pc)));
-                    JS_FUNCTION_METER(cx, joinedinitmethod);
                     break;
                 }
 
                 if (op2 == JSOP_SETMETHOD) {
 #ifdef DEBUG
                     op2 = js_GetOpcode(cx, script, pc2 + JSOP_SETMETHOD_LENGTH);
                     JS_ASSERT(op2 == JSOP_POP || op2 == JSOP_POPV);
 #endif
                     const Value &lref = regs.sp[-1];
                     if (lref.isObject() && lref.toObject().canHaveMethodBarrier()) {
                         fun->setMethodAtom(script->getAtom(GET_FULL_INDEX(pc2 - regs.pc)));
-                        JS_FUNCTION_METER(cx, joinedsetmethod);
                         break;
                     }
                 } else if (fun->joinable()) {
                     if (op2 == JSOP_CALL) {
                         /*
                          * Array.prototype.sort and String.prototype.replace are
                          * optimized as if they are special form. We know that they
                          * won't leak the joined function object in obj, therefore
@@ -5438,48 +4969,31 @@ BEGIN_CASE(JSOP_LAMBDA)
                          * is the callee for this JSOP_CALL.
                          */
                         const Value &cref = regs.sp[1 - (iargc + 2)];
                         JSObject *callee;
 
                         if (IsFunctionObject(cref, &callee)) {
                             JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee);
                             if (Native native = calleeFun->maybeNative()) {
-                                if (iargc == 1 && native == array_sort) {
-                                    JS_FUNCTION_METER(cx, joinedsort);
-                                    break;
-                                }
-                                if (iargc == 2 && native == str_replace) {
-                                    JS_FUNCTION_METER(cx, joinedreplace);
+                                if ((iargc == 1 && native == array_sort) ||
+                                    (iargc == 2 && native == str_replace)) {
                                     break;
                                 }
                             }
                         }
                     } else if (op2 == JSOP_NULL) {
                         pc2 += JSOP_NULL_LENGTH;
                         op2 = JSOp(*pc2);
 
-                        if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0) {
-                            JS_FUNCTION_METER(cx, joinedmodulepat);
+                        if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0)
                             break;
-                        }
                     }
                 }
             }
-
-#ifdef DEBUG
-            if (rt->functionMeterFilename) {
-                // No locking, this is mainly for js shell testing.
-                ++rt->functionMeter.unjoined;
-
-                typedef JSRuntime::FunctionCountMap::Ptr Ptr;
-                if (Ptr p = rt->unjoinedFunctionCountMap.lookupWithDefault(fun, 0))
-                    ++p->value;
-            }
-#endif
         } else {
             parent = GetScopeChainFast(cx, regs.fp(), JSOP_LAMBDA, JSOP_LAMBDA_LENGTH);
             if (!parent)
                 goto error;
         }
 
         obj = CloneFunctionObject(cx, fun, parent);
         if (!obj)
@@ -6696,20 +6210,16 @@ END_CASE(JSOP_ARRAYPUSH)
      * js_UnwindScope returns true.
      *
      * When a trap handler returns JSTRAP_RETURN, we jump here with
      * interpReturnOK set to true bypassing any finally blocks.
      */
     interpReturnOK &= js_UnwindScope(cx, 0, interpReturnOK || cx->isExceptionPending());
     JS_ASSERT(regs.sp == regs.fp()->base());
 
-#ifdef DEBUG
-    cx->logPrevPc = NULL;
-#endif
-
     if (entryFrame != regs.fp())
         goto inline_return;
 
   exit:
     interpReturnOK = ScriptEpilogueOrGeneratorYield(cx, regs.fp(), interpReturnOK);
     regs.fp()->setFinishedInInterpreter();
 
     /*
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -333,32 +333,16 @@ js_LeaveWith(JSContext *cx);
  * Find the results of incrementing or decrementing *vp. For pre-increments,
  * both *vp and *vp2 will contain the result on return. For post-increments,
  * vp will contain the original value converted to a number and vp2 will get
  * the result. Both vp and vp2 must be roots.
  */
 extern JSBool
 js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, js::Value *vp, js::Value *vp2);
 
-/*
- * Opcode tracing helper. When len is not 0, cx->fp->regs->pc[-len] gives the
- * previous opcode.
- */
-extern JS_REQUIRES_STACK void
-js_LogOpcode(JSContext *cx);
-
-/*
- * JS_OPMETER helper functions.
- */
-extern void
-js_MeterOpcodePair(JSOp op1, JSOp op2);
-
-extern void
-js_MeterSlotOpcode(JSOp op, uint32 slot);
-
 #endif /* JS_LONE_INTERPRET */
 /*
  * Unwind block and scope chains to match the given depth. The function sets
  * fp->sp on return to stackDepth.
  */
 extern JS_REQUIRES_STACK JSBool
 js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind);
 
--- a/js/src/jslock.h
+++ b/js/src/jslock.h
@@ -159,23 +159,16 @@ extern JSBool js_IsRuntimeLocked(JSRunti
 
 #define JS_LOCK_RUNTIME(rt)         ((void)0)
 #define JS_UNLOCK_RUNTIME(rt)       ((void)0)
 
 #define JS_IS_RUNTIME_LOCKED(rt)        1
 
 #endif /* !JS_THREADSAFE */
 
-#define JS_LOCK_RUNTIME_VOID(rt,e)                                            \
-    JS_BEGIN_MACRO                                                            \
-        JS_LOCK_RUNTIME(rt);                                                  \
-        e;                                                                    \
-        JS_UNLOCK_RUNTIME(rt);                                                \
-    JS_END_MACRO
-
 #define JS_LOCK_GC(rt)              JS_ACQUIRE_LOCK((rt)->gcLock)
 #define JS_UNLOCK_GC(rt)            JS_RELEASE_LOCK((rt)->gcLock)
 #define JS_AWAIT_GC_DONE(rt)        JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT)
 #define JS_NOTIFY_GC_DONE(rt)       JS_NOTIFY_ALL_CONDVAR((rt)->gcDone)
 #define JS_AWAIT_REQUEST_DONE(rt)   JS_WAIT_CONDVAR((rt)->requestDone,        \
                                                     JS_NO_TIMEOUT)
 #define JS_NOTIFY_REQUEST_DONE(rt)  JS_NOTIFY_CONDVAR((rt)->requestDone)
 
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -968,17 +968,16 @@ EvalCacheLookup(JSContext *cx, JSLinearS
      * FIXME bug 620141: Qualify hits by calling script rather than function.
      * Then we wouldn't need the unintuitive !isEvalFrame() hack in EvalKernel
      * to avoid caching nested evals in functions (thus potentially mismatching
      * on strict mode), and we could cache evals in global code if desired.
      */
     uintN count = 0;
     JSScript **scriptp = bucket;
 
-    EVAL_CACHE_METER(probe);
     JSVersion version = cx->findVersion();
     JSScript *script;
     while ((script = *scriptp) != NULL) {
         if (script->savedCallerFun &&
             script->staticLevel == staticLevel &&
             script->getVersion() == version &&
             !script->hasSingletons &&
             (script->principals == principals ||
@@ -1008,35 +1007,32 @@ EvalCacheLookup(JSContext *cx, JSLinearS
                     JSObjectArray *objarray = script->objects();
                     int i = 1;
 
                     if (objarray->length == 1) {
                         if (JSScript::isValidOffset(script->regexpsOffset)) {
                             objarray = script->regexps();
                             i = 0;
                         } else {
-                            EVAL_CACHE_METER(noscope);
                             i = -1;
                         }
                     }
                     if (i < 0 ||
                         objarray->vector[i]->getParent() == &scopeobj) {
                         JS_ASSERT(staticLevel == script->staticLevel);
-                        EVAL_CACHE_METER(hit);
                         *scriptp = script->u.nextToGC;
                         script->u.nextToGC = NULL;
                         return script;
                     }
                 }
             }
         }
 
         if (++count == EVAL_CACHE_CHAIN_LIMIT)
             return NULL;
-        EVAL_CACHE_METER(step);
         scriptp = &script->u.nextToGC;
     }
     return NULL;
 }
 
 /*
  * There are two things we want to do with each script executed in EvalKernel:
  *  1. notify jsdbgapi about script creation/destruction
@@ -4834,34 +4830,28 @@ CallResolveOp(JSContext *cx, JSObject *s
             *objp = obj;
             *propp = (JSProperty *) shape;
         }
     }
 
     return true;
 }
 
-#define SCOPE_DEPTH_ACCUM(bs,val) JS_SCOPE_DEPTH_METERING(JS_BASIC_STATS_ACCUM(bs, val))
-
 static JS_ALWAYS_INLINE bool
 LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN flags,
                               JSObject **objp, JSProperty **propp)
 {
     /* We should not get string indices which aren't already integers here. */
     JS_ASSERT(id == js_CheckForStringIndex(id));
 
     /* Search scopes starting with obj and following the prototype link. */
     JSObject *start = obj;
-#ifdef JS_SCOPE_DEPTH_METER
-    int protoIndex = 0;
-#endif
-    for (; ; JS_SCOPE_DEPTH_METERING(protoIndex++)) {
+    while (true) {
         const Shape *shape = obj->nativeLookup(id);
         if (shape) {
-            SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
             *objp = obj;
             *propp = (JSProperty *) shape;
             return true;
         }
 
         /* Try obj's class resolve hook if id was not found in obj's scope. */
         if (obj->getClass()->resolve != JS_ResolveStub) {
             bool recursed;
@@ -4869,17 +4859,16 @@ LookupPropertyWithFlagsInline(JSContext 
                 return false;
             if (recursed)
                 break;
             if (*propp) {
                 /*
                  * For stats we do not recalculate protoIndex even if it was
                  * resolved on some other object.
                  */
-                SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
                 return true;
             }
         }
 
         JSObject *proto = obj->getProto();
         if (!proto)
             break;
         if (!proto->isNative()) {
@@ -4984,17 +4973,16 @@ js_FindPropertyHelper(JSContext *cx, jsi
             /*
              * We must check if pobj is native as a global object can have
              * non-native prototype.
              */
             if (cacheResult && pobj->isNative()) {
                 entry = JS_PROPERTY_CACHE(cx).fill(cx, scopeChain, scopeIndex, pobj,
                                                    (Shape *) prop);
             }
-            SCOPE_DEPTH_ACCUM(&cx->runtime->scopeSearchDepthStats, scopeIndex);
             goto out;
         }
 
         if (!parent) {
             pobj = NULL;
             goto out;
         }
         obj = parent;
@@ -6273,55 +6261,16 @@ js_XDRObject(JSXDRState *xdr, JSObject *
                              JSMSG_CANT_XDR_CLASS, clasp->name);
         return JS_FALSE;
     }
     return clasp->xdrObject(xdr, objp);
 }
 
 #endif /* JS_HAS_XDR */
 
-#ifdef JS_DUMP_SCOPE_METERS
-
-#include <stdio.h>
-
-JSBasicStats js_entry_count_bs = JS_INIT_STATIC_BASIC_STATS;
-
-namespace js {
-
-void
-MeterEntryCount(uintN count)
-{
-    JS_BASIC_STATS_ACCUM(&js_entry_count_bs, count);
-}
-
-}
-
-void
-js_DumpScopeMeters(JSRuntime *rt)
-{
-    static FILE *logfp;
-    if (!logfp)
-        logfp = fopen("/tmp/scope.stats", "a");
-
-    {
-        double mean, sigma;
-
-        mean = JS_MeanAndStdDevBS(&js_entry_count_bs, &sigma);
-
-        fprintf(logfp, "scopes %u entries %g mean %g sigma %g max %u",
-                js_entry_count_bs.num, js_entry_count_bs.sum, mean, sigma,
-                js_entry_count_bs.max);
-    }
-
-    JS_DumpHistogram(&js_entry_count_bs, logfp);
-    JS_BASIC_STATS_INIT(&js_entry_count_bs);
-    fflush(logfp);
-}
-#endif
-
 #ifdef DEBUG
 void
 js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize)
 {
     JS_ASSERT(trc->debugPrinter == js_PrintObjectSlotName);
 
     JSObject *obj = (JSObject *)trc->debugPrintArg;
     uint32 slot = (uint32)trc->debugPrintIndex;
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -193,19 +193,16 @@ struct PropDesc {
     }
     js::StrictPropertyOp setter() const {
         return js::CastAsStrictPropertyOp(setterObject());
     }
 };
 
 typedef Vector<PropDesc, 1> PropDescArray;
 
-void
-MeterEntryCount(uintN count);
-
 } /* namespace js */
 
 enum {
     INVALID_SHAPE = 0x8fffffff,
     SHAPELESS = 0xffffffff
 };
 
 /*
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -233,26 +233,16 @@ JSObject::methodReadBarrier(JSContext *c
     uint32 slot = shape.slot;
     const js::Shape *newshape = methodShapeChange(cx, shape);
     if (!newshape)
         return NULL;
     JS_ASSERT(!newshape->isMethod());
     JS_ASSERT(newshape->slot == slot);
     vp->setObject(*funobj);
     nativeSetSlot(slot, *vp);
-
-#ifdef DEBUG
-    if (cx->runtime->functionMeterFilename) {
-        JS_FUNCTION_METER(cx, mreadbarrier);
-
-        typedef JSRuntime::FunctionCountMap::Ptr Ptr;
-        if (Ptr p = cx->runtime->methodReadBarrierCountMap.lookupWithDefault(fun, 0))
-            ++p->value;
-    }
-#endif
     return newshape;
 }
 
 static JS_ALWAYS_INLINE bool
 ChangesMethodValue(const js::Value &prev, const js::Value &v)
 {
     JSObject *prevObj;
     return prev.isObject() && (prevObj = &prev.toObject())->isFunction() &&
@@ -260,34 +250,30 @@ ChangesMethodValue(const js::Value &prev
 }
 
 inline const js::Shape *
 JSObject::methodWriteBarrier(JSContext *cx, const js::Shape &shape, const js::Value &v)
 {
     if (brandedOrHasMethodBarrier() && shape.slot != SHAPE_INVALID_SLOT) {
         const js::Value &prev = nativeGetSlot(shape.slot);
 
-        if (ChangesMethodValue(prev, v)) {
-            JS_FUNCTION_METER(cx, mwritebarrier);
+        if (ChangesMethodValue(prev, v))
             return methodShapeChange(cx, shape);
-        }
     }
     return &shape;
 }
 
 inline bool
 JSObject::methodWriteBarrier(JSContext *cx, uint32 slot, const js::Value &v)
 {
     if (brandedOrHasMethodBarrier()) {
         const js::Value &prev = nativeGetSlot(slot);
 
-        if (ChangesMethodValue(prev, v)) {
-            JS_FUNCTION_METER(cx, mwslotbarrier);
+        if (ChangesMethodValue(prev, v))
             return methodShapeChange(cx, slot);
-        }
     }
     return true;
 }
 
 inline bool
 JSObject::ensureClassReservedSlots(JSContext *cx)
 {
     return !nativeEmpty() || ensureClassReservedSlotsForEmptyObject(cx);
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -121,22 +121,16 @@ JS_STATIC_ASSERT(pn_offsetof(pn_u.name.a
     JS_BEGIN_MACRO                                                                          \
         if (tokenStream.getToken((__flags)) != tt) {                                        \
             reportErrorNumber(NULL, JSREPORT_ERROR, errno);                                 \
             return NULL;                                                                    \
         }                                                                                   \
     JS_END_MACRO
 #define MUST_MATCH_TOKEN(tt, errno) MUST_MATCH_TOKEN_WITH_FLAGS(tt, errno, 0)
 
-#ifdef METER_PARSENODES
-static uint32 parsenodes = 0;
-static uint32 maxparsenodes = 0;
-static uint32 recyclednodes = 0;
-#endif
-
 void
 JSParseNode::become(JSParseNode *pn2)
 {
     JS_ASSERT(!pn_defn);
     JS_ASSERT(!pn2->pn_defn);
 
     JS_ASSERT(!pn_used);
     if (pn2->pn_used) {
@@ -383,20 +377,16 @@ AddNodeToFreeList(JSParseNode *pn, js::P
 
 #ifdef DEBUG
     /* Poison the node, to catch attempts to use it without initializing it. */
     memset(pn, 0xab, sizeof(*pn));
 #endif
 
     pn->pn_next = parser->nodeList;
     parser->nodeList = pn;
-
-#ifdef METER_PARSENODES
-    recyclednodes++;
-#endif
 }
 
 /* Add |node| to |tc|'s parser's free node list. */
 static inline void
 AddNodeToFreeList(JSParseNode *pn, JSTreeContext *tc)
 {
     AddNodeToFreeList(pn, tc->parser);
 }
@@ -684,21 +674,16 @@ NewOrRecycledNode(JSTreeContext *tc)
         JS_ARENA_ALLOCATE_TYPE(pn, JSParseNode, &cx->tempPool);
         if (!pn)
             js_ReportOutOfMemory(cx);
     } else {
         tc->parser->nodeList = pn->pn_next;
     }
 
     if (pn) {
-#ifdef METER_PARSENODES
-        parsenodes++;
-        if (parsenodes - recyclednodes > maxparsenodes)
-            maxparsenodes = parsenodes - recyclednodes;
-#endif
         pn->pn_used = pn->pn_defn = false;
         memset(&pn->pn_u, 0, sizeof pn->pn_u);
         pn->pn_next = NULL;
     }
     return pn;
 }
 
 /* used only by static create methods of subclasses */
@@ -905,19 +890,16 @@ Compiler::compileScript(JSContext *cx, J
                         JSString *source /* = NULL */,
                         uintN staticLevel /* = 0 */)
 {
     JSArenaPool codePool, notePool;
     TokenKind tt;
     JSParseNode *pn;
     JSScript *script;
     bool inDirectivePrologue;
-#ifdef METER_PARSENODES
-    void *sbrk(ptrdiff_t), *before = sbrk(0);
-#endif
 
     JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL | TCF_NEED_MUTABLE_SCRIPT |
                             TCF_COMPILE_FOR_EVAL)));
 
     /*
      * The scripted callerFrame can only be given for compile-and-go scripts
      * and non-zero static level requires callerFrame.
      */
@@ -1102,58 +1084,32 @@ Compiler::compileScript(JSContext *cx, J
                     slot += cg.sharpSlots();
                 if (slot >= SLOTNO_LIMIT)
                     goto too_many_slots;
                 SET_SLOTNO(code, slot);
             }
         }
     }
 
-#ifdef METER_PARSENODES
-    printf("Parser growth: %d (%u nodes, %u max, %u unrecycled)\n",
-           (char *)sbrk(0) - (char *)before,
-           parsenodes,
-           maxparsenodes,
-           parsenodes - recyclednodes);
-    before = sbrk(0);
-#endif
-
     /*
      * Nowadays the threaded interpreter needs a stop instruction, so we
      * do have to emit that here.
      */
     if (js_Emit1(cx, &cg, JSOP_STOP) < 0)
         goto out;
 
-#ifdef METER_PARSENODES
-    printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n",
-           (char *)sbrk(0) - (char *)before, CG_OFFSET(&cg), cg.noteCount);
-#endif
-
-#ifdef JS_ARENAMETER
-    JS_DumpArenaStats(stdout);
-#endif
-
     JS_ASSERT(cg.version() == version);
 
     script = JSScript::NewScriptFromCG(cx, &cg);
     if (!script)
         goto out;
 
     if (funbox)
         script->savedCallerFun = true;
 
-#ifdef JS_SCOPE_DEPTH_METER
-    JSObject *obj = scopeChain;
-    uintN depth = 1;
-    while ((obj = obj->getParent()) != NULL)
-        ++depth;
-    JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
-#endif
-
     {
         AutoShapeRooter shapeRoot(cx, script->bindings.lastShape());
         if (!defineGlobals(cx, globalScope, script))
             goto late_error;
     }
 
   out:
     JS_FinishArenaPool(&codePool);
@@ -2460,18 +2416,16 @@ DeoptimizeUsesWithin(JSDefinition *dn, c
     }
 
     return ndeoptimized != 0;
 }
 
 void
 Parser::setFunctionKinds(JSFunctionBox *funbox, uint32 *tcflags)
 {
-#define FUN_METER(x) JS_FUNCTION_METER(context, x)
-
     for (;;) {
         JSParseNode *fn = funbox->node;
         JSParseNode *pn = fn->pn_body;
 
         if (funbox->kids) {
             setFunctionKinds(funbox->kids, tcflags);
 
             /*
@@ -2507,22 +2461,20 @@ Parser::setFunctionKinds(JSFunctionBox *
                     funbox->tcflags |= TCF_FUN_UNBRAND_THIS;
             }
         }
 
         JSFunction *fun = funbox->function();
 
         JS_ASSERT(FUN_KIND(fun) == JSFUN_INTERPRETED);
 
-        FUN_METER(allfun);
         if (funbox->tcflags & TCF_FUN_HEAVYWEIGHT) {
-            FUN_METER(heavy);
+            /* nothing to do */
         } else if (funbox->inAnyDynamicScope()) {
             JS_ASSERT(!FUN_NULL_CLOSURE(fun));
-            FUN_METER(indynamicscope);
         } else if (pn->pn_type != TOK_UPVARS) {
             /*
              * No lexical dependencies => null closure, for best performance.
              * A null closure needs no scope chain, but alas we've coupled
              * principals-finding to scope (for good fundamental reasons, but
              * the implementation overloads the parent slot and we should fix
              * that). See, e.g., the JSOP_LAMBDA case in jsinterp.cpp.
              *
@@ -2530,17 +2482,16 @@ Parser::setFunctionKinds(JSFunctionBox *
              * "joined function objects", or not, at its discretion. But real-
              * world implementations always create unique function objects for
              * closures, and this can be detected via mutation. Open question:
              * do popular implementations create unique function objects for
              * null closures?
              *
              * FIXME: bug 476950.
              */
-            FUN_METER(nofreeupvar);
             FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE);
         } else {
             JSAtomList upvars(pn->pn_names);
             JS_ASSERT(upvars.count != 0);
 
             JSAtomListIterator iter(&upvars);
             JSAtomListElement *ale;
 
@@ -2559,20 +2510,18 @@ Parser::setFunctionKinds(JSFunctionBox *
                     JSDefinition *lexdep = ALE_DEFN(ale)->resolve();
 
                     if (!lexdep->isFreeVar()) {
                         JS_ASSERT(lexdep->frameLevel() <= funbox->level);
                         break;
                     }
                 }
 
-                if (!ale) {
-                    FUN_METER(onlyfreevar);
+                if (!ale)
                     FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE);
-                }
             } else {
                 uintN nupvars = 0, nflattened = 0;
 
                 /*
                  * For each lexical dependency from this closure to an outer
                  * binding, analyze whether it is safe to copy the binding's
                  * value into a flat closure slot when the closure is formed.
                  */
@@ -2599,41 +2548,37 @@ Parser::setFunctionKinds(JSFunctionBox *
                          * closure. This is safe because we leave fun's kind
                          * set to interpreted, so all functions holding its
                          * upvars will be flagged as heavyweight.
                          */
                     }
                 }
 
                 if (nupvars == 0) {
-                    FUN_METER(onlyfreevar);
                     FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE);
                 } else if (nflattened == nupvars) {
                     /*
                      * We made it all the way through the upvar loop, so it's
                      * safe to optimize to a flat closure.
                      */
-                    FUN_METER(flat);
                     FUN_SET_KIND(fun, JSFUN_FLAT_CLOSURE);
                     switch (PN_OP(fn)) {
                       case JSOP_DEFFUN:
                         fn->pn_op = JSOP_DEFFUN_FC;
                         break;
                       case JSOP_DEFLOCALFUN:
                         fn->pn_op = JSOP_DEFLOCALFUN_FC;
                         break;
                       case JSOP_LAMBDA:
                         fn->pn_op = JSOP_LAMBDA_FC;
                         break;
                       default:
                         /* js_EmitTree's case TOK_FUNCTION: will select op. */
                         JS_ASSERT(PN_OP(fn) == JSOP_NOP);
                     }
-                } else {
-                    FUN_METER(badfunarg);
                 }
             }
         }
 
         if (FUN_KIND(fun) == JSFUN_INTERPRETED && pn->pn_type == TOK_UPVARS) {
             /*
              * One or more upvars cannot be safely snapshot into a flat
              * closure's non-reserved slot (see JSOP_GETFCSLOT), so we loop
@@ -2658,18 +2603,16 @@ Parser::setFunctionKinds(JSFunctionBox *
 
         if (funbox->joinable())
             fun->setJoinable();
 
         funbox = funbox->siblings;
         if (!funbox)
             break;
     }
-
-#undef FUN_METER
 }
 
 /*
  * Walk the JSFunctionBox tree looking for functions whose call objects may
  * acquire new bindings as they execute: non-strict functions that call eval,
  * and functions that contain function statements (definitions not appearing
  * within the top statement list, which don't take effect unless they are
  * evaluated). Such call objects may acquire bindings that shadow variables
@@ -5609,18 +5552,16 @@ Parser::letStatement()
              * Insert stmt on the tc->topScopeStmt/stmtInfo.downScope linked
              * list stack, if it isn't already there.  If it is there, but it
              * lacks the SIF_SCOPE flag, it must be a try, catch, or finally
              * block.
              */
             stmt->flags |= SIF_SCOPE;
             stmt->downScope = tc->topScopeStmt;
             tc->topScopeStmt = stmt;
-            JS_SCOPE_DEPTH_METERING(++tc->scopeDepth > tc->maxScopeDepth &&
-                                    (tc->maxScopeDepth = tc->scopeDepth));
 
             obj->setParent(tc->blockChain());
             blockbox->parent = tc->blockChainBox;
             tc->blockChainBox = blockbox;
             stmt->blockBox = blockbox;
 
 #ifdef DEBUG
             JSParseNode *tmp = tc->blockNode;
--- a/js/src/jspropertytree.cpp
+++ b/js/src/jspropertytree.cpp
@@ -67,18 +67,16 @@ ShapeHasher::match(const Key k, const Lo
 Shape *
 PropertyTree::newShape(JSContext *cx)
 {
     Shape *shape = js_NewGCShape(cx);
     if (!shape) {
         JS_ReportOutOfMemory(cx);
         return NULL;
     }
-    JS_COMPARTMENT_METER(compartment->livePropTreeNodes++);
-    JS_COMPARTMENT_METER(compartment->totalPropTreeNodes++);
     return shape;
 }
 
 static KidsHash *
 HashChildren(Shape *kid1, Shape *kid2)
 {
     KidsHash *hash = OffTheBooks::new_<KidsHash>();
     if (!hash || !hash->init(2)) {
@@ -187,16 +185,30 @@ PropertyTree::getChild(JSContext *cx, Sh
                       child.flags, child.shortid, js_GenerateShape(cx));
 
     if (!insertChild(cx, parent, shape))
         return NULL;
 
     return shape;
 }
 
+void
+Shape::finalize(JSContext *cx)
+{
+    if (!inDictionary()) {
+        if (parent && parent->isMarked())
+            parent->removeChild(this);
+
+        if (kids.isHash())
+            cx->delete_(kids.toHash());
+    }
+
+    freeTable(cx);
+}
+
 #ifdef DEBUG
 
 void
 KidsPointer::checkConsistency(const Shape *aKid) const
 {
     if (isShape()) {
         JS_ASSERT(toShape() == aKid);
     } else {
@@ -261,43 +273,16 @@ Shape::dump(JSContext *cx, FILE *fp) con
         DUMP_FLAG(IN_DICTIONARY, in_dictionary);
 #undef  DUMP_FLAG
         fputs(") ", fp);
     }
 
     fprintf(fp, "shortid %d\n", shortid);
 }
 
-static void
-MeterKidCount(JSBasicStats *bs, uintN nkids)
-{
-    JS_BASIC_STATS_ACCUM(bs, nkids);
-}
-
-void
-js::PropertyTree::meter(JSBasicStats *bs, Shape *node)
-{
-    uintN nkids = 0;
-    const KidsPointer &kidp = node->kids;
-    if (kidp.isShape()) {
-        meter(bs, kidp.toShape());
-        nkids = 1;
-    } else if (kidp.isHash()) {
-        const KidsHash &hash = *kidp.toHash();
-        for (KidsHash::Range range = hash.all(); !range.empty(); range.popFront()) {
-            Shape *kid = range.front();
-            
-            meter(bs, kid);
-            nkids++;
-        }
-    }
-
-    MeterKidCount(bs, nkids);
-}
-
 void
 Shape::dumpSubtree(JSContext *cx, int level, FILE *fp) const
 {
     if (!parent) {
         JS_ASSERT(level == 0);
         JS_ASSERT(JSID_IS_EMPTY(propid));
         fprintf(fp, "class %s emptyShape %u\n", clasp->name, shapeid);
     } else {
@@ -318,181 +303,43 @@ Shape::dumpSubtree(JSContext *cx, int le
 
                 JS_ASSERT(kid->parent == this);
                 kid->dumpSubtree(cx, level, fp);
             }
         }
     }
 }
 
-#endif /* DEBUG */
-
-void
-Shape::finalize(JSContext *cx)
-{
-#ifdef DEBUG
-    if ((flags & SHARED_EMPTY) && cx->runtime->meterEmptyShapes())
-        compartment()->emptyShapes.remove((EmptyShape *)this);
-#endif
-
-    if (inDictionary()) {
-        JS_COMPARTMENT_METER(compartment()->liveDictModeNodes--);
-    } else {
-        if (parent && parent->isMarked())
-            parent->removeChild(this);
-
-        if (kids.isHash())
-            cx->delete_(kids.toHash());
-    }
-
-    freeTable(cx);
-    JS_COMPARTMENT_METER(compartment()->livePropTreeNodes--);
-}
-
-void
-js::PropertyTree::dumpShapeStats()
-{
-#ifdef DEBUG
-    JSRuntime *rt = compartment->rt;
-
-    JSBasicStats bs;
-    static FILE *logfp;
-    if (!logfp) {
-        if (const char *filename = rt->propTreeStatFilename)
-            logfp = fopen(filename, "w");
-        if (!logfp)
-            return;
-    }
-
-    JS_BASIC_STATS_INIT(&bs);
-
-    uint32 empties;
-    {
-        typedef JSCompartment::EmptyShapeSet HS;
-
-        HS &h = compartment->emptyShapes;
-        empties = h.count();
-        MeterKidCount(&bs, empties);
-        for (HS::Range r = h.all(); !r.empty(); r.popFront())
-            meter(&bs, r.front());
-    }
-
-    double nodes = compartment->livePropTreeNodes;
-    double dicts = compartment->liveDictModeNodes;
-
-    /* Empty scope nodes are never hashed, so subtract them from nodes. */
-    JS_ASSERT(nodes - dicts == bs.sum);
-    nodes -= empties;
-
-    double sigma;
-    double mean = JS_MeanAndStdDevBS(&bs, &sigma);
-
-    fprintf(logfp,
-            "nodes %g (dicts %g) meankids %g sigma %g max %u\n",
-            nodes, dicts, mean, sigma, bs.max);
-
-    JS_DumpHistogram(&bs, logfp);
-
-    /* This data is global, so only print it once per GC. */
-    if (compartment == rt->atomsCompartment) {
-        fprintf(logfp,
-                "\nProperty tree stats for gcNumber %lu\n",
-                (unsigned long) rt->gcNumber);
-
-#define RATE(f1, f2) (((double)js_scope_stats.f1 / js_scope_stats.f2) * 100.0)
-
-        fprintf(logfp,
-                "Scope search stats:\n"
-                "  searches:        %6u\n"
-                "  hits:            %6u %5.2f%% of searches\n"
-                "  misses:          %6u %5.2f%%\n"
-                "  hashes:          %6u %5.2f%%\n"
-                "  hashHits:        %6u %5.2f%% (%5.2f%% of hashes)\n"
-                "  hashMisses:      %6u %5.2f%% (%5.2f%%)\n"
-                "  steps:           %6u %5.2f%% (%5.2f%%)\n"
-                "  stepHits:        %6u %5.2f%% (%5.2f%%)\n"
-                "  stepMisses:      %6u %5.2f%% (%5.2f%%)\n"
-                "  initSearches:    %6u\n"
-                "  changeSearches:  %6u\n"
-                "  tableAllocFails: %6u\n"
-                "  toDictFails:     %6u\n"
-                "  wrapWatchFails:  %6u\n"
-                "  adds:            %6u\n"
-                "  addFails:        %6u\n"
-                "  puts:            %6u\n"
-                "  redundantPuts:   %6u\n"
-                "  putFails:        %6u\n"
-                "  changes:         %6u\n"
-                "  changeFails:     %6u\n"
-                "  compresses:      %6u\n"
-                "  grows:           %6u\n"
-                "  removes:         %6u\n"
-                "  removeFrees:     %6u\n"
-                "  uselessRemoves:  %6u\n"
-                "  shrinks:         %6u\n",
-                js_scope_stats.searches,
-                js_scope_stats.hits, RATE(hits, searches),
-                js_scope_stats.misses, RATE(misses, searches),
-                js_scope_stats.hashes, RATE(hashes, searches),
-                js_scope_stats.hashHits, RATE(hashHits, searches), RATE(hashHits, hashes),
-                js_scope_stats.hashMisses, RATE(hashMisses, searches), RATE(hashMisses, hashes),
-                js_scope_stats.steps, RATE(steps, searches), RATE(steps, hashes),
-                js_scope_stats.stepHits, RATE(stepHits, searches), RATE(stepHits, hashes),
-                js_scope_stats.stepMisses, RATE(stepMisses, searches), RATE(stepMisses, hashes),
-                js_scope_stats.initSearches,
-                js_scope_stats.changeSearches,
-                js_scope_stats.tableAllocFails,
-                js_scope_stats.toDictFails,
-                js_scope_stats.wrapWatchFails,
-                js_scope_stats.adds,
-                js_scope_stats.addFails,
-                js_scope_stats.puts,
-                js_scope_stats.redundantPuts,
-                js_scope_stats.putFails,
-                js_scope_stats.changes,
-                js_scope_stats.changeFails,
-                js_scope_stats.compresses,
-                js_scope_stats.grows,
-                js_scope_stats.removes,
-                js_scope_stats.removeFrees,
-                js_scope_stats.uselessRemoves,
-                js_scope_stats.shrinks);
-    }
-
-#undef RATE
-
-    fflush(logfp);
-#endif /* DEBUG */
-}
-
-#ifdef DEBUG
 void
 js::PropertyTree::dumpShapes(JSContext *cx)
 {
-    JSRuntime *rt = cx->runtime;
+    static bool init = false;
+    static FILE *dumpfp = NULL;
+    if (!init) {
+        init = true;
+        const char *name = getenv("JS_DUMP_SHAPES_FILE");
+        if (!name)
+            return;
+        dumpfp = fopen(name, "a");
+    }
 
-    if (const char *filename = rt->propTreeDumpFilename) {
-        char pathname[1024];
-        JS_snprintf(pathname, sizeof pathname, "%s.%lu",
-                    filename, (unsigned long)rt->gcNumber);
-        FILE *dumpfp = fopen(pathname, "w");
-        if (dumpfp) {
-            typedef JSCompartment::EmptyShapeSet HS;
+    if (!dumpfp)
+        return;
 
-            for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
-                if (rt->gcCurrentCompartment != NULL && rt->gcCurrentCompartment != *c)
-                    continue;
+    JSRuntime *rt = cx->runtime;
+    fprintf(dumpfp, "rt->gcNumber = %lu", (unsigned long)rt->gcNumber);
 
-                fprintf(dumpfp, "*** Compartment %p ***\n", (void *)*c);
+    for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
+        if (rt->gcCurrentCompartment != NULL && rt->gcCurrentCompartment != *c)
+            continue;
 
-                HS &h = (*c)->emptyShapes;
-                for (HS::Range r = h.all(); !r.empty(); r.popFront()) {
-                    Shape *empty = r.front();
-                    empty->dumpSubtree(cx, 0, dumpfp);
-                    putc('\n', dumpfp);
-                }
-            }
+        fprintf(dumpfp, "*** Compartment %p ***\n", (void *)*c);
 
-            fclose(dumpfp);
+        typedef JSCompartment::EmptyShapeSet HS;
+        HS &h = (*c)->emptyShapes;
+        for (HS::Range r = h.all(); !r.empty(); r.popFront()) {
+            Shape *empty = r.front();
+            empty->dumpSubtree(cx, 0, dumpfp);
+            putc('\n', dumpfp);
         }
     }
 }
 #endif
--- a/js/src/jspropertytree.h
+++ b/js/src/jspropertytree.h
@@ -112,17 +112,16 @@ class PropertyTree
     PropertyTree(JSCompartment *comp)
         : compartment(comp)
     {
     }
     
     js::Shape *newShape(JSContext *cx);
     js::Shape *getChild(JSContext *cx, js::Shape *parent, const js::Shape &child);
 
-    void dumpShapeStats();
 #ifdef DEBUG
     static void dumpShapes(JSContext *cx);
     static void meter(JSBasicStats *bs, js::Shape *node);
 #endif
 };
 
 } /* namespace js */
 
--- a/js/src/jsscope.cpp
+++ b/js/src/jsscope.cpp
@@ -130,24 +130,16 @@ JSObject::ensureClassReservedSlotsForEmp
     if (nfixed > numSlots() && !allocSlots(cx, nfixed))
         return false;
 
     return true;
 }
 
 #define PROPERTY_TABLE_NBYTES(n) ((n) * sizeof(Shape *))
 
-#ifdef DEBUG
-JS_FRIEND_DATA(JSScopeStats) js_scope_stats = {0};
-
-# define METER(x)       JS_ATOMIC_INCREMENT(&js_scope_stats.x)
-#else
-# define METER(x)       ((void) 0)
-#endif
-
 bool
 PropertyTable::init(JSRuntime *rt, Shape *lastProp)
 {
     /*
      * Either we're creating a table for a large scope that was populated
      * via property cache hit logic under JSOP_INITPROP, JSOP_SETNAME, or
      * JSOP_SETPROP; or else calloc failed at least once already. In any
      * event, let's try to grow, overallocating to hold at least twice the
@@ -157,26 +149,22 @@ PropertyTable::init(JSRuntime *rt, Shape
     if (sizeLog2 < MIN_SIZE_LOG2)
         sizeLog2 = MIN_SIZE_LOG2;
 
     /*
      * Use rt->calloc_ for memory accounting and overpressure handling
      * without OOM reporting. See PropertyTable::change.
      */
     entries = (Shape **) rt->calloc_(JS_BIT(sizeLog2) * sizeof(Shape *));
-    if (!entries) {
-        METER(tableAllocFails);
+    if (!entries)
         return false;
-    }
 
     hashShift = JS_DHASH_BITS - sizeLog2;
     for (Shape::Range r = lastProp->all(); !r.empty(); r.popFront()) {
         const Shape &shape = r.front();
-        METER(searches);
-        METER(initSearches);
         Shape **spp = search(shape.propid, true);
 
         /*
          * Beware duplicate args and arg vs. var conflicts: the youngest shape
          * (nearest to lastProp) must win. See bug 600067.
          */
         if (!SHAPE_FETCH(spp))
             SHAPE_STORE_PRESERVING_COLLISION(spp, &shape);
@@ -196,23 +184,16 @@ Shape::hashify(JSRuntime *rt)
         rt->free_(table);
         return false;
     }
 
     setTable(table);
     return true;
 }
 
-#ifdef DEBUG
-# include "jsprf.h"
-# define LIVE_SCOPE_METER(cx,expr) JS_LOCK_RUNTIME_VOID(cx->runtime,expr)
-#else
-# define LIVE_SCOPE_METER(cx,expr) /* nothing */
-#endif
-
 JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
 JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
 
 #if JS_BYTES_PER_WORD == 4
 # define HASH_ID(id) ((JSHashNumber)(JSID_BITS(id)))
 #elif JS_BYTES_PER_WORD == 8
 # define HASH_ID(id) ((JSHashNumber)(JSID_BITS(id)) ^ (JSHashNumber)((JSID_BITS(id)) >> 32))
 #else
@@ -236,36 +217,29 @@ PropertyTable::search(jsid id, bool addi
     int sizeLog2;
     Shape *stored, *shape, **spp, **firstRemoved;
     uint32 sizeMask;
 
     JS_ASSERT(entries);
     JS_ASSERT(!JSID_IS_VOID(id));
 
     /* Compute the primary hash address. */
-    METER(hashes);
     hash0 = HASH0(id);
     hash1 = HASH1(hash0, hashShift);
     spp = entries + hash1;
 
     /* Miss: return space for a new entry. */
     stored = *spp;
-    if (SHAPE_IS_FREE(stored)) {
-        METER(misses);
-        METER(hashMisses);
+    if (SHAPE_IS_FREE(stored))
         return spp;
-    }
 
     /* Hit: return entry. */
     shape = SHAPE_CLEAR_COLLISION(stored);
-    if (shape && shape->propid == id) {
-        METER(hits);
-        METER(hashHits);
+    if (shape && shape->propid == id)
         return spp;
-    }
 
     /* Collision: double hash. */
     sizeLog2 = JS_DHASH_BITS - hashShift;
     hash2 = HASH2(hash0, sizeLog2, hashShift);
     sizeMask = JS_BITMASK(sizeLog2);
 
 #ifdef DEBUG
     jsuword collision_flag = SHAPE_COLLISION;
@@ -279,32 +253,26 @@ PropertyTable::search(jsid id, bool addi
         if (adding && !SHAPE_HAD_COLLISION(stored))
             SHAPE_FLAG_COLLISION(spp, shape);
 #ifdef DEBUG
         collision_flag &= jsuword(*spp) & SHAPE_COLLISION;
 #endif
     }
 
     for (;;) {
-        METER(steps);
         hash1 -= hash2;
         hash1 &= sizeMask;
         spp = entries + hash1;
 
         stored = *spp;
-        if (SHAPE_IS_FREE(stored)) {
-            METER(misses);
-            METER(stepMisses);
+        if (SHAPE_IS_FREE(stored))
             return (adding && firstRemoved) ? firstRemoved : spp;
-        }
 
         shape = SHAPE_CLEAR_COLLISION(stored);
         if (shape && shape->propid == id) {
-            METER(hits);
-            METER(stepHits);
             JS_ASSERT(collision_flag);
             return spp;
         }
 
         if (SHAPE_IS_REMOVED(stored)) {
             if (!firstRemoved)
                 firstRemoved = spp;
         } else {
@@ -333,33 +301,29 @@ PropertyTable::change(int log2Delta, JSC
      * Grow, shrink, or compress by changing this->entries.
      */
     oldlog2 = JS_DHASH_BITS - hashShift;
     newlog2 = oldlog2 + log2Delta;
     oldsize = JS_BIT(oldlog2);
     newsize = JS_BIT(newlog2);
     nbytes = PROPERTY_TABLE_NBYTES(newsize);
     newTable = (Shape **) cx->calloc_(nbytes);
-    if (!newTable) {
-        METER(tableAllocFails);
+    if (!newTable)
         return false;
-    }
 
     /* Now that we have newTable allocated, update members. */
     hashShift = JS_DHASH_BITS - newlog2;
     removedCount = 0;
     oldTable = entries;
     entries = newTable;
 
     /* Copy only live entries, leaving removed and free ones behind. */
     for (oldspp = oldTable; oldsize != 0; oldspp++) {
         shape = SHAPE_FETCH(oldspp);
         if (shape) {
-            METER(searches);
-            METER(changeSearches);
             spp = search(shape->propid, true);
             JS_ASSERT(SHAPE_IS_FREE(*spp));
             *spp = shape;
         }
         oldsize--;
     }
 
     /* Finally, free the old entries storage. */
@@ -369,20 +333,16 @@ PropertyTable::change(int log2Delta, JSC
 
 bool
 PropertyTable::grow(JSContext *cx)
 {
     JS_ASSERT(needsToGrow());
 
     uint32 size = capacity();
     int delta = removedCount < size >> 2;
-    if (!delta)
-        METER(compresses);
-    else
-        METER(grows);
 
     if (!change(delta, cx) && entryCount + removedCount == size - 1) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
     return true;
 }
 
@@ -405,17 +365,16 @@ Shape::getChild(JSContext *cx, const js:
             return NULL;
 
         if (newDictionaryShape(cx, child, listp)) {
             Shape *newShape = *listp;
 
             JS_ASSERT(oldShape == newShape->parent);
             if (table) {
                 /* Add newShape to the property table. */
-                METER(searches);
                 Shape **spp = table->search(newShape->propid, true);
 
                 /*
                  * Beware duplicate formal parameters, allowed by ECMA-262 in
                  * non-strict mode. Otherwise we know that Bindings::add (our
                  * caller) won't pass an id already in the table to us. In the
                  * case of duplicate formals, the last one wins, so while we
                  * must not overcount entries, we must store newShape.
@@ -520,18 +479,16 @@ Shape::newDictionaryShape(JSContext *cx,
         return NULL;
 
     new (dprop) Shape(child.propid, child.rawGetter, child.rawSetter, child.slot, child.attrs,
                       (child.flags & ~FROZEN) | IN_DICTIONARY, child.shortid,
                       js_GenerateShape(cx), child.slotSpan);
 
     dprop->listp = NULL;
     dprop->insertIntoDictionary(listp);
-
-    JS_COMPARTMENT_METER(cx->compartment->liveDictModeNodes++);
     return dprop;
 }
 
 Shape *
 Shape::newDictionaryList(JSContext *cx, Shape **listp)
 {
     Shape *shape = *listp;
     Shape *list = shape;
@@ -544,17 +501,16 @@ Shape::newDictionaryList(JSContext *cx, 
     Shape *root = NULL;
     Shape **childp = &root;
 
     while (shape) {
         JS_ASSERT_IF(!shape->frozen(), !shape->inDictionary());
 
         Shape *dprop = Shape::newDictionaryShape(cx, *shape, childp);
         if (!dprop) {
-            METER(toDictFails);
             *listp = list;
             return NULL;
         }
 
         JS_ASSERT(!dprop->hasTable());
         childp = &dprop->parent;
         shape = shape->parent;
     }
@@ -708,21 +664,17 @@ JSObject::addProperty(JSContext *cx, jsi
     Shape **spp = nativeSearch(id, true);
     JS_ASSERT(!SHAPE_FETCH(spp));
     const Shape *shape = addPropertyInternal(cx, id, getter, setter, slot, attrs, 
                                              flags, shortid, spp);
     if (!shape)
         return NULL;
 
     /* Update any watchpoints referring to this property. */
-    shape = js_UpdateWatchpointsForShape(cx, this, shape);
-    if (!shape)
-        METER(wrapWatchFails);
-
-    return shape;
+    return js_UpdateWatchpointsForShape(cx, this, shape);
 }
 
 const Shape *
 JSObject::addPropertyInternal(JSContext *cx, jsid id,
                               PropertyOp getter, StrictPropertyOp setter,
                               uint32 slot, uintN attrs,
                               uintN flags, intN shortid,
                               Shape **spp)
@@ -738,18 +690,16 @@ JSObject::addPropertyInternal(JSContext 
             table = lastProp->getTable();
         }
     } else if (lastProp->hasTable()) {
         table = lastProp->getTable();
         if (table->needsToGrow()) {
             if (!table->grow(cx))
                 return NULL;
 
-            METER(searches);
-            METER(changeSearches);
             spp = table->search(id, true);
             JS_ASSERT(!SHAPE_FETCH(spp));
         }
     }
 
     /* Find or create a property tree node labeled by our arguments. */
     const Shape *shape;
     {
@@ -767,22 +717,20 @@ JSObject::addPropertyInternal(JSContext 
 
             /* Pass the table along to the new lastProp, namely shape. */
             JS_ASSERT(shape->parent->getTable() == table);
             shape->parent->setTable(NULL);
             shape->setTable(table);
         }
 
         CHECK_SHAPE_CONSISTENCY(this);
-        METER(adds);
         return shape;
     }
 
     CHECK_SHAPE_CONSISTENCY(this);
-    METER(addFails);
     return NULL;
 }
 
 /*
  * Check and adjust the new attributes for the shape to make sure that our
  * slot access optimizations are sound. It is responsibility of the callers to
  * enforce all restrictions from ECMA-262 v5 8.12.9 [[DefineOwnProperty]].
  */
@@ -837,20 +785,17 @@ JSObject::putProperty(JSContext *cx, jsi
             reportNotExtensible(cx);
             return NULL;
         }
 
         const Shape *newShape =
             addPropertyInternal(cx, id, getter, setter, slot, attrs, flags, shortid, spp);
         if (!newShape)
             return NULL;
-        newShape = js_UpdateWatchpointsForShape(cx, this, newShape);
-        if (!newShape)
-            METER(wrapWatchFails);
-        return newShape;
+        return js_UpdateWatchpointsForShape(cx, this, newShape);
     }
 
     /* Property exists: search must have returned a valid *spp. */
     JS_ASSERT(!SHAPE_IS_REMOVED(*spp));
 
     if (!CheckCanChangeAttrs(cx, this, shape, &attrs))
         return NULL;
     
@@ -863,20 +808,18 @@ JSObject::putProperty(JSContext *cx, jsi
     uint32 oldSlot = shape->slot;
     if (!(attrs & JSPROP_SHARED) && slot == SHAPE_INVALID_SLOT && hadSlot)
         slot = oldSlot;
 
     /*
      * Now that we've possibly preserved slot, check whether all members match.
      * If so, this is a redundant "put" and we can return without more work.
      */
-    if (shape->matchesParamsAfterId(getter, setter, slot, attrs, flags, shortid)) {
-        METER(redundantPuts);
+    if (shape->matchesParamsAfterId(getter, setter, slot, attrs, flags, shortid))
         return shape;
-    }
 
     /*
      * Overwriting a non-last property requires switching to dictionary mode.
      * The shape tree is shared immutable, and we can't removeProperty and then
      * addPropertyInternal because a failure under add would lose data.
      */
     if (shape != lastProp && !inDictionaryMode()) {
         if (!toDictionaryMode(cx))
@@ -950,17 +893,16 @@ JSObject::putProperty(JSContext *cx, jsi
 
         /* Find or create a property tree node labeled by our arguments. */
         Shape child(id, getter, setter, slot, attrs, flags, shortid);
 
         Shape *newShape = getChildProperty(cx, lastProp, child);
         if (!newShape) {
             setLastProperty(shape);
             CHECK_SHAPE_CONSISTENCY(this);
-            METER(putFails);
             return NULL;
         }
 
         shape = newShape;
     }
 
     /*
      * Can't fail now, so free the previous incarnation's slot if the new shape
@@ -972,22 +914,18 @@ JSObject::putProperty(JSContext *cx, jsi
         if (oldSlot < shape->slotSpan)
             freeSlot(cx, oldSlot);
         else
             getSlotRef(oldSlot).setUndefined();
         JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals);
     }
 
     CHECK_SHAPE_CONSISTENCY(this);
-    METER(puts);
 
-    const Shape *newShape = js_UpdateWatchpointsForShape(cx, this, shape);
-    if (!newShape)
-        METER(wrapWatchFails);
-    return newShape;
+    return js_UpdateWatchpointsForShape(cx, this, shape);
 }
 
 const Shape *
 JSObject::changeProperty(JSContext *cx, const Shape *shape, uintN attrs, uintN mask,
                          PropertyOp getter, StrictPropertyOp setter)
 {
     JS_ASSERT_IF(inDictionaryMode(), !lastProp->frozen());
     JS_ASSERT(!JSID_IS_VOID(shape->propid));
@@ -1044,20 +982,18 @@ JSObject::changeProperty(JSContext *cx, 
 
         updateFlags(shape);
 
         /* See the corresponding code in putProperty. */
         lastProp->shapeid = js_GenerateShape(cx);
         clearOwnShape();
 
         shape = js_UpdateWatchpointsForShape(cx, this, shape);
-        if (!shape) {
-            METER(wrapWatchFails);
+        if (!shape)
             return NULL;
-        }
         JS_ASSERT(shape == mutableShape);
         newShape = mutableShape;
     } else if (shape == lastProp) {
         Shape child(shape->propid, getter, setter, shape->slot, attrs, shape->flags,
                     shape->shortid);
 
         newShape = getChildProperty(cx, shape->parent, child);
 #ifdef DEBUG
@@ -1075,41 +1011,29 @@ JSObject::changeProperty(JSContext *cx, 
          * the conservation of shape->slot (if it's valid). We must not call
          * removeProperty because it will free an allocated shape->slot, and
          * putProperty won't re-allocate it.
          */
         Shape child(shape->propid, getter, setter, shape->slot, attrs, shape->flags,
                     shape->shortid);
         newShape = putProperty(cx, child.propid, child.rawGetter, child.rawSetter, child.slot,
                                child.attrs, child.flags, child.shortid);
-#ifdef DEBUG
-        if (newShape)
-            METER(changePuts);
-#endif
     }
 
-#ifdef DEBUG
     CHECK_SHAPE_CONSISTENCY(this);
-    if (newShape)
-        METER(changes);
-    else
-        METER(changeFails);
-#endif
     return newShape;
 }
 
 bool
 JSObject::removeProperty(JSContext *cx, jsid id)
 {
     Shape **spp = nativeSearch(id);
     Shape *shape = SHAPE_FETCH(spp);
-    if (!shape) {
-        METER(uselessRemoves);
+    if (!shape)
         return true;
-    }
 
     /* First, if shape is unshared and not has a slot, free its slot number. */
     bool addedToFreelist = false;
     bool hadSlot = !shape->isAlias() && shape->hasSlot();
     if (hadSlot) {
         addedToFreelist = freeSlot(cx, shape->slot);
         JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals);
     }
@@ -1131,17 +1055,16 @@ JSObject::removeProperty(JSContext *cx, 
         PropertyTable *table = lastProp->hasTable() ? lastProp->getTable() : NULL;
 
         if (SHAPE_HAD_COLLISION(*spp)) {
             JS_ASSERT(table);
             *spp = SHAPE_REMOVED;
             ++table->removedCount;
             --table->entryCount;
         } else {
-            METER(removeFrees);
             if (table) {
                 *spp = NULL;
                 --table->entryCount;
 
 #ifdef DEBUG
                 /*
                  * Check the consistency of the table but limit the number of
                  * checks not to alter significantly the complexity of the
@@ -1219,31 +1142,28 @@ JSObject::removeProperty(JSContext *cx, 
         }
     }
     updateShape(cx);
 
     /* On the way out, consider shrinking table if its load factor is <= .25. */
     if (lastProp->hasTable()) {
         PropertyTable *table = lastProp->getTable();
         uint32 size = table->capacity();
-        if (size > PropertyTable::MIN_SIZE && table->entryCount <= size >> 2) {
-            METER(shrinks);
+        if (size > PropertyTable::MIN_SIZE && table->entryCount <= size >> 2)
             (void) table->change(-1, cx);
-        }
     }
 
     /* Also, consider shrinking object slots if 25% or more are unused. */
     if (hasSlotsArray()) {
         JS_ASSERT(slotSpan() <= numSlots());
         if ((slotSpan() + (slotSpan() >> 2)) < numSlots())
             shrinkSlots(cx, slotSpan());
     }
 
     CHECK_SHAPE_CONSISTENCY(this);
-    METER(removes);
     return true;
 }
 
 void
 JSObject::clear(JSContext *cx)
 {
     Shape *shape = lastProp;
     JS_ASSERT(inDictionaryMode() == shape->inDictionary());
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -672,63 +672,22 @@ struct EmptyShape : public js::Shape
                            : (shape)->propid)
 
 extern uint32
 js_GenerateShape(JSRuntime *rt);
 
 extern uint32
 js_GenerateShape(JSContext *cx);
 
-#ifdef DEBUG
-struct JSScopeStats {
-    jsrefcount          searches;
-    jsrefcount          hits;
-    jsrefcount          misses;
-    jsrefcount          hashes;
-    jsrefcount          hashHits;
-    jsrefcount          hashMisses;
-    jsrefcount          steps;
-    jsrefcount          stepHits;
-    jsrefcount          stepMisses;
-    jsrefcount          initSearches;
-    jsrefcount          changeSearches;
-    jsrefcount          tableAllocFails;
-    jsrefcount          toDictFails;
-    jsrefcount          wrapWatchFails;
-    jsrefcount          adds;
-    jsrefcount          addFails;
-    jsrefcount          puts;
-    jsrefcount          redundantPuts;
-    jsrefcount          putFails;
-    jsrefcount          changes;
-    jsrefcount          changePuts;
-    jsrefcount          changeFails;
-    jsrefcount          compresses;
-    jsrefcount          grows;
-    jsrefcount          removes;
-    jsrefcount          removeFrees;
-    jsrefcount          uselessRemoves;
-    jsrefcount          shrinks;
-};
-
-extern JS_FRIEND_DATA(JSScopeStats) js_scope_stats;
-
-# define METER(x)       JS_ATOMIC_INCREMENT(&js_scope_stats.x)
-#else
-# define METER(x)       /* nothing */
-#endif
-
 namespace js {
 
 JS_ALWAYS_INLINE js::Shape **
 Shape::search(JSRuntime *rt, js::Shape **startp, jsid id, bool adding)
 {
     js::Shape *start = *startp;
-    METER(searches);
-
     if (start->hasTable())
         return start->getTable()->search(id, adding);
 
     if (start->numLinearSearches == PropertyTable::MAX_LINEAR_SEARCHES) {
         if (start->hashify(rt))
             return start->getTable()->search(id, adding);
         /* OOM!  Don't increment numLinearSearches, to keep hasTable() false. */
         JS_ASSERT(!start->hasTable());
@@ -742,27 +701,22 @@ Shape::search(JSRuntime *rt, js::Shape *
      * from *startp.
      *
      * We don't use a Range here, or stop at null parent (the empty shape
      * at the end), to avoid an extra load per iteration just to save a
      * load and id test at the end (when missing).
      */
     js::Shape **spp;
     for (spp = startp; js::Shape *shape = *spp; spp = &shape->parent) {
-        if (shape->propid == id) {
-            METER(hits);
+        if (shape->propid == id)
             return spp;
-        }
     }
-    METER(misses);
     return spp;
 }
 
-#undef METER
-
 } // namespace js
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #pragma warning(pop)
 #endif
 
 #endif /* jsscope_h___ */
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -345,22 +345,17 @@ Shape::insertIntoDictionary(js::Shape **
         parent->listp = &parent;
     listp = dictp;
     *dictp = this;
 }
 
 inline
 EmptyShape::EmptyShape(JSCompartment *comp, js::Class *aclasp)
   : js::Shape(comp, aclasp)
-{
-#ifdef DEBUG
-    if (comp->rt->meterEmptyShapes())
-        comp->emptyShapes.put(this);
-#endif
-}
+{}
 
 /* static */ inline EmptyShape *
 EmptyShape::getEmptyArgumentsShape(JSContext *cx)
 {
     return ensure(cx, &NormalArgumentsObject::jsClass, &cx->compartment->emptyArgumentsShape);
 }
 
 /* static */ inline EmptyShape *
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -901,26 +901,16 @@ SaveScriptFilename(JSContext *cx, const 
         if (!sfe) {
             JS_ReportOutOfMemory(cx);
             return NULL;
         }
         sfe->key = strcpy(sfe->filename, filename);
         sfe->mark = JS_FALSE;
     }
 
-#ifdef DEBUG
-    if (rt->functionMeterFilename) {
-        size_t len = strlen(sfe->filename);
-        if (len >= sizeof rt->lastScriptFilename)
-            len = sizeof rt->lastScriptFilename - 1;
-        memcpy(rt->lastScriptFilename, sfe->filename, len);
-        rt->lastScriptFilename[len] = '\0';
-    }
-#endif
-
     return sfe->filename;
 }
 
 /*
  * Back up from a saved filename by its offset within its hash table entry.
  */
 #define FILENAME_TO_SFE(fn) \
     ((ScriptFilenameEntry *) ((fn) - offsetof(ScriptFilenameEntry, filename)))
@@ -1369,41 +1359,16 @@ JSScript::NewScriptFromCG(JSContext *cx,
         script->owner = NULL;
 #endif
         if (cg->flags & TCF_FUN_HEAVYWEIGHT)
             fun->flags |= JSFUN_HEAVYWEIGHT;
     }
 
     /* Tell the debugger about this compiled script. */
     js_CallNewScriptHook(cx, script, fun);
-#ifdef DEBUG
-    {
-        jsrefcount newEmptyLive, newLive, newTotal;
-        if (script->isEmpty()) {
-            newEmptyLive = JS_RUNTIME_METER(cx->runtime, liveEmptyScripts);
-            newLive = cx->runtime->liveScripts;
-            newTotal =
-                JS_RUNTIME_METER(cx->runtime, totalEmptyScripts) + cx->runtime->totalScripts;
-        } else {
-            newEmptyLive = cx->runtime->liveEmptyScripts;
-            newLive = JS_RUNTIME_METER(cx->runtime, liveScripts);
-            newTotal =
-                cx->runtime->totalEmptyScripts + JS_RUNTIME_METER(cx->runtime, totalScripts);
-        }
-
-        jsrefcount oldHigh = cx->runtime->highWaterLiveScripts;
-        if (newEmptyLive + newLive > oldHigh) {
-            JS_ATOMIC_SET(&cx->runtime->highWaterLiveScripts, newEmptyLive + newLive);
-            if (getenv("JS_DUMP_LIVE_SCRIPTS")) {
-                fprintf(stderr, "high water script count: %d empty, %d not (total %d)\n",
-                        newEmptyLive, newLive, newTotal);
-            }
-        }
-    }
-#endif
 
     return script;
 
 bad:
     js_DestroyScript(cx, script);
     return NULL;
 }
 
@@ -1452,23 +1417,16 @@ js_CallDestroyScriptHook(JSContext *cx, 
     if (hook)
         hook(cx, script, cx->debugHooks->destroyScriptHookData);
     JS_ClearScriptTraps(cx, script);
 }
 
 static void
 DestroyScript(JSContext *cx, JSScript *script)
 {
-#ifdef DEBUG
-    if (script->isEmpty())
-        JS_RUNTIME_UNMETER(cx->runtime, liveEmptyScripts);
-    else
-        JS_RUNTIME_UNMETER(cx->runtime, liveScripts);
-#endif
-
     if (script->principals)
         JSPRINCIPALS_DROP(cx, script->principals);
 
     GSNCache *gsnCache = GetGSNCache(cx);
     if (gsnCache->code == script->code)
         gsnCache->purge();
 
     /*
@@ -1601,49 +1559,40 @@ js_NewScriptObject(JSContext *cx, JSScri
     return obj;
 }
 
 namespace js {
 
 static const uint32 GSN_CACHE_THRESHOLD = 100;
 static const uint32 GSN_CACHE_MAP_INIT_SIZE = 20;
 
-#ifdef JS_GSNMETER
-# define GSN_CACHE_METER(cache,cnt) (++(cache)->stats.cnt)
-#else
-# define GSN_CACHE_METER(cache,cnt) ((void) 0)
-#endif
-
 void
 GSNCache::purge()
 {
     code = NULL;
     if (map.initialized())
         map.finish();
-    GSN_CACHE_METER(this, purges);
 }
 
 } /* namespace js */
 
 jssrcnote *
 js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     size_t target = pc - script->code;
     if (target >= size_t(script->length))
         return NULL;
 
     GSNCache *cache = GetGSNCache(cx);
     if (cache->code == script->code) {
-        GSN_CACHE_METER(cache, hits);
         JS_ASSERT(cache->map.initialized());
         GSNCache::Map::Ptr p = cache->map.lookup(pc);
         return p ? p->value : NULL;
     }
 
-    GSN_CACHE_METER(cache, misses);
     size_t offset = 0;
     jssrcnote *result;
     for (jssrcnote *sn = script->notes(); ; sn = SN_NEXT(sn)) {
         if (SN_IS_TERMINATOR(sn)) {
             result = NULL;
             break;
         }
         offset += SN_DELTA(sn);
@@ -1669,17 +1618,16 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
             pc = script->code;
             for (jssrcnote *sn = script->notes(); !SN_IS_TERMINATOR(sn);
                  sn = SN_NEXT(sn)) {
                 pc += SN_DELTA(sn);
                 if (SN_IS_GETTABLE(sn))
                     JS_ALWAYS_TRUE(cache->map.put(pc, sn));
             }
             cache->code = script->code;
-            GSN_CACHE_METER(cache, fills);
         }
     }
 
     return result;
 }
 
 uintN
 js_FramePCToLineNumber(JSContext *cx, StackFrame *fp, jsbytecode *pc)
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3420,37 +3420,16 @@ js_NewDependentString(JSContext *cx, JSS
     const jschar *chars = base->chars() + start;
 
     if (JSLinearString *staticStr = JSAtom::lookupStatic(chars, length))
         return staticStr;
 
     return JSDependentString::new_(cx, base, chars, length);
 }
 
-#ifdef DEBUG
-#include <math.h>
-
-void printJSStringStats(JSRuntime *rt)
-{
-    double mean, sigma;
-
-    mean = JS_MeanAndStdDev(rt->totalStrings, rt->lengthSum,
-                            rt->lengthSquaredSum, &sigma);
-
-    fprintf(stderr, "%lu total strings, mean length %g (sigma %g)\n",
-            (unsigned long)rt->totalStrings, mean, sigma);
-
-    mean = JS_MeanAndStdDev(rt->totalDependentStrings, rt->strdepLengthSum,
-                            rt->strdepLengthSquaredSum, &sigma);
-
-    fprintf(stderr, "%lu total dependent strings, mean length %g (sigma %g)\n",
-            (unsigned long)rt->totalDependentStrings, mean, sigma);
-}
-#endif
-
 JSFixedString *
 js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n)
 {
     if (JSShortString::lengthFits(n))
         return NewShortString(cx, s, n);
 
     jschar *news = (jschar *) cx->malloc_((n + 1) * sizeof(jschar));
     if (!news)
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -127,20 +127,16 @@ JS_BEGIN_EXTERN_C
  * entire process to stop.
  */
 extern JS_PUBLIC_API(void) JS_Abort(void);
 
 #ifdef DEBUG
 # define JS_BASIC_STATS 1
 #endif
 
-#ifdef DEBUG_brendan
-# define JS_SCOPE_DEPTH_METER 1
-#endif
-
 #ifdef JS_BASIC_STATS
 
 #include <stdio.h>
 
 typedef struct JSBasicStats {
     uint32      num;
     uint32      max;
     double      sum;
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -116,31 +116,16 @@ js_LeaveLocalRootScopeWithResult(JSConte
 {
 }
 
 static inline void
 js_LeaveLocalRootScopeWithResult(JSContext *cx, void *rval)
 {
 }
 
-#ifdef XML_METERING
-static struct {
-    jsrefcount  qname;
-    jsrefcount  xmlnamespace;
-    jsrefcount  xml;
-    jsrefcount  xmlobj;
-} xml_stats;
-
-#define METER(x)        JS_ATOMIC_INCREMENT(&(x))
-#define UNMETER(x)      JS_ATOMIC_DECREMENT(&(x))
-#else
-#define METER(x)        /* nothing */
-#define UNMETER(x)      /* nothing */
-#endif
-
 /*
  * Random utilities and global functions.
  */
 const char js_AttributeName_str[] = "AttributeName";
 const char js_isXMLName_str[]     = "isXMLName";
 const char js_XMLList_str[]       = "XMLList";
 const char js_localName_str[]     = "localName";
 const char js_xml_parent_str[]    = "parent";
@@ -294,17 +279,16 @@ NewXMLNamespace(JSContext *cx, JSLinearS
         return NULL;
 
     if (prefix)
         obj->setNamePrefix(prefix);
     if (uri)
         obj->setNameURI(uri);
     if (declared)
         obj->setNamespaceDeclared(JSVAL_TRUE);
-    METER(xml_stats.xmlnamespace);
     return obj;
 }
 
 /*
  * QName class and library functions.
  */
 DEFINE_GETTER(QNameNameURI_getter,
               if (obj->getClass() == &js_QNameClass)
@@ -508,17 +492,16 @@ static JSObject *
 NewXMLQName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix,
             JSLinearString *localName)
 {
     JSObject *obj = NewBuiltinClassInstanceXML(cx, &js_QNameClass);
     if (!obj)
         return NULL;
     if (!InitXMLQName(cx, obj, uri, prefix, localName))
         return NULL;
-    METER(xml_stats.qname);
     return obj;
 }
 
 static JSObject *
 NewXMLAttributeName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix,
                     JSLinearString *localName)
 {
     /*
@@ -526,17 +509,16 @@ NewXMLAttributeName(JSContext *cx, JSLin
      * exposed to scripts.
      */
     JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AttributeNameClass, NULL, NULL);
     if (!obj)
         return NULL;
     JS_ASSERT(obj->isQName());
     if (!InitXMLQName(cx, obj, uri, prefix, localName))
         return NULL;
-    METER(xml_stats.qname);
     return obj;
 }
 
 JSObject *
 js_ConstructXMLQNameObject(JSContext *cx, const Value &nsval, const Value &lnval)
 {
     Value argv[2];
 
@@ -646,17 +628,16 @@ NamespaceHelper(JSContext *cx, JSObject 
             return JS_FALSE;
     }
 
     /* Per ECMA-357, 13.2.5, these properties must be "own". */
     if (!JS_DefineProperties(cx, obj, namespace_props))
         return JS_FALSE;
 
     *rval = OBJECT_TO_JSVAL(obj);
-    METER(xml_stats.xmlnamespace);
 
     empty = cx->runtime->emptyString;
     obj->setNamePrefix(empty);
     obj->setNameURI(empty);
 
     if (argc == 1 || argc == -1) {
         if (isNamespace) {
             obj->setNameURI(uriobj->getNameURI());
@@ -756,17 +737,16 @@ QNameHelper(JSContext *cx, JSObject *obj
         }
 
         /* Create and return a new QName object exactly as if constructed. */
         obj = NewBuiltinClassInstanceXML(cx, &js_QNameClass);
         if (!obj)
             return JS_FALSE;
     }
     *rval = OBJECT_TO_JSVAL(obj);
-    METER(xml_stats.qname);
 
     if (isQName) {
         /* If namespace is not specified and name is a QName, clone it. */
         qn = JSVAL_TO_OBJECT(nameval);
         if (argc == 1) {
             uri = qn->getNameURI();
             prefix = qn->getNamePrefix();
             name = qn->getQNameLocalName();
@@ -7029,17 +7009,16 @@ js_NewXML(JSContext *cx, JSXMLClass xml_
             xml->xml_attrs.init();
         }
     }
 
 #ifdef DEBUG_notme
     JS_APPEND_LINK(&xml->links, &xml_leaks);
     xml->serial = xml_serial++;
 #endif
-    METER(xml_stats.xml);
     return xml;
 }
 
 void
 js_TraceXML(JSTracer *trc, JSXML *xml)
 {
     if (xml->object)
         MarkObject(trc, *xml->object, "object");
@@ -7092,17 +7071,16 @@ static JSObject *
 NewXMLObject(JSContext *cx, JSXML *xml)
 {
     JSObject *obj;
 
     obj = NewNonFunction<WithProto::Class>(cx, &js_XMLClass, NULL, NULL);
     if (!obj)
         return NULL;
     obj->setPrivate(xml);
-    METER(xml_stats.xmlobj);
     return obj;
 }
 
 JSObject *
 js_GetXMLObject(JSContext *cx, JSXML *xml)
 {
     JSObject *obj;
 
@@ -7146,17 +7124,16 @@ js_InitXMLClass(JSContext *cx, JSObject 
     if (!proto)
         return NULL;
 
     JSXML *xml = js_NewXML(cx, JSXML_CLASS_TEXT);
     if (!xml)
         return NULL;
     proto->setPrivate(xml);
     xml->object = proto;
-    METER(xml_stats.xmlobj);
 
     /*
      * Prepare to set default settings on the XML constructor we just made.
      * NB: We can't use JS_GetConstructor, because it calls
      * JSObject::getProperty, which is xml_getProperty, which creates a new
      * XMLList every time!  We must instead call js_LookupProperty directly.
      */
     JSObject *pobj;
@@ -7376,17 +7353,16 @@ js_GetAnyName(JSContext *cx, jsid *idp)
         if (!obj)
             return false;
 
         JS_ASSERT(!obj->getProto());
 
         JSRuntime *rt = cx->runtime;
         if (!InitXMLQName(cx, obj, rt->emptyString, rt->emptyString, rt->atomState.starAtom))
             return false;
-        METER(xml_stats.qname);
 
         v.setObject(*obj);
         if (!js_SetReservedSlot(cx, global, JSProto_AnyName, v))
             return false;
     }
     *idp = OBJECT_TO_JSID(&v.toObject());
     return true;
 }
--- a/js/src/prmjtime.cpp
+++ b/js/src/prmjtime.cpp
@@ -690,17 +690,16 @@ DSTOffsetCache::computeDSTOffsetMillisec
 
     return diff * MILLISECONDS_PER_SECOND;
 }
 
 JSInt64
 DSTOffsetCache::getDSTOffsetMilliseconds(JSInt64 localTimeMilliseconds, JSContext *cx)
 {
     sanityCheck();
-    noteOffsetCalculation();
 
     JSInt64 localTimeSeconds = localTimeMilliseconds / MILLISECONDS_PER_SECOND;
 
     if (localTimeSeconds > MAX_UNIX_TIMET) {
         localTimeSeconds = MAX_UNIX_TIMET;
     } else if (localTimeSeconds < 0) {
         /* Go ahead a day to make localtime work (does not work with 0). */
         localTimeSeconds = SECONDS_PER_DAY;
@@ -709,130 +708,78 @@ DSTOffsetCache::getDSTOffsetMilliseconds
     /*
      * NB: Be aware of the initial range values when making changes to this
      *     code: the first call to this method, with those initial range
      *     values, must result in a cache miss.
      */
 
     if (rangeStartSeconds <= localTimeSeconds &&
         localTimeSeconds <= rangeEndSeconds) {
-        noteCacheHit();
         return offsetMilliseconds;
     }
 
     if (oldRangeStartSeconds <= localTimeSeconds &&
         localTimeSeconds <= oldRangeEndSeconds) {
-        noteCacheHit();
         return oldOffsetMilliseconds;
     }
 
     oldOffsetMilliseconds = offsetMilliseconds;
     oldRangeStartSeconds = rangeStartSeconds;
     oldRangeEndSeconds = rangeEndSeconds;
 
     if (rangeStartSeconds <= localTimeSeconds) {
         JSInt64 newEndSeconds = JS_MIN(rangeEndSeconds + RANGE_EXPANSION_AMOUNT, MAX_UNIX_TIMET);
         if (newEndSeconds >= localTimeSeconds) {
             JSInt64 endOffsetMilliseconds = computeDSTOffsetMilliseconds(newEndSeconds);
             if (endOffsetMilliseconds == offsetMilliseconds) {
-                noteCacheMissIncrease();
                 rangeEndSeconds = newEndSeconds;
                 return offsetMilliseconds;
             }
 
             offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
             if (offsetMilliseconds == endOffsetMilliseconds) {
-                noteCacheMissIncreasingOffsetChangeUpper();
                 rangeStartSeconds = localTimeSeconds;
                 rangeEndSeconds = newEndSeconds;
             } else {
-                noteCacheMissIncreasingOffsetChangeExpand();
                 rangeEndSeconds = localTimeSeconds;
             }
             return offsetMilliseconds;
         }
 
-        noteCacheMissLargeIncrease();
         offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
         rangeStartSeconds = rangeEndSeconds = localTimeSeconds;
         return offsetMilliseconds;
     }
 
     JSInt64 newStartSeconds = JS_MAX(rangeStartSeconds - RANGE_EXPANSION_AMOUNT, 0);
     if (newStartSeconds <= localTimeSeconds) {
         JSInt64 startOffsetMilliseconds = computeDSTOffsetMilliseconds(newStartSeconds);
         if (startOffsetMilliseconds == offsetMilliseconds) {
-            noteCacheMissDecrease();
             rangeStartSeconds = newStartSeconds;
             return offsetMilliseconds;
         }
 
         offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
         if (offsetMilliseconds == startOffsetMilliseconds) {
-            noteCacheMissDecreasingOffsetChangeLower();
             rangeStartSeconds = newStartSeconds;
             rangeEndSeconds = localTimeSeconds;
         } else {
-            noteCacheMissDecreasingOffsetChangeExpand();
             rangeStartSeconds = localTimeSeconds;
         }
         return offsetMilliseconds;
     }
 
-    noteCacheMissLargeDecrease();
     rangeStartSeconds = rangeEndSeconds = localTimeSeconds;
     offsetMilliseconds = computeDSTOffsetMilliseconds(localTimeSeconds);
     return offsetMilliseconds;
 }
 
 void
 DSTOffsetCache::sanityCheck()
 {
     JS_ASSERT(rangeStartSeconds <= rangeEndSeconds);
     JS_ASSERT_IF(rangeStartSeconds == INT64_MIN, rangeEndSeconds == INT64_MIN);
     JS_ASSERT_IF(rangeEndSeconds == INT64_MIN, rangeStartSeconds == INT64_MIN);
     JS_ASSERT_IF(rangeStartSeconds != INT64_MIN,
                  rangeStartSeconds >= 0 && rangeEndSeconds >= 0);
     JS_ASSERT_IF(rangeStartSeconds != INT64_MIN,
                  rangeStartSeconds <= MAX_UNIX_TIMET && rangeEndSeconds <= MAX_UNIX_TIMET);
-
-#ifdef JS_METER_DST_OFFSET_CACHING
-    JS_ASSERT(totalCalculations ==
-              hit +
-              missIncreasing + missDecreasing +
-              missIncreasingOffsetChangeExpand + missIncreasingOffsetChangeUpper +
-              missDecreasingOffsetChangeExpand + missDecreasingOffsetChangeLower +
-              missLargeIncrease + missLargeDecrease);
-#endif
 }
-
-#ifdef JS_METER_DST_OFFSET_CACHING
-void
-DSTOffsetCache::dumpStats()
-{
-    if (!getenv("JS_METER_DST_OFFSET_CACHING"))
-        return;
-    FILE *fp = fopen("/tmp/dst-offset-cache.stats", "a");
-    if (!fp)
-        return;
-    typedef unsigned long UL;
-    fprintf(fp,
-            "hit:\n"
-            "  in range: %lu\n"
-            "misses:\n"
-            "  increase range end:                 %lu\n"
-            "  decrease range start:               %lu\n"
-            "  increase, offset change, expand:    %lu\n"
-            "  increase, offset change, new range: %lu\n"
-            "  decrease, offset change, expand:    %lu\n"
-            "  decrease, offset change, new range: %lu\n"
-            "  large increase:                     %lu\n"
-            "  large decrease:                     %lu\n"
-            "total: %lu\n\n",
-            UL(hit),
-            UL(missIncreasing), UL(missDecreasing),
-            UL(missIncreasingOffsetChangeExpand), UL(missIncreasingOffsetChangeUpper),
-            UL(missDecreasingOffsetChangeExpand), UL(missDecreasingOffsetChangeLower),
-            UL(missLargeIncrease), UL(missLargeDecrease),
-            UL(totalCalculations));
-    fclose(fp);
-}
-#endif
--- a/js/src/prmjtime.h
+++ b/js/src/prmjtime.h
@@ -96,89 +96,36 @@ struct JSContext;
  * potential win from better caching offsets the loss from extra complexity.)
  */
 class DSTOffsetCache {
   public:
     inline DSTOffsetCache();
     JSInt64 getDSTOffsetMilliseconds(int64 localTimeMilliseconds, JSContext *cx);
 
     inline void purge();
-#ifdef JS_METER_DST_OFFSET_CACHING
-    void dumpStats();
-#endif
 
   private:
     JSInt64 computeDSTOffsetMilliseconds(int64 localTimeSeconds);
 
     JSInt64 offsetMilliseconds;
     JSInt64 rangeStartSeconds, rangeEndSeconds;
 
     JSInt64 oldOffsetMilliseconds;
     JSInt64 oldRangeStartSeconds, oldRangeEndSeconds;
 
-#ifdef JS_METER_DST_OFFSET_CACHING
-    size_t totalCalculations;
-    size_t hit;
-    size_t missIncreasing;
-    size_t missDecreasing;
-    size_t missIncreasingOffsetChangeUpper;
-    size_t missIncreasingOffsetChangeExpand;
-    size_t missLargeIncrease;
-    size_t missDecreasingOffsetChangeLower;
-    size_t missDecreasingOffsetChangeExpand;
-    size_t missLargeDecrease;
-#endif
-
     static const JSInt64 MAX_UNIX_TIMET = 2145859200; /* time_t 12/31/2037 */
     static const JSInt64 MILLISECONDS_PER_SECOND = 1000;
     static const JSInt64 SECONDS_PER_MINUTE = 60;
     static const JSInt64 SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
     static const JSInt64 SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR;
 
     static const JSInt64 RANGE_EXPANSION_AMOUNT = 30 * SECONDS_PER_DAY;
 
   private:
     void sanityCheck();
-
-#ifdef JS_METER_DST_OFFSET_CACHING
-#define NOTE_GENERIC(member) this->member++
-#else
-#define NOTE_GENERIC(member) ((void)0)
-#endif
-    void noteOffsetCalculation() {
-        NOTE_GENERIC(totalCalculations);
-    }
-    void noteCacheHit() {
-        NOTE_GENERIC(hit);
-    }
-    void noteCacheMissIncrease() {
-        NOTE_GENERIC(missIncreasing);
-    }
-    void noteCacheMissDecrease() {
-        NOTE_GENERIC(missDecreasing);
-    }
-    void noteCacheMissIncreasingOffsetChangeUpper() {
-        NOTE_GENERIC(missIncreasingOffsetChangeUpper);
-    }
-    void noteCacheMissIncreasingOffsetChangeExpand() {
-        NOTE_GENERIC(missIncreasingOffsetChangeExpand);
-    }
-    void noteCacheMissLargeIncrease() {
-        NOTE_GENERIC(missLargeIncrease);
-    }
-    void noteCacheMissDecreasingOffsetChangeLower() {
-        NOTE_GENERIC(missDecreasingOffsetChangeLower);
-    }
-    void noteCacheMissDecreasingOffsetChangeExpand() {
-        NOTE_GENERIC(missDecreasingOffsetChangeExpand);
-    }
-    void noteCacheMissLargeDecrease() {
-        NOTE_GENERIC(missLargeDecrease);
-    }
-#undef NOTE_GENERIC
 };
 
 JS_BEGIN_EXTERN_C
 
 typedef struct PRMJTime       PRMJTime;
 
 /*
  * Broken down form of 64 bit time value.
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1513,26 +1513,16 @@ GC(JSContext *cx, uintN argc, jsval *vp)
 #else
                 0
 #endif
                 );
     *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));
     return true;
 }
 
-#ifdef JS_GCMETER
-static JSBool
-GCStats(JSContext *cx, uintN argc, jsval *vp)
-{
-    js_DumpGCStats(cx->runtime, stdout);
-    *vp = JSVAL_VOID;
-    return true;
-}
-#endif
-
 static JSBool
 GCParameter(JSContext *cx, uintN argc, jsval *vp)
 {
     static const struct {
         const char      *name;
         JSGCParamKey    param;
     } paramMap[] = {
         {"maxBytes",            JSGC_MAX_BYTES },
@@ -2603,68 +2593,16 @@ DisassWithSrc(JSContext *cx, uintN argc,
         JS_ARENA_RELEASE(&cx->tempPool, mark);
         fclose(file);
     }
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return ok;
 #undef LINE_BUF_LEN
 }
 
-static JSBool
-Tracing(JSContext *cx, uintN argc, jsval *vp)
-{
-    FILE *file;
-
-    if (argc == 0) {
-        *vp = BOOLEAN_TO_JSVAL(cx->logfp != 0);
-        return JS_TRUE;
-    }
-
-    jsval *argv = JS_ARGV(cx, vp);
-    switch (JS_TypeOfValue(cx, argv[0])) {
-      case JSTYPE_NUMBER:
-      case JSTYPE_BOOLEAN: {
-        JSBool bval;
-        JS_ValueToBoolean(cx, argv[0], &bval);
-        file = bval ? stderr : NULL;
-        break;
-      }
-      case JSTYPE_STRING: {
-        JSAutoByteString name(cx, JSVAL_TO_STRING(argv[0]));
-        if (!name)
-            return JS_FALSE;
-        file = fopen(name.ptr(), "w");
-        if (!file) {
-            JS_ReportError(cx, "tracing: couldn't open output file %s: %s",
-                           name.ptr(), strerror(errno));
-            return JS_FALSE;
-        }
-        break;
-      }
-      default:
-          goto bad_argument;
-    }
-    if (cx->logfp && cx->logfp != stderr)
-        fclose((FILE *)cx->logfp);
-    cx->logfp = file;
-    cx->logPrevPc = NULL;
-    JS_SET_RVAL(cx, vp, JSVAL_VOID);
-    return JS_TRUE;
-
- bad_argument:
-    JSString *str = JS_ValueToString(cx, argv[0]);
-    if (!str)
-        return JS_FALSE;
-    JSAutoByteString bytes(cx, str);
-    if (!bytes)
-        return JS_FALSE;
-    JS_ReportError(cx, "tracing: illegal argument %s", bytes.ptr());
-    return JS_FALSE;
-}
-
 static void
 DumpScope(JSContext *cx, JSObject *obj, FILE *fp)
 {
     uintN i = 0;
     for (JSScopeProperty *sprop = NULL; JS_PropertyIterator(obj, &sprop);) {
         fprintf(fp, "%3u %p ", i++, (void *) sprop);
         ((Shape *) sprop)->dump(cx, fp);
     }
@@ -2684,21 +2622,17 @@ DumpStats(JSContext *cx, uintN argc, jsv
     for (i = 0; i < argc; i++) {
         str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return JS_FALSE;
         argv[i] = STRING_TO_JSVAL(str);
         JSFlatString *flatStr = JS_FlattenString(cx, str);
         if (!flatStr)
             return JS_FALSE;
-        if (JS_FlatStringEqualsAscii(flatStr, "arena")) {
-#ifdef JS_ARENAMETER
-            JS_DumpArenaStats(stdout);
-#endif
-        } else if (JS_FlatStringEqualsAscii(flatStr, "atom")) {
+        if (JS_FlatStringEqualsAscii(flatStr, "atom")) {
             js_DumpAtoms(cx, gOutFile);
         } else if (JS_FlatStringEqualsAscii(flatStr, "global")) {
             DumpScope(cx, cx->globalObject, stdout);
         } else {
             if (!JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
                 return JS_FALSE;
             JSObject *obj;
             if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
@@ -4878,19 +4812,16 @@ static JSFunctionSpec shell_functions[] 
     JS_FN("print",          Print,          0,0),
     JS_FN("putstr",         PutStr,         0,0),
     JS_FN("dateNow",        Now,            0,0),
     JS_FN("help",           Help,           0,0),
     JS_FN("quit",           Quit,           0,0),
     JS_FN("assertEq",       AssertEq,       2,0),
     JS_FN("assertJit",      AssertJit,      0,0),
     JS_FN("gc",             ::GC,           0,0),
-#ifdef JS_GCMETER
-    JS_FN("gcstats",        GCStats,        0,0),
-#endif
     JS_FN("gcparam",        GCParameter,    2,0),
     JS_FN("countHeap",      CountHeap,      0,0),
     JS_FN("makeFinalizeObserver", MakeFinalizeObserver, 0,0),
     JS_FN("finalizeCount",  FinalizeCount, 0,0),
 #ifdef JS_GC_ZEAL
     JS_FN("gczeal",         GCZeal,         2,0),
     JS_FN("schedulegc",     ScheduleGC,     1,0),
 #endif
@@ -4908,17 +4839,16 @@ static JSFunctionSpec shell_functions[] 
 #ifdef DEBUG
     JS_FN("disassemble",    DisassembleToString, 1,0),
     JS_FN("dis",            Disassemble,    1,0),
     JS_FN("disfile",        DisassFile,     1,0),
     JS_FN("dissrc",         DisassWithSrc,  1,0),
     JS_FN("dumpHeap",       DumpHeap,       0,0),
     JS_FN("dumpObject",     DumpObject,     1,0),
     JS_FN("notes",          Notes,          1,0),
-    JS_FN("tracing",        Tracing,        0,0),
     JS_FN("stats",          DumpStats,      1,0),
 #endif
     JS_FN("dumpStack",      DumpStack,      1,0),
 #ifdef TEST_CVTARGS
     JS_FN("cvtargs",        ConvertArgs,    0,0),
 #endif
     JS_FN("build",          BuildDate,      0,0),
     JS_FN("clear",          Clear,          0,0),
@@ -4994,19 +4924,16 @@ static const char *const shell_help_mess
 "help([name ...])         Display usage and help messages",
 "quit()                   Quit the shell",
 "assertEq(actual, expected[, msg])\n"
 "  Throw if the first two arguments are not the same (both +0 or both -0,\n"
 "  both NaN, or non-zero and ===)",
 "assertJit()              Throw if the calling function failed to JIT",
 "gc([obj])                Run the garbage collector\n"
 "                         When obj is given, GC only the compartment it's in",
-#ifdef JS_GCMETER
-"gcstats()                Print garbage collector statistics",
-#endif
 "gcparam(name, value)\n"
 "  Wrapper for JS_SetGCParameter. The name must be either 'maxBytes' or\n"
 "  'maxMallocBytes' and the value must be convertable to a positive uint32",
 "countHeap([start[, kind]])\n"
 "  Count the number of live GC things in the heap or things reachable from\n"
 "  start when it is given and is not null. kind is either 'all' (default) to\n"
 "  count all things or one of 'object', 'double', 'string', 'function',\n"
 "  'qname', 'namespace', 'xml' to count only things of that kind",
@@ -5042,18 +4969,16 @@ static const char *const shell_help_mess
 "  dis and disfile take these options as preceeding string arguments\n"
 "    \"-r\" (disassemble recursively)\n"
 "    \"-l\" (show line numbers)",
 "dissrc([fun])            Disassemble functions with source lines",
 "dumpHeap([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])\n"
 "  Interface to JS_DumpHeap with output sent to file",
 "dumpObject()             Dump an internal representation of an object",
 "notes([fun])             Show source notes for functions",
-"tracing([true|false|filename]) Turn bytecode execution tracing on/off.\n"
-"                         With filename, send to file.",
 "stats([string ...])      Dump 'arena', 'atom', 'global' stats",
 #endif
 "dumpStack()              Dump the stack as an array of callees (youngest first)",
 #ifdef TEST_CVTARGS
 "cvtargs(arg1..., arg12)  Test argument formatter",
 #endif
 "build()                  Show build date and time",
 "clear([obj])             Clear properties of object",
--- a/js/src/tests/js1_5/Regress/jstests.list
+++ b/js/src/tests/js1_5/Regress/jstests.list
@@ -91,21 +91,19 @@ script regress-275378.js
 script regress-276103.js
 script regress-278873.js
 script regress-280769-1.js
 silentfail script regress-280769-2.js
 script regress-280769-3.js
 script regress-280769-4.js
 script regress-280769-5.js
 script regress-280769.js
-script regress-281487.js
 script regress-281606.js
 script regress-281930.js
 script regress-283477.js
-script regress-286216.js
 script regress-288688.js
 script regress-289094.js
 script regress-290575.js
 script regress-290656.js
 script regress-294191.js
 script regress-294195-01.js
 script regress-294195-02.js
 script regress-294302.js
deleted file mode 100644
--- a/js/src/tests/js1_5/Regress/regress-281487.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is JavaScript Engine testing utilities.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Philipp Vogt
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 281487;
-var summary = 'JSOP_ARGDEC assertion when tracing';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-printStatus('This test requires a DEBUG build and will cause a false ' +
-            'failure to be reported by jsDriver.pl since the tracing output ' +
-            'will contain the string FAILED.');
-printStatus('This test only fails if it causes a crash.');
-
-if (typeof tracing == 'function')
-{
-  tracing(true);
-}
-
-var x;
-
-var a = function (i,j,k) {
-  x = j--;
-};
-
-a(1,2,3);
-if (typeof tracing == 'function')
-{
-  tracing(false);
-} 
-reportCompare(expect, actual, summary);
deleted file mode 100644
--- a/js/src/tests/js1_5/Regress/regress-286216.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is JavaScript Engine testing utilities.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Philipp Vogt
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 286216;
-var summary = 'Do not crash tracing a for-in loop';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-if (typeof tracking == 'function')
-{
-  tracing(true);
-}
-var mytest = 3;
-var dut = { 'x' : mytest };
-var ob = [];
-for (ob[0] in dut) {
-  printStatus(dut[ob[0]]);
-}
-
-if (typeof tracing == 'function')
-{
-  tracing(false);
-} 
-reportCompare(expect, actual, summary);
--- a/js/src/vm/String-inl.h
+++ b/js/src/vm/String-inl.h
@@ -81,29 +81,16 @@ JSDependentString::new_(JSContext *cx, J
     JS_ASSERT(base->isFlat());
     JS_ASSERT(chars >= base->chars() && chars < base->chars() + base->length());
     JS_ASSERT(length <= base->length() - (chars - base->chars()));
 
     JSDependentString *str = (JSDependentString *)js_NewGCString(cx);
     if (!str)
         return NULL;
     str->init(base, chars, length);
-#ifdef DEBUG
-    JSRuntime *rt = cx->runtime;
-    JS_RUNTIME_METER(rt, liveDependentStrings);
-    JS_RUNTIME_METER(rt, totalDependentStrings);
-    JS_RUNTIME_METER(rt, liveStrings);
-    JS_RUNTIME_METER(rt, totalStrings);
-    JS_LOCK_RUNTIME_VOID(rt,
-        (rt->strdepLengthSum += (double)length,
-         rt->strdepLengthSquaredSum += (double)length * (double)length));
-    JS_LOCK_RUNTIME_VOID(rt,
-        (rt->lengthSum += (double)length,
-         rt->lengthSquaredSum += (double)length * (double)length));
-#endif
     return str;
 }
 
 JS_ALWAYS_INLINE void
 JSFixedString::init(const jschar *chars, size_t length)
 {
     d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
     d.u1.chars = chars;
@@ -114,25 +101,16 @@ JSFixedString::new_(JSContext *cx, const
 {
     JS_ASSERT(length <= MAX_LENGTH);
     JS_ASSERT(chars[length] == jschar(0));
 
     JSFixedString *str = (JSFixedString *)js_NewGCString(cx);
     if (!str)
         return NULL;
     str->init(chars, length);
-
-#ifdef DEBUG
-    JSRuntime *rt = cx->runtime;
-    JS_RUNTIME_METER(rt, liveStrings);
-    JS_RUNTIME_METER(rt, totalStrings);
-    JS_LOCK_RUNTIME_VOID(rt,
-        (rt->lengthSum += (double)length,
-         rt->lengthSquaredSum += (double)length * (double)length));
-#endif
     return str;
 }
 
 JS_ALWAYS_INLINE JSAtom *
 JSFixedString::morphAtomizedStringIntoAtom()
 {
     JS_ASSERT((d.lengthAndFlags & FLAGS_MASK) == JS_BIT(2));
     JS_STATIC_ASSERT(NON_STATIC_ATOM == JS_BIT(3));
@@ -296,26 +274,23 @@ JSAtom::lookupStatic(const jschar *chars
     }
 
     return NULL;
 }
 
 JS_ALWAYS_INLINE void
 JSString::finalize(JSContext *cx)
 {
+    /* Statics are not GC-things and shorts are in a different arena. */
     JS_ASSERT(!isStaticAtom() && !isShort());
 
-    JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
-
-    if (isDependent())
-        JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
-    else if (isFlat())
+    if (isFlat())
         asFlat().finalize(cx->runtime);
     else
-        JS_ASSERT(isRope());
+        JS_ASSERT(isDependent() || isRope());
 }
 
 inline void
 JSFlatString::finalize(JSRuntime *rt)
 {
     JS_ASSERT(!isShort());
 
     /*
@@ -325,33 +300,31 @@ JSFlatString::finalize(JSRuntime *rt)
     if (chars() != d.inlineStorage)
         rt->free_(const_cast<jschar *>(chars()));
 }
 
 inline void
 JSShortString::finalize(JSContext *cx)
 {
     JS_ASSERT(isShort());
-    JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
 }
 
 inline void
 JSAtom::finalize(JSRuntime *rt)
 {
     JS_ASSERT(isAtom());
     if (arenaHeader()->getThingKind() == js::gc::FINALIZE_STRING)
         asFlat().finalize(rt);
     else
         JS_ASSERT(arenaHeader()->getThingKind() == js::gc::FINALIZE_SHORT_STRING);
 }
 
 inline void
 JSExternalString::finalize(JSContext *cx)
 {
-    JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
     if (JSStringFinalizeOp finalizer = str_finalizers[externalType()])
         finalizer(cx, this);
 }
 
 inline void
 JSExternalString::finalize()
 {
     JSStringFinalizeOp finalizer = str_finalizers[externalType()];
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -307,23 +307,14 @@ JSDependentString::undepend(JSContext *c
         return NULL;
 
     PodCopy(s, chars(), n);
     s[n] = 0;
 
     d.lengthAndFlags = buildLengthAndFlags(n, FIXED_FLAGS);
     d.u1.chars = s;
 
-#ifdef DEBUG
-    JSRuntime *rt = cx->runtime;
-    JS_RUNTIME_UNMETER(rt, liveDependentStrings);
-    JS_RUNTIME_UNMETER(rt, totalDependentStrings);
-    JS_LOCK_RUNTIME_VOID(rt,
-        (rt->strdepLengthSum -= (double)n,
-         rt->strdepLengthSquaredSum -= (double)n * (double)n));
-#endif
-
     return &this->asFixed();
 }
 
 JSStringFinalizeOp JSExternalString::str_finalizers[JSExternalString::TYPE_LIMIT] = {
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };