Backed out 7 changesets (bug 893222, bug 899256) for build bustage on a CLOSED TREE.

Backed out changeset 4aa234138f44 (bug 893222)
Backed out changeset 4b0bf28abdf2 (bug 899256)
Backed out changeset ea8b6ba99c05 (bug 893222)
Backed out changeset ac8220cb61d5 (bug 893222)
Backed out changeset d01358ff4b15 (bug 893222)
Backed out changeset 3baebe7cc655 (bug 893222)
Backed out changeset 4bdf8611ec57 (bug 893222)
This commit is contained in:
Ryan VanderMeulen 2013-08-02 14:49:38 -04:00
parent 790587f72d
commit e4c4af080d
7 changed files with 223 additions and 592 deletions

View File

@ -11,14 +11,12 @@
// change in the future. Depend on them at your own risk.
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"
#include <string.h>
#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<NotableStringInfo> info);
NotableStringInfo &operator=(mozilla::MoveRef<NotableStringInfo> 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<ZoneStats> 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<JSString*, StringInfo, js::StringHashPolicy, js::SystemAllocPolicy>
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<NotableStringInfo, 0, js::SystemAllocPolicy> 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<HugeStringInfo, 0, js::SystemAllocPolicy> hugeStrings;
// The size of all the live things in the GC heap that don't belong to any
// compartment.

View File

@ -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<jschar> 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<jschar> ownedChars1;
if (!c1) {
if (!k->getCharsNonDestructive(/* tcx */ NULL, ownedChars1))
MOZ_CRASH("oom");
c1 = ownedChars1;
}
const jschar *c2 = l->maybeChars();
ScopedJSFreePtr<jschar> 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<char>(bufferSize);
if (!buffer) {
MOZ_CRASH("oom");
}
const jschar* chars = str->maybeChars();
ScopedJSFreePtr<jschar> 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<char>(bufferSize);
if (!buffer)
MOZ_CRASH("oom");
strcpy(buffer, info.buffer);
}
NotableStringInfo::NotableStringInfo(MoveRef<NotableStringInfo> info)
: StringInfo(info)
{
buffer = info->buffer;
info->buffer = NULL;
}
NotableStringInfo &NotableStringInfo::operator=(MoveRef<NotableStringInfo> info)
{
this->~NotableStringInfo();
new (this) NotableStringInfo(info);
return *this;
}
NotableStringInfo::~NotableStringInfo()
{
js_free(buffer);
}
} // namespace JS
typedef HashSet<ScriptSource *, DefaultHasher<ScriptSource *>, SystemAllocPolicy> SourceSet;
struct IteratorClosure
@ -312,25 +201,23 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin
case JSTRACE_STRING: {
JSString *str = static_cast<JSString *>(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];

View File

@ -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;

View File

@ -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

View File

@ -185,12 +185,7 @@ JSRope::getCharsNonDestructiveInternal(ThreadSafeContext *cx, ScopedJSFreePtr<js
*/
size_t n = length();
jschar *s;
if (cx)
s = cx->pod_malloc<jschar>(n + 1);
else
s = js_pod_malloc<jschar>(n + 1);
jschar *s = cx->pod_malloc<jschar>(n + 1);
if (!s)
return false;
jschar *pos = s;

View File

@ -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<const xpc::ZoneStatsExtras*>(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;

View File

@ -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");
]]>
</script>