Bug 1037886 - Report Latin1 and TwoByte strings separately in about:memory. r=njn
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 16 Jul 2014 19:11:50 +0200
changeset 216326 beb84b882a689ed0fc07800afdcf3029f063b913
parent 216325 cd712c340dd7b1281860a368345d6b253258ef74
child 216327 f0d2710d4ea58fd8651c5317fcffb821eb1d4f61
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1037886
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1037886 - Report Latin1 and TwoByte strings separately in about:memory. r=njn
js/public/MemoryMetrics.h
js/src/vm/MemoryMetrics.cpp
js/xpconnect/src/XPCJSRuntime.cpp
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -207,18 +207,20 @@ struct GCSizes
 // This class holds information about the memory taken up by identical copies of
 // a particular string.  Multiple JSStrings may have their sizes aggregated
 // together into one StringInfo object.  Note that two strings with identical
 // chars will not be aggregated together if one is a short string and the other
 // is not.
 struct StringInfo
 {
 #define FOR_EACH_SIZE(macro) \
-    macro(Strings, IsLiveGCThing,  gcHeap) \
-    macro(Strings, NotLiveGCThing, mallocHeap) \
+    macro(Strings, IsLiveGCThing,  gcHeapLatin1) \
+    macro(Strings, IsLiveGCThing,  gcHeapTwoByte) \
+    macro(Strings, NotLiveGCThing, mallocHeapLatin1) \
+    macro(Strings, NotLiveGCThing, mallocHeapTwoByte)
 
     StringInfo()
       : FOR_EACH_SIZE(ZERO_SIZE)
         numCopies(0)
     {}
 
     void add(const StringInfo &other) {
         FOR_EACH_SIZE(ADD_OTHER_SIZE);
--- a/js/src/vm/MemoryMetrics.cpp
+++ b/js/src/vm/MemoryMetrics.cpp
@@ -375,18 +375,23 @@ StatsCellCallback(JSRuntime *rt, void *d
         }
         break;
       }
 
       case JSTRACE_STRING: {
         JSString *str = static_cast<JSString *>(thing);
 
         JS::StringInfo info;
-        info.gcHeap = thingSize;
-        info.mallocHeap = str->sizeOfExcludingThis(rtStats->mallocSizeOf_);
+        if (str->hasLatin1Chars()) {
+            info.gcHeapLatin1 = thingSize;
+            info.mallocHeapLatin1 = str->sizeOfExcludingThis(rtStats->mallocSizeOf_);
+        } else {
+            info.gcHeapTwoByte = thingSize;
+            info.mallocHeapTwoByte = str->sizeOfExcludingThis(rtStats->mallocSizeOf_);
+        }
         info.numCopies = 1;
 
         zStats->stringInfo.add(info);
 
         // The primary use case for anonymization is automated crash submission
         // (to help detect OOM crashes). In that case, we don't want to pay the
         // memory cost required to do notable string detection.
         if (granularity == FineGrained && !closure->anonymize) {
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1910,62 +1910,88 @@ ReportZoneStats(const JS::ZoneStats &zSt
         // "string(length=".  If we report these as notable, then we'll create
         // even more notable strings the next time we open about:memory (unless
         // there's a GC in the meantime), and so on ad infinitum.
         //
         // To avoid cluttering up about:memory like this, we stick notable
         // strings which contain "string(length=" into their own bucket.
 #       define STRING_LENGTH "string(length="
         if (FindInReadable(NS_LITERAL_CSTRING(STRING_LENGTH), notableString)) {
-            stringsNotableAboutMemoryGCHeap += info.gcHeap;
-            stringsNotableAboutMemoryMallocHeap += info.mallocHeap;
+            stringsNotableAboutMemoryGCHeap += info.gcHeapLatin1;
+            stringsNotableAboutMemoryGCHeap += info.gcHeapTwoByte;
+            stringsNotableAboutMemoryMallocHeap += info.mallocHeapLatin1;
+            stringsNotableAboutMemoryMallocHeap += info.mallocHeapTwoByte;
             continue;
         }
 
         // Escape / to \ before we put notableString into the memory reporter
         // path, because we don't want any forward slashes in the string to
         // count as path separators.
         nsCString escapedString(notableString);
         escapedString.ReplaceSubstring("/", "\\");
 
         bool truncated = notableString.Length() < info.length;
 
         nsCString path = pathPrefix +
             nsPrintfCString("strings/" STRING_LENGTH "%d, copies=%d, \"%s\"%s)/",
                             info.length, info.numCopies, escapedString.get(),
                             truncated ? " (truncated)" : "");
 
-        if (info.gcHeap > 0) {
-            REPORT_GC_BYTES(path + NS_LITERAL_CSTRING("gc-heap"),
-                info.gcHeap,
-                "Strings. " MAYBE_INLINE);
+        if (info.gcHeapLatin1 > 0) {
+            REPORT_GC_BYTES(path + NS_LITERAL_CSTRING("gc-heap/latin1"),
+                info.gcHeapLatin1,
+                "Latin1 strings. " MAYBE_INLINE);
+        }
+
+        if (info.gcHeapTwoByte > 0) {
+            REPORT_GC_BYTES(path + NS_LITERAL_CSTRING("gc-heap/two-byte"),
+                info.gcHeapTwoByte,
+                "TwoByte strings. " MAYBE_INLINE);
         }
 
-        if (info.mallocHeap > 0) {
-            REPORT_BYTES(path + NS_LITERAL_CSTRING("malloc-heap"),
-                KIND_HEAP, info.mallocHeap,
-                "Non-inline string characters. " MAYBE_OVERALLOCATED);
+        if (info.mallocHeapLatin1 > 0) {
+            REPORT_BYTES(path + NS_LITERAL_CSTRING("malloc-heap/latin1"),
+                KIND_HEAP, info.mallocHeapLatin1,
+                "Non-inline Latin1 string characters. " MAYBE_OVERALLOCATED);
+        }
+
+        if (info.mallocHeapTwoByte > 0) {
+            REPORT_BYTES(path + NS_LITERAL_CSTRING("malloc-heap/two-byte"),
+                KIND_HEAP, info.mallocHeapTwoByte,
+                "Non-inline TwoByte string characters. " MAYBE_OVERALLOCATED);
         }
     }
 
     nsCString nonNotablePath = pathPrefix;
     nonNotablePath += (zStats.isTotals || anonymize)
                     ? NS_LITERAL_CSTRING("strings/")
                     : NS_LITERAL_CSTRING("strings/string(<non-notable strings>)/");
 
-    if (zStats.stringInfo.gcHeap > 0) {
-        REPORT_GC_BYTES(nonNotablePath + NS_LITERAL_CSTRING("gc-heap"),
-            zStats.stringInfo.gcHeap,
-            "Strings. " MAYBE_INLINE);
+    if (zStats.stringInfo.gcHeapLatin1 > 0) {
+        REPORT_GC_BYTES(nonNotablePath + NS_LITERAL_CSTRING("gc-heap/latin1"),
+            zStats.stringInfo.gcHeapLatin1,
+            "Latin1 strings. " MAYBE_INLINE);
+    }
+
+    if (zStats.stringInfo.gcHeapTwoByte > 0) {
+        REPORT_GC_BYTES(nonNotablePath + NS_LITERAL_CSTRING("gc-heap/two-byte"),
+            zStats.stringInfo.gcHeapTwoByte,
+            "TwoByte strings. " MAYBE_INLINE);
     }
 
-    if (zStats.stringInfo.mallocHeap > 0) {
-        REPORT_BYTES(nonNotablePath + NS_LITERAL_CSTRING("malloc-heap"),
-            KIND_HEAP, zStats.stringInfo.mallocHeap,
-            "Non-inline string characters. " MAYBE_OVERALLOCATED);
+    if (zStats.stringInfo.mallocHeapLatin1 > 0) {
+        REPORT_BYTES(nonNotablePath + NS_LITERAL_CSTRING("malloc-heap/latin1"),
+            KIND_HEAP, zStats.stringInfo.mallocHeapLatin1,
+            "Non-inline Latin1 string characters. " MAYBE_OVERALLOCATED);
+    }
+
+    if (zStats.stringInfo.mallocHeapTwoByte > 0) {
+        REPORT_BYTES(nonNotablePath + NS_LITERAL_CSTRING("malloc-heap/two-byte"),
+            KIND_HEAP, zStats.stringInfo.mallocHeapTwoByte,
+            "Non-inline TwoByte string characters. " MAYBE_OVERALLOCATED);
     }
 
     if (stringsNotableAboutMemoryGCHeap > 0) {
         MOZ_ASSERT(!zStats.isTotals);
         REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/string(<about-memory>)/gc-heap"),
             stringsNotableAboutMemoryGCHeap,
             "Strings that contain the characters '" STRING_LENGTH "', which "
             "are probably from about:memory itself." MAYBE_INLINE