Bug 755581 (part 4) - Add "math-cache", "script-filenames" and "compartment-objects" reporters. r=luke.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 15 May 2012 19:30:28 -0700
changeset 98248 bf84a728f4ed503eb0b8f0fb64b6d66c1a2aaf6a
parent 98247 2eba6266c52768a9ed7d33bb8c063c2a7e25aaa3
child 98249 747124aac893ffeac20d6256c487d96bf030b0eb
push idunknown
push userunknown
push dateunknown
reviewersluke
bugs755581
milestone15.0a1
Bug 755581 (part 4) - Add "math-cache", "script-filenames" and "compartment-objects" reporters. r=luke.
js/public/MemoryMetrics.h
js/src/jscntxt.cpp
js/src/jsmath.cpp
js/src/jsmath.h
js/xpconnect/src/XPCJSRuntime.cpp
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -74,28 +74,39 @@ struct RuntimeSizes
       , contexts(0)
       , dtoa(0)
       , temporary(0)
       , mjitCode(0)
       , regexpCode(0)
       , unusedCodeMemory(0)
       , stackCommitted(0)
       , gcMarker(0)
+      , mathCache(0)
+      , scriptFilenames(0)
+      , compartmentObjects(0)
     {}
 
     size_t object;
     size_t atomsTable;
     size_t contexts;
     size_t dtoa;
     size_t temporary;
     size_t mjitCode;
     size_t regexpCode;
     size_t unusedCodeMemory;
     size_t stackCommitted;
     size_t gcMarker;
+    size_t mathCache;
+    size_t scriptFilenames;
+
+    // This is the exception to the "RuntimeSizes doesn't measure things within
+    // compartments" rule.  We combine the sizes of all the JSCompartment
+    // objects into a single measurement because each one is fairly small, and
+    // they're all the same size.
+    size_t compartmentObjects;
 };
 
 struct CompartmentStats
 {
     CompartmentStats() {
         memset(this, 0, sizeof(*this));
     }
 
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -89,16 +89,29 @@
 #include "jsatominlines.h"
 #include "jscntxtinlines.h"
 #include "jscompartment.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
+struct CallbackData
+{
+    CallbackData(JSMallocSizeOfFun f) : mallocSizeOf(f), n(0) {}
+    JSMallocSizeOfFun mallocSizeOf;
+    size_t n;
+};
+
+void CompartmentCallback(JSRuntime *rt, void *vdata, JSCompartment *compartment)
+{
+    CallbackData *data = (CallbackData *) vdata;
+    data->n += data->mallocSizeOf(compartment);
+}
+
 void
 JSRuntime::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, RuntimeSizes *runtime)
 {
     runtime->object = mallocSizeOf(this);
     
     runtime->atomsTable = atomState.atoms.sizeOfExcludingThis(mallocSizeOf);
     
     runtime->contexts = 0;
@@ -113,16 +126,27 @@ JSRuntime::sizeOfIncludingThis(JSMallocS
         execAlloc_->sizeOfCode(&runtime->mjitCode, &runtime->regexpCode,
                                &runtime->unusedCodeMemory);
     else
         runtime->mjitCode = runtime->regexpCode = runtime->unusedCodeMemory = 0;
 
     runtime->stackCommitted = stackSpace.sizeOfCommitted();
 
     runtime->gcMarker = gcMarker.sizeOfExcludingThis(mallocSizeOf);
+
+    runtime->mathCache = mathCache_ ? mathCache_->sizeOfIncludingThis(mallocSizeOf) : 0;
+
+    runtime->scriptFilenames = scriptFilenameTable.sizeOfExcludingThis(mallocSizeOf);
+    for (ScriptFilenameTable::Range r = scriptFilenameTable.all(); !r.empty(); r.popFront())
+        runtime->scriptFilenames += mallocSizeOf(r.front());
+
+    runtime->compartmentObjects = 0;
+    CallbackData data(mallocSizeOf);
+    JS_IterateCompartments(this, &data, CompartmentCallback);
+    runtime->compartmentObjects = data.n;
 }
 
 size_t
 JSRuntime::sizeOfExplicitNonHeap()
 {
     if (!execAlloc_)
         return 0; 
     
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -102,16 +102,22 @@ MathCache::MathCache() {
     memset(table, 0, sizeof(table));
 
     /* See comments in lookup(). */
     JS_ASSERT(MOZ_DOUBLE_IS_NEGATIVE_ZERO(-0.0));
     JS_ASSERT(!MOZ_DOUBLE_IS_NEGATIVE_ZERO(+0.0));
     JS_ASSERT(hash(-0.0) != hash(+0.0));
 }
 
+size_t
+MathCache::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf)
+{
+    return mallocSizeOf(this);
+}
+
 Class js::MathClass = {
     js_Math_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
     JS_PropertyStub,         /* addProperty */
     JS_PropertyStub,         /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -69,16 +69,18 @@ class MathCache
         unsigned index = hash(x);
         Entry &e = table[index];
         if (e.in == x && e.f == f)
             return e.out;
         e.in = x;
         e.f = f;
         return (e.out = f(x));
     }
+
+    size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf);
 };
 
 } /* namespace js */
 
 /*
  * JS math functions.
  */
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1574,16 +1574,30 @@ ReportJSRuntimeExplicitTreeStats(const J
                  "Memory used for the JS call stack.  This is the committed "
                  "portion of the stack; the uncommitted portion is not "
                  "measured because it hardly costs anything.");
 
     REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/gc-marker"),
                  nsIMemoryReporter::KIND_HEAP, rtStats.runtime.gcMarker,
                  "Memory used for the GC mark stack and gray roots.");
 
+    REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/math-cache"),
+                 nsIMemoryReporter::KIND_HEAP, rtStats.runtime.mathCache,
+                 "Memory used for the math cache.");
+
+    REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/script-filenames"),
+                 nsIMemoryReporter::KIND_HEAP, rtStats.runtime.scriptFilenames,
+                 "Memory used for the table holding script filenames.");
+
+    REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/compartment-objects"),
+                 nsIMemoryReporter::KIND_HEAP, rtStats.runtime.compartmentObjects,
+                 "Memory used for JSCompartment objects.  These are fairly "
+                 "small and all the same size, so they're not worth reporting "
+                 "on a per-compartment basis.");
+
     REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap-chunk-dirty-unused"),
                     rtStats.gcHeapChunkDirtyUnused,
                     "Memory on the garbage-collected JavaScript heap, within "
                     "chunks with at least one allocated GC thing, that could "
                     "be holding useful data but currently isn't.  Memory here "
                     "is mutually exclusive with memory reported under "
                     "'explicit/js/gc-heap-decommitted'.");