diff --git a/js/public/MemoryMetrics.h b/js/public/MemoryMetrics.h index 0f6f5312899..ed61e1c4277 100644 --- a/js/public/MemoryMetrics.h +++ b/js/public/MemoryMetrics.h @@ -11,14 +11,12 @@ // change in the future. Depend on them at your own risk. #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include #include "jsalloc.h" #include "jspubtd.h" -#include "js/HashTable.h" #include "js/Utility.h" #include "js/Vector.h" @@ -32,61 +30,9 @@ namespace js { // MemoryReportingSundriesThreshold() bytes. // // We need to define this value here, rather than in the code which actually -// generates the memory reports, because NotableStringInfo uses this value. +// generates the memory reports, because HugeStringInfo uses this value. JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold(); -struct StringHashPolicy -{ - typedef JSString *Lookup; - static HashNumber hash(const Lookup &l); - static bool match(const JSString *const &k, const Lookup &l); -}; - -struct ZoneStatsPod -{ - ZoneStatsPod() { - mozilla::PodZero(this); - } - - void add(const ZoneStatsPod &other) { - #define ADD(x) this->x += other.x - - ADD(gcHeapArenaAdmin); - ADD(gcHeapUnusedGcThings); - - ADD(gcHeapStringsNormal); - ADD(gcHeapStringsShort); - ADD(gcHeapLazyScripts); - ADD(gcHeapTypeObjects); - ADD(gcHeapIonCodes); - - ADD(stringCharsNonNotable); - ADD(lazyScripts); - ADD(typeObjects); - ADD(typePool); - - #undef ADD - } - - // This field can be used by embedders. - void *extra; - - size_t gcHeapArenaAdmin; - size_t gcHeapUnusedGcThings; - - size_t gcHeapStringsNormal; - size_t gcHeapStringsShort; - - size_t gcHeapLazyScripts; - size_t gcHeapTypeObjects; - size_t gcHeapIonCodes; - - size_t stringCharsNonNotable; - size_t lazyScripts; - size_t typeObjects; - size_t typePool; -}; - } // namespace js namespace JS { @@ -157,86 +103,26 @@ struct CodeSizes CodeSizes() { memset(this, 0, sizeof(CodeSizes)); } }; - -// 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. -struct StringInfo +// Holds data about a huge string (one which uses more HugeStringInfo::MinSize +// bytes of memory), so we can report it individually. +struct HugeStringInfo { - StringInfo() - : length(0), numCopies(0), sizeOfShortStringGCThings(0), - sizeOfNormalStringGCThings(0), sizeOfAllStringChars(0) - {} - - StringInfo(size_t length, size_t shorts, size_t normals, size_t chars) - : length(length), - numCopies(1), - sizeOfShortStringGCThings(shorts), - sizeOfNormalStringGCThings(normals), - sizeOfAllStringChars(chars) - {} - - void add(size_t shorts, size_t normals, size_t chars) { - sizeOfShortStringGCThings += shorts; - sizeOfNormalStringGCThings += normals; - sizeOfAllStringChars += chars; - numCopies++; - } - - void add(const StringInfo& info) { - MOZ_ASSERT(length == info.length); - - sizeOfShortStringGCThings += info.sizeOfShortStringGCThings; - sizeOfNormalStringGCThings += info.sizeOfNormalStringGCThings; - sizeOfAllStringChars += info.sizeOfAllStringChars; - numCopies += info.numCopies; - } - - size_t totalSizeOf() const { - return sizeOfShortStringGCThings + sizeOfNormalStringGCThings + sizeOfAllStringChars; - } - - size_t totalGCThingSizeOf() const { - return sizeOfShortStringGCThings + sizeOfNormalStringGCThings; - } - - // The string's length, excluding the null-terminator. - size_t length; - - // How many copies of the string have we seen? - size_t numCopies; - - // These are all totals across all copies of the string we've seen. - size_t sizeOfShortStringGCThings; - size_t sizeOfNormalStringGCThings; - size_t sizeOfAllStringChars; -}; - -// Holds data about a notable string (one which uses more than -// NotableStringInfo::notableSize() bytes of memory), so we can report it -// individually. -// -// Essentially the only difference between this class and StringInfo is that -// NotableStringInfo holds a copy of the string's chars. -struct NotableStringInfo : public StringInfo -{ - NotableStringInfo(); - NotableStringInfo(JSString *str, const StringInfo &info); - NotableStringInfo(const NotableStringInfo& info); - NotableStringInfo(mozilla::MoveRef info); - NotableStringInfo &operator=(mozilla::MoveRef info); - ~NotableStringInfo(); + HugeStringInfo() : length(0), size(0) { memset(&buffer, 0, sizeof(buffer)); } // A string needs to take up this many bytes of storage before we consider - // it to be "notable". - static size_t notableSize() { + // it to be "huge". + static size_t MinSize() { return js::MemoryReportingSundriesThreshold(); } - // The amount of memory we requested for |buffer|; i.e. - // buffer = malloc(bufferSize). - size_t bufferSize; - char *buffer; + // A string's size in memory is not necessarily equal to twice its length + // because the allocator and the JS engine both may round up. + size_t length; + size_t size; + + // We record the first 32 chars of the escaped string here. (We escape the + // string so we can use a char[] instead of a jschar[] here. + char buffer[32]; }; // These measurements relate directly to the JSRuntime, and not to @@ -260,46 +146,84 @@ struct RuntimeSizes CodeSizes code; }; -struct ZoneStats : js::ZoneStatsPod +struct ZoneStats { - ZoneStats() { - strings.init(); - } - - ZoneStats(mozilla::MoveRef other) - : ZoneStatsPod(other), - strings(mozilla::Move(other->strings)), - notableStrings(mozilla::Move(other->notableStrings)) + ZoneStats() + : extra(NULL), + gcHeapArenaAdmin(0), + gcHeapUnusedGcThings(0), + gcHeapStringsNormal(0), + gcHeapStringsShort(0), + gcHeapLazyScripts(0), + gcHeapTypeObjects(0), + gcHeapIonCodes(0), + stringCharsNonHuge(0), + lazyScripts(0), + typeObjects(0), + typePool(0), + hugeStrings() {} - // Add other's numbers to this object's numbers. Both objects' - // notableStrings vectors must be empty at this point, because we can't - // merge them. (A NotableStringInfo contains only a prefix of the string, - // so we can't tell whether two NotableStringInfo objects correspond to the - // same string.) - void add(const ZoneStats &other) { - ZoneStatsPod::add(other); - - MOZ_ASSERT(notableStrings.empty()); - MOZ_ASSERT(other.notableStrings.empty()); - - for (StringsHashMap::Range r = other.strings.all(); !r.empty(); r.popFront()) { - StringsHashMap::AddPtr p = strings.lookupForAdd(r.front().key); - if (p) { - // We've seen this string before; add its size to our tally. - p->value.add(r.front().value); - } else { - // We haven't seen this string before; add it to the hashtable. - strings.add(p, r.front().key, r.front().value); - } - } + ZoneStats(const ZoneStats &other) + : extra(other.extra), + gcHeapArenaAdmin(other.gcHeapArenaAdmin), + gcHeapUnusedGcThings(other.gcHeapUnusedGcThings), + gcHeapStringsNormal(other.gcHeapStringsNormal), + gcHeapStringsShort(other.gcHeapStringsShort), + gcHeapLazyScripts(other.gcHeapLazyScripts), + gcHeapTypeObjects(other.gcHeapTypeObjects), + gcHeapIonCodes(other.gcHeapIonCodes), + stringCharsNonHuge(other.stringCharsNonHuge), + lazyScripts(other.lazyScripts), + typeObjects(other.typeObjects), + typePool(other.typePool), + hugeStrings() + { + hugeStrings.appendAll(other.hugeStrings); } - typedef js::HashMap - StringsHashMap; + // Add other's numbers to this object's numbers. + void add(ZoneStats &other) { + #define ADD(x) this->x += other.x - StringsHashMap strings; - js::Vector notableStrings; + ADD(gcHeapArenaAdmin); + ADD(gcHeapUnusedGcThings); + + ADD(gcHeapStringsNormal); + ADD(gcHeapStringsShort); + ADD(gcHeapLazyScripts); + ADD(gcHeapTypeObjects); + ADD(gcHeapIonCodes); + + ADD(stringCharsNonHuge); + ADD(lazyScripts); + ADD(typeObjects); + ADD(typePool); + + #undef ADD + + hugeStrings.appendAll(other.hugeStrings); + } + + // This field can be used by embedders. + void *extra; + + size_t gcHeapArenaAdmin; + size_t gcHeapUnusedGcThings; + + size_t gcHeapStringsNormal; + size_t gcHeapStringsShort; + + size_t gcHeapLazyScripts; + size_t gcHeapTypeObjects; + size_t gcHeapIonCodes; + + size_t stringCharsNonHuge; + size_t lazyScripts; + size_t typeObjects; + size_t typePool; + + js::Vector hugeStrings; // The size of all the live things in the GC heap that don't belong to any // compartment. diff --git a/js/src/jsmemorymetrics.cpp b/js/src/jsmemorymetrics.cpp index 07f76151444..bdf7c1b4832 100644 --- a/js/src/jsmemorymetrics.cpp +++ b/js/src/jsmemorymetrics.cpp @@ -19,14 +19,10 @@ #include "vm/Runtime.h" #include "vm/Shape.h" #include "vm/WrapperObject.h" -#include "vm/String.h" #include "jsobjinlines.h" using mozilla::DebugOnly; -using mozilla::Move; -using mozilla::MoveRef; -using mozilla::PodEqual; using namespace js; @@ -35,119 +31,12 @@ using JS::ObjectPrivateVisitor; using JS::ZoneStats; using JS::CompartmentStats; -namespace js { - JS_FRIEND_API(size_t) -MemoryReportingSundriesThreshold() +js::MemoryReportingSundriesThreshold() { return 8 * 1024; } -/* static */ HashNumber -StringHashPolicy::hash(const Lookup &l) -{ - const jschar *chars = l->maybeChars(); - ScopedJSFreePtr ownedChars; - if (!chars) { - if (!l->getCharsNonDestructive(/* tcx */ NULL, ownedChars)) - MOZ_CRASH("oom"); - chars = ownedChars; - } - - return mozilla::HashString(chars, l->length()); -} - -/* static */ bool -StringHashPolicy::match(const JSString *const &k, const Lookup &l) -{ - // We can't use js::EqualStrings, because that flattens our strings. - if (k->length() != l->length()) - return false; - - const jschar *c1 = k->maybeChars(); - ScopedJSFreePtr ownedChars1; - if (!c1) { - if (!k->getCharsNonDestructive(/* tcx */ NULL, ownedChars1)) - MOZ_CRASH("oom"); - c1 = ownedChars1; - } - - const jschar *c2 = l->maybeChars(); - ScopedJSFreePtr ownedChars2; - if (!c2) { - if (!l->getCharsNonDestructive(/* tcx */ NULL, ownedChars2)) - MOZ_CRASH("oom"); - c2 = ownedChars2; - } - - return PodEqual(c1, c2, k->length()); -} - -} // namespace js - -namespace JS -{ - -NotableStringInfo::NotableStringInfo() - : bufferSize(0), - buffer(0) -{} - -NotableStringInfo::NotableStringInfo(JSString *str, const StringInfo &info) - : StringInfo(info) -{ - bufferSize = Min(str->length() + 1, size_t(4096)); - buffer = js_pod_malloc(bufferSize); - if (!buffer) { - MOZ_CRASH("oom"); - } - - const jschar* chars = str->maybeChars(); - ScopedJSFreePtr ownedChars; - if (!chars) { - if (!str->getCharsNonDestructive(/* tcx */ NULL, ownedChars)) - MOZ_CRASH("oom"); - chars = ownedChars; - } - - // We might truncate |str| even if it's much shorter than 4096 chars, if - // |str| contains unicode chars. Since this is just for a memory reporter, - // we don't care. - PutEscapedString(buffer, bufferSize, chars, str->length(), /* quote */ 0); -} - -NotableStringInfo::NotableStringInfo(const NotableStringInfo& info) - : StringInfo(info), - bufferSize(info.bufferSize) -{ - buffer = js_pod_malloc(bufferSize); - if (!buffer) - MOZ_CRASH("oom"); - - strcpy(buffer, info.buffer); -} - -NotableStringInfo::NotableStringInfo(MoveRef info) - : StringInfo(info) -{ - buffer = info->buffer; - info->buffer = NULL; -} - -NotableStringInfo &NotableStringInfo::operator=(MoveRef info) -{ - this->~NotableStringInfo(); - new (this) NotableStringInfo(info); - return *this; -} - -NotableStringInfo::~NotableStringInfo() -{ - js_free(buffer); -} - -} // namespace JS - typedef HashSet, SystemAllocPolicy> SourceSet; struct IteratorClosure @@ -312,25 +201,23 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin case JSTRACE_STRING: { JSString *str = static_cast(thing); - size_t strCharsSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf_); - MOZ_ASSERT_IF(str->isShort(), strCharsSize == 0); + size_t strSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf_); - size_t shortStringThingSize = str->isShort() ? thingSize : 0; - size_t normalStringThingSize = !str->isShort() ? thingSize : 0; - - ZoneStats::StringsHashMap::AddPtr p = zStats->strings.lookupForAdd(str); - if (!p) { - JS::StringInfo info(str->length(), shortStringThingSize, - normalStringThingSize, strCharsSize); - zStats->strings.add(p, str, info); + // If we can't grow hugeStrings, let's just call this string non-huge. + // We're probably about to OOM anyway. + if (strSize >= JS::HugeStringInfo::MinSize() && zStats->hugeStrings.growBy(1)) { + zStats->gcHeapStringsNormal += thingSize; + JS::HugeStringInfo &info = zStats->hugeStrings.back(); + info.length = str->length(); + info.size = strSize; + PutEscapedString(info.buffer, sizeof(info.buffer), &str->asLinear(), 0); + } else if (str->isShort()) { + MOZ_ASSERT(strSize == 0); + zStats->gcHeapStringsShort += thingSize; } else { - p->value.add(shortStringThingSize, normalStringThingSize, strCharsSize); + zStats->gcHeapStringsNormal += thingSize; + zStats->stringCharsNonHuge += strSize; } - - zStats->gcHeapStringsShort += shortStringThingSize; - zStats->gcHeapStringsNormal += normalStringThingSize; - zStats->stringCharsNonNotable += strCharsSize; - break; } @@ -413,44 +300,6 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin zStats->gcHeapUnusedGcThings -= thingSize; } -static void -FindNotableStrings(ZoneStats &zStats) -{ - using namespace JS; - - // You should only run FindNotableStrings once per ZoneStats object - // (although it's not going to break anything if you run it more than once, - // unless you add to |strings| in the meantime). - MOZ_ASSERT(zStats.notableStrings.empty()); - - for (ZoneStats::StringsHashMap::Range r = zStats.strings.all(); !r.empty(); r.popFront()) { - - JSString *str = r.front().key; - StringInfo &info = r.front().value; - - // If this string is too small, or if we can't grow the notableStrings - // vector, skip this string. - if (info.totalSizeOf() < NotableStringInfo::notableSize() || - !zStats.notableStrings.growBy(1)) - continue; - - zStats.notableStrings.back() = Move(NotableStringInfo(str, info)); - - // We're moving this string from a non-notable to a notable bucket, so - // subtract it out of the non-notable tallies. - MOZ_ASSERT(zStats.gcHeapStringsShort >= info.sizeOfShortStringGCThings); - MOZ_ASSERT(zStats.gcHeapStringsNormal >= info.sizeOfNormalStringGCThings); - MOZ_ASSERT(zStats.stringCharsNonNotable >= info.sizeOfAllStringChars); - zStats.gcHeapStringsShort -= info.sizeOfShortStringGCThings; - zStats.gcHeapStringsNormal -= info.sizeOfNormalStringGCThings; - zStats.stringCharsNonNotable -= info.sizeOfAllStringChars; - } - - // zStats.strings holds unrooted JSString pointers, which we don't want to - // expose out into the dangerous land where we might GC. - zStats.strings.clear(); -} - JS_PUBLIC_API(bool) JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *opv) { @@ -491,14 +340,8 @@ JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisit #ifdef DEBUG totalArenaSize += zStats.gcHeapArenaAdmin + zStats.gcHeapUnusedGcThings; #endif - - // Move any strings which take up more than the sundries threshold - // (counting all of their copies together) into notableStrings. - FindNotableStrings(zStats); } - FindNotableStrings(rtStats->zTotals); - for (size_t i = 0; i < rtStats->compartmentStatsVector.length(); i++) { CompartmentStats &cStats = rtStats->compartmentStatsVector[i]; diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 08d1559f649..649eaa03125 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -4403,14 +4403,6 @@ js_OneUcs4ToUtf8Char(uint8_t *utf8Buffer, uint32_t ucs4Char) size_t js::PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, JSLinearString *str, uint32_t quote) -{ - return PutEscapedStringImpl(buffer, bufferSize, fp, str->chars(), - str->length(), quote); -} - -size_t -js::PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const jschar *chars, - size_t length, uint32_t quote) { enum { STOP, FIRST_QUOTE, LAST_QUOTE, CHARS, ESCAPE_START, ESCAPE_MORE @@ -4425,7 +4417,8 @@ js::PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const jschar else bufferSize--; - const jschar *charsEnd = chars + length; + const jschar *chars = str->chars(); + const jschar *charsEnd = chars + str->length(); size_t n = 0; state = FIRST_QUOTE; unsigned shift = 0; diff --git a/js/src/jsstr.h b/js/src/jsstr.h index f204fb58fb0..8d3e178da6d 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -320,10 +320,6 @@ namespace js { extern size_t PutEscapedStringImpl(char *buffer, size_t size, FILE *fp, JSLinearString *str, uint32_t quote); -extern size_t -PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const jschar *chars, - size_t length, uint32_t quote); - /* * Write str into buffer escaping any non-printable or non-ASCII character * using \escapes for JS string literals. @@ -343,16 +339,6 @@ PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32_t quote) return n; } -inline size_t -PutEscapedString(char *buffer, size_t bufferSize, const jschar *chars, size_t length, uint32_t quote) -{ - size_t n = PutEscapedStringImpl(buffer, bufferSize, NULL, chars, length, quote); - - /* PutEscapedStringImpl can only fail with a file. */ - JS_ASSERT(n != size_t(-1)); - return n; -} - /* * Write str into file escaping any non-printable or non-ASCII character. * If quote is not 0, it must be a single or double quote character that diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index b0aa0885f0d..66c0a9e4b2a 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -185,12 +185,7 @@ JSRope::getCharsNonDestructiveInternal(ThreadSafeContext *cx, ScopedJSFreePtrpod_malloc(n + 1); - else - s = js_pod_malloc(n + 1); - + jschar *s = cx->pod_malloc(n + 1); if (!s) return false; jschar *pos = s; diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 6218a068d4f..20ab3e48ed4 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -1537,43 +1537,21 @@ NS_MEMORY_REPORTER_IMPLEMENT(JSMainRuntimeTemporaryPeak, // The REPORT* macros do an unconditional report. The ZCREPORT* macros are for // compartments and zones; they aggregate any entries smaller than -// SUNDRIES_THRESHOLD into the "sundries/gc-heap" and "sundries/malloc-heap" -// entries for the compartment. +// SUNDRIES_THRESHOLD into "gc-heap/sundries" and "other-sundries" entries for +// the compartment. #define SUNDRIES_THRESHOLD js::MemoryReportingSundriesThreshold() #define REPORT(_path, _kind, _units, _amount, _desc) \ do { \ nsresult rv; \ - rv = cb->Callback(EmptyCString(), _path, \ - nsIMemoryReporter::_kind, \ - nsIMemoryReporter::_units, \ - _amount, \ - NS_LITERAL_CSTRING(_desc), \ - closure); \ + rv = cb->Callback(EmptyCString(), _path, _kind, _units, _amount, \ + NS_LITERAL_CSTRING(_desc), closure); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) #define REPORT_BYTES(_path, _kind, _amount, _desc) \ - REPORT(_path, _kind, UNITS_BYTES, _amount, _desc); - -// REPORT2 and REPORT_BYTES2 are just like REPORT and REPORT_BYTES, except the -// description is an nsCString, instead of a literal string. - -#define REPORT2(_path, _kind, _units, _amount, _desc) \ - do { \ - nsresult rv; \ - rv = cb->Callback(EmptyCString(), _path, \ - nsIMemoryReporter::_kind, \ - nsIMemoryReporter::_units, \ - _amount, \ - _desc, \ - closure); \ - NS_ENSURE_SUCCESS(rv, rv); \ - } while (0) - -#define REPORT_BYTES2(_path, _kind, _amount, _desc) \ - REPORT2(_path, _kind, UNITS_BYTES, _amount, _desc); + REPORT(_path, _kind, nsIMemoryReporter::UNITS_BYTES, _amount, _desc); #define REPORT_GC_BYTES(_path, _amount, _desc) \ do { \ @@ -1658,39 +1636,54 @@ ReportZoneStats(const JS::ZoneStats &zStats, const nsAutoCString& pathPrefix = extras.pathPrefix; size_t gcTotal = 0, gcHeapSundries = 0, otherSundries = 0; - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap-arena-admin"), + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/arena-admin"), zStats.gcHeapArenaAdmin, "Memory on the garbage-collected JavaScript " "heap, within arenas, that is used (a) to hold internal " "bookkeeping information, and (b) to provide padding to " "align GC things."); - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("unused-gc-things"), + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/unused-gc-things"), zStats.gcHeapUnusedGcThings, "Memory on the garbage-collected JavaScript " "heap taken by empty GC thing slots within non-empty " "arenas."); - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/gc-heap"), + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/strings/normal"), + zStats.gcHeapStringsNormal, + "Memory on the garbage-collected JavaScript " + "heap that holds normal string headers. String headers contain " + "various pieces of information about a string, but do not " + "contain (except in the case of very short strings) the " + "string characters; characters in longer strings are " + "counted under 'gc-heap/string-chars' instead."); + + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/strings/short"), + zStats.gcHeapStringsShort, + "Memory on the garbage-collected JavaScript " + "heap that holds over-sized string headers, in which " + "string characters are stored inline."); + + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/lazy-scripts"), zStats.gcHeapLazyScripts, "Memory on the garbage-collected JavaScript " "heap that represents scripts which haven't executed yet."); - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-objects/gc-heap"), + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/type-objects"), zStats.gcHeapTypeObjects, "Memory on the garbage-collected JavaScript " "heap that holds type inference information."); - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("ion-codes/gc-heap"), + ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/ion-codes"), zStats.gcHeapIonCodes, "Memory on the garbage-collected JavaScript " "heap that holds references to executable code pools " "used by the IonMonkey JIT."); - ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/malloc-heap"), + ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-script-data"), zStats.lazyScripts, "Memory holding miscellaneous additional information associated with lazy " - "scripts. This memory is allocated on the malloc heap."); + "scripts."); ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-objects"), zStats.typeObjects, @@ -1701,126 +1694,55 @@ ReportZoneStats(const JS::ZoneStats &zStats, zStats.typePool, "Memory holding contents of type sets and related data."); - size_t gcHeapStringsAboutMemory = 0; - size_t stringCharsAboutMemory = 0; + ZCREPORT_BYTES2(pathPrefix + NS_LITERAL_CSTRING("string-chars/non-huge"), + zStats.stringCharsNonHuge, nsPrintfCString( + "Memory allocated to hold characters of strings whose " + "characters take up less than than %d bytes of memory.\n\n" + "Sometimes more memory is allocated than necessary, to " + "simplify string concatenation. Each string also includes a " + "header which is stored on the compartment's JavaScript heap; " + "that header is not counted here, but in 'gc-heap/strings' " + "instead.", + JS::HugeStringInfo::MinSize())); - for (size_t i = 0; i < zStats.notableStrings.length(); i++) { - const JS::NotableStringInfo& info = zStats.notableStrings[i]; + for (size_t i = 0; i < zStats.hugeStrings.length(); i++) { + const JS::HugeStringInfo& info = zStats.hugeStrings[i]; - nsDependentCString notableString(info.buffer); + nsDependentCString hugeString(info.buffer); - // Viewing about:memory generates many notable strings which contain - // "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 "strings/notable/string(length=" into their own - // bucket. -# define STRING_LENGTH "string(length=" - if (FindInReadable(NS_LITERAL_CSTRING(STRING_LENGTH), notableString)) { - gcHeapStringsAboutMemory += info.totalGCThingSizeOf(); - stringCharsAboutMemory += info.sizeOfAllStringChars; - continue; - } - - // Escape / to \ before we put notableString into the memory reporter + // Escape / to \/ before we put hugeString 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("/", "\\"); + nsCString escapedString(hugeString); + escapedString.ReplaceSubstring("/", "\\/"); - bool truncated = notableString.Length() < info.length; - - nsCString path = pathPrefix + - nsPrintfCString("strings/notable/" STRING_LENGTH "%d, copies=%d, \"%s\"%s)/", - info.length, info.numCopies, escapedString.get(), - truncated ? " (truncated)" : ""); - - REPORT_BYTES2(path + NS_LITERAL_CSTRING("gc-heap"), - KIND_NONHEAP, - info.totalGCThingSizeOf(), - nsPrintfCString("Memory allocated to hold headers for copies of " - "the given notable string. A string is notable if all of its copies " - "together use more than %d bytes total of JS GC heap and malloc heap " - "memory.\n\n" - "These headers may contain the string data itself, if the string " - "is short enough. If so, the string won't have any memory reported " - "under 'string-chars/.", - JS::NotableStringInfo::notableSize())); - gcTotal += info.totalGCThingSizeOf(); - - if (info.sizeOfAllStringChars > 0) { - REPORT_BYTES2(path + NS_LITERAL_CSTRING("malloc-heap"), - KIND_HEAP, - info.sizeOfAllStringChars, - nsPrintfCString("Memory allocated on the malloc heap to hold " - "string data for copies of the given notable string. A string is " - "notable if all of its copies together use more than %d bytes " - "total of JS GC heap and malloc heap memory.", - JS::NotableStringInfo::notableSize())); - } - } - - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/short/gc-heap"), - zStats.gcHeapStringsShort, - "Memory on the garbage-collected JavaScript " - "heap that holds headers for strings which are short " - "enough to be stored completely within the header. That " - "is, a 'short' string uses no string-chars."); - - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/normal/gc-heap"), - zStats.gcHeapStringsNormal, - "Memory on the garbage-collected JavaScript " - "heap that holds string headers for strings which are too " - "long to fit entirely within the header. The character " - "data for such strings is counted under " - "strings/normal/malloc-heap."); - - ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/normal/malloc-heap"), - zStats.stringCharsNonNotable, - "Memory allocated to hold characters for strings which are too long " - "to fit entirely within their string headers.\n\n" - "Sometimes more memory is allocated than necessary, to " - "simplify string concatenation."); - - if (gcHeapStringsAboutMemory > 0) { - ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/notable/about-memory/gc-heap"), - gcHeapStringsAboutMemory, - "Memory allocated on the garbage-collected JavaScript " - "heap that holds headers for notable strings which " - "contain the string '" STRING_LENGTH "'. These " - "strings are likely from about:memory itself. We " - "filter them out rather than display them, because " - "displaying them would create even more strings every " - "time you refresh about:memory."); - } - - if (stringCharsAboutMemory > 0) { - ZCREPORT_BYTES(pathPrefix + - NS_LITERAL_CSTRING("strings/notable/about-memory/malloc-heap"), - stringCharsAboutMemory, - "Memory allocated to hold characters of notable strings " - "which contain the string '" STRING_LENGTH "'. These " - "strings are likely from about:memory itself. We filter " - "them out rather than display them, because displaying " - "them would create even more strings every time you " - "refresh about:memory."); + ZCREPORT_BYTES2( + pathPrefix + + nsPrintfCString("string-chars/huge/string(length=%d, \"%s...\")", + info.length, escapedString.get()), + info.size, + nsPrintfCString("Memory allocated to hold characters of " + "a length-%d string which begins \"%s\".\n\n" + "Sometimes more memory is allocated than necessary, to simplify " + "string concatenation. Each string also includes a header which is " + "stored on the compartment's JavaScript heap; that header is not " + "counted here, but in 'gc-heap/strings' instead.", + info.length, hugeString.get())); } if (gcHeapSundries > 0) { // We deliberately don't use ZCREPORT_GC_BYTES here. - REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("sundries/gc-heap"), + REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/sundries"), gcHeapSundries, - "The sum of all the 'gc-heap' measurements that are too " + "The sum of all the gc-heap measurements that are too " "small to be worth showing individually."); } if (otherSundries > 0) { // We deliberately don't use ZCREPORT_BYTES here. - REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("sundries/malloc-heap"), + REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("other-sundries"), nsIMemoryReporter::KIND_HEAP, otherSundries, - "The sum of all the 'malloc-heap' measurements that are too " + "The sum of all the non-gc-heap measurements that are too " "small to be worth showing individually."); } @@ -1828,8 +1750,6 @@ ReportZoneStats(const JS::ZoneStats &zStats, *gcTotalOut += gcTotal; return NS_OK; - -# undef STRING_LENGTH } static nsresult @@ -1864,72 +1784,72 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats, } } - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/ordinary"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/ordinary"), cStats.gcHeapObjectsOrdinary, "Memory on the garbage-collected JavaScript " "heap that holds ordinary (i.e. not otherwise distinguished " "my memory reporters) objects."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/function"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/function"), cStats.gcHeapObjectsFunction, "Memory on the garbage-collected JavaScript " "heap that holds function objects."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/dense-array"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/dense-array"), cStats.gcHeapObjectsDenseArray, "Memory on the garbage-collected JavaScript " "heap that holds dense array objects."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/slow-array"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/slow-array"), cStats.gcHeapObjectsSlowArray, "Memory on the garbage-collected JavaScript " "heap that holds slow array objects."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/cross-compartment-wrapper"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/cross-compartment-wrapper"), cStats.gcHeapObjectsCrossCompartmentWrapper, "Memory on the garbage-collected JavaScript " "heap that holds cross-compartment wrapper objects."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("scripts/gc-heap"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/scripts"), cStats.gcHeapScripts, "Memory on the garbage-collected JavaScript " "heap that holds JSScript instances. A JSScript is " "created for each user-defined function in a script. One " "is also created for the top-level code in a script."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree/global-parented"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/tree/global-parented"), cStats.gcHeapShapesTreeGlobalParented, "Memory on the garbage-collected JavaScript heap that " "holds shapes that (a) are in a property tree, and (b) " "represent an object whose parent is the global object."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree/non-global-parented"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/tree/non-global-parented"), cStats.gcHeapShapesTreeNonGlobalParented, "Memory on the garbage-collected JavaScript heap that " "holds shapes that (a) are in a property tree, and (b) " "represent an object whose parent is not the global object."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/dict"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/dict"), cStats.gcHeapShapesDict, "Memory on the garbage-collected JavaScript " "heap that holds shapes that are in dictionary mode."); - ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/base"), + ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/base"), cStats.gcHeapShapesBase, "Memory on the garbage-collected JavaScript " "heap that collates data common to many shapes."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/slots"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/slots"), cStats.objectsExtra.slots, - "Memory allocated on the malloc heap for the non-fixed object " + "Memory allocated for the non-fixed object " "slot arrays, which are used to represent object properties. " "Some objects also contain a fixed number of slots which are " "stored on the JavaScript heap; those slots " - "are not counted here, but in 'objects/gc-heap/*' instead."); + "are not counted here, but in 'gc-heap/objects' instead."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/elements/non-asm.js"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/non-asm.js"), cStats.objectsExtra.elementsNonAsmJS, - "Memory allocated on the malloc heap for non-asm.js object element arrays, " + "Memory allocated for non-asm.js object element arrays, " "which are used to represent indexed object properties."); // asm.js arrays are heap-allocated on some platforms and @@ -1937,37 +1857,35 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats, // because (a) in practice they're almost always larger than the sundries // threshold, and (b) we'd need a third category of non-heap, non-GC // sundries, which would be a pain. + #define ASM_JS_DESC "Memory allocated for object element " \ + "arrays used as asm.js array buffers." size_t asmJSHeap = cStats.objectsExtra.elementsAsmJSHeap; size_t asmJSNonHeap = cStats.objectsExtra.elementsAsmJSNonHeap; JS_ASSERT(asmJSHeap == 0 || asmJSNonHeap == 0); if (asmJSHeap > 0) { - REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/elements/asm.js"), - KIND_HEAP, asmJSHeap, - "Memory allocated on the malloc heap for object element arrays used as asm.js " - "array buffers."); + REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/asm.js"), + nsIMemoryReporter::KIND_HEAP, asmJSHeap, ASM_JS_DESC); } if (asmJSNonHeap > 0) { - REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/non-heap/elements/asm.js"), - KIND_NONHEAP, asmJSNonHeap, - "Memory allocated for object element arrays used as asm.js array buffers. " - "This memory lives outside both the malloc heap and the JS heap."); + REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/asm.js"), + nsIMemoryReporter::KIND_NONHEAP, asmJSNonHeap, ASM_JS_DESC); } - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/arguments-data"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/arguments-data"), cStats.objectsExtra.argumentsData, - "Memory allocated on the malloc heap for data belonging to arguments objects."); + "Memory allocated for data belonging to arguments objects."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/regexp-statics"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/regexp-statics"), cStats.objectsExtra.regExpStatics, "Memory allocated for data belonging to the RegExpStatics object."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/property-iterator-data"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/property-iterator-data"), cStats.objectsExtra.propertyIteratorData, - "Memory allocated on the malloc heap for data belonging to property iterator objects."); + "Memory allocated for data belonging to property iterator objects."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/ctypes-data"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/ctypes-data"), cStats.objectsExtra.ctypesData, - "Memory allocated on the malloc heap for data belonging to ctypes objects."); + "Memory allocated for data belonging to ctypes objects."); // Note that we use cDOMPathPrefix here. This is because we measure orphan // DOM nodes in the JS multi-reporter, but we want to report them in a @@ -1977,30 +1895,29 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats, "Memory used by orphan DOM nodes that are only reachable " "from JavaScript objects."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/tree-tables"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes-extra/tree-tables"), cStats.shapesExtraTreeTables, - "Memory allocated on the malloc heap for the property tables " + "Memory allocated for the property tables " "that belong to shapes that are in a property tree."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/dict-tables"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes-extra/dict-tables"), cStats.shapesExtraDictTables, - "Memory allocated on the malloc heap for the property tables " + "Memory allocated for the property tables " "that belong to shapes that are in dictionary mode."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/tree-shape-kids"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes-extra/tree-shape-kids"), cStats.shapesExtraTreeShapeKids, - "Memory allocated on the malloc heap for the kid hashes that " + "Memory allocated for the kid hashes that " "belong to shapes that are in a property tree."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/compartment-tables"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes-extra/compartment-tables"), cStats.shapesCompartmentTables, - "Memory on the malloc heap used by compartment-wide tables storing shape " + "Memory used by compartment-wide tables storing shape " "information for use during object construction."); - ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("scripts/malloc-heap/data"), + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("script-data"), cStats.scriptData, - "Memory on the malloc heap allocated for various variable-length tables in " - "JSScript."); + "Memory allocated for various variable-length tables in JSScript."); ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("baseline/data"), cStats.baselineData, @@ -2069,18 +1986,20 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats, if (gcHeapSundries > 0) { // We deliberately don't use ZCREPORT_GC_BYTES here. - REPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("sundries/gc-heap"), + REPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("gc-heap/sundries"), gcHeapSundries, - "The sum of all the 'gc-heap' measurements that are too " - "small to be worth showing individually."); + "The sum of all the gc-heap " + "measurements that are too small to be worth showing " + "individually."); } if (otherSundries > 0) { // We deliberately don't use ZCREPORT_BYTES here. - REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("sundries/malloc-heap"), - KIND_HEAP, otherSundries, - "The sum of all the 'malloc-heap' measurements that are too " - "small to be worth showing individually."); + REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("other-sundries"), + nsIMemoryReporter::KIND_HEAP, otherSundries, + "The sum of all the non-gc-heap " + "measurements that are too small to be worth showing " + "individually."); } if (gcTotalOut) @@ -2101,7 +2020,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats, size_t gcTotal = 0; for (size_t i = 0; i < rtStats.zoneStatsVector.length(); i++) { - const JS::ZoneStats &zStats = rtStats.zoneStatsVector[i]; + JS::ZoneStats zStats = rtStats.zoneStatsVector[i]; const xpc::ZoneStatsExtras *extras = static_cast(zStats.extra); rv = ReportZoneStats(zStats, *extras, cb, closure, &gcTotal); @@ -2523,55 +2442,55 @@ JSMemoryMultiReporter::CollectReports(WindowPaths *windowPaths, // Report the sum of the runtime/ numbers. REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/runtime"), - KIND_OTHER, rtTotal, + nsIMemoryReporter::KIND_OTHER, rtTotal, "The sum of all measurements under 'explicit/js-non-window/runtime/'."); // Report the numbers for memory outside of compartments. REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/unused-chunks"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapUnusedChunks, "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/unused-arenas"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapUnusedArenas, "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/chunk-admin"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapChunkAdmin, "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."); // Report a breakdown of the committed GC space. REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/chunks"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapUnusedChunks, "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/arenas"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapUnusedArenas, "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.zTotals.gcHeapUnusedGcThings, "The same as 'js-main-runtime/compartments/gc-heap/unused-gc-things'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/chunk-admin"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapChunkAdmin, "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/arena-admin"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.zTotals.gcHeapArenaAdmin, "The same as 'js-main-runtime/compartments/gc-heap/arena-admin'."); REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things"), - KIND_OTHER, + nsIMemoryReporter::KIND_OTHER, rtStats.gcHeapGcThings, "Memory on the garbage-collected JavaScript heap that holds GC things such " "as objects, strings, scripts, etc.") @@ -2579,7 +2498,7 @@ JSMemoryMultiReporter::CollectReports(WindowPaths *windowPaths, // Report xpconnect. REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect"), - KIND_HEAP, xpconnect, + nsIMemoryReporter::KIND_HEAP, xpconnect, "Memory used by XPConnect."); return NS_OK; diff --git a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul index efaf8ded068..2b71260ce60 100644 --- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul +++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul @@ -52,26 +52,6 @@ let isImagesPresent = false; let isXptiWorkingSetPresent = false; let isAtomTablePresent = false; - let isBigStringPresent = false; - let isSmallString1Present = false; - let isSmallString2Present = false; - - // Generate a long, random string. We'll check that this string is - // reported in at least one of the memory reporters. - let bigString = ""; - while (bigString.length < 10000) { - bigString += Math.random(); - } - let bigStringPrefix = bigString.substring(0, 100); - - // Generate many copies of two distinctive short strings, "!)(*&" and - // "@)(*&". We'll check that these strings are reported in at least - // one of the memory reporters. - let shortStrings = []; - for (let i = 0; i < 10000; i++) { - let str = (Math.random() > 0.5 ? "!" : "@") + ")(*&"; - shortStrings.push(str); - } let mySandbox = Components.utils.Sandbox(document.nodePrincipal, { sandboxName: "this-is-a-sandbox-name" }); @@ -107,12 +87,6 @@ // A system compartment with a location (such as a sandbox) should // show that location. isSandboxLocationShown = true; - } else if (aPath.contains(bigStringPrefix)) { - isBigStringPresent = true; - } else if (aPath.contains("!)(*&")) { - isSmallString1Present = true; - } else if (aPath.contains("@)(*&")) { - isSmallString2Present = true; } } @@ -174,9 +148,6 @@ ok(isImagesPresent, "images is present"); ok(isXptiWorkingSetPresent, "xpti-working-set is present"); ok(isAtomTablePresent, "atom-table is present"); - ok(isBigStringPresent, "large string is present"); - ok(isSmallString1Present, "small string 1 is present"); - ok(isSmallString2Present, "small string 2 is present"); ]]>