mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 943744 (part 2) - Represent the sizes in StringInfo more compactly. r=till.
--HG-- extra : rebase_source : 799693bac2beb4609daf55fc5e8cbe19adff3ed8
This commit is contained in:
parent
6633debe59
commit
b72a8989be
@ -211,49 +211,45 @@ struct 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.
|
||||
// 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
|
||||
{
|
||||
StringInfo()
|
||||
: numCopies(0), shortGCHeap(0), normalGCHeap(0), normalMallocHeap(0)
|
||||
: numCopies(0),
|
||||
isShort(0),
|
||||
gcHeap(0),
|
||||
mallocHeap(0)
|
||||
{}
|
||||
|
||||
StringInfo(size_t shorts, size_t normals, size_t chars)
|
||||
StringInfo(bool isShort, size_t gcSize, size_t mallocSize)
|
||||
: numCopies(1),
|
||||
shortGCHeap(shorts),
|
||||
normalGCHeap(normals),
|
||||
normalMallocHeap(chars)
|
||||
isShort(isShort),
|
||||
gcHeap(gcSize),
|
||||
mallocHeap(mallocSize)
|
||||
{}
|
||||
|
||||
void add(size_t shorts, size_t normals, size_t chars) {
|
||||
shortGCHeap += shorts;
|
||||
normalGCHeap += normals;
|
||||
normalMallocHeap += chars;
|
||||
void add(bool isShort, size_t gcSize, size_t mallocSize) {
|
||||
numCopies++;
|
||||
MOZ_ASSERT(isShort == this->isShort);
|
||||
gcHeap += gcSize;
|
||||
mallocHeap += mallocSize;
|
||||
}
|
||||
|
||||
void add(const StringInfo& info) {
|
||||
shortGCHeap += info.shortGCHeap;
|
||||
normalGCHeap += info.normalGCHeap;
|
||||
normalMallocHeap += info.normalMallocHeap;
|
||||
numCopies += info.numCopies;
|
||||
MOZ_ASSERT(info.isShort == isShort);
|
||||
gcHeap += info.gcHeap;
|
||||
mallocHeap += info.mallocHeap;
|
||||
}
|
||||
|
||||
size_t totalSizeOf() const {
|
||||
return shortGCHeap + normalGCHeap + normalMallocHeap;
|
||||
}
|
||||
|
||||
size_t totalGCHeapSizeOf() const {
|
||||
return shortGCHeap + normalGCHeap;
|
||||
}
|
||||
|
||||
// How many copies of the string have we seen?
|
||||
size_t numCopies;
|
||||
uint32_t numCopies:31; // How many copies of the string have we seen?
|
||||
uint32_t isShort:1; // Is it a short string?
|
||||
|
||||
// These are all totals across all copies of the string we've seen.
|
||||
size_t shortGCHeap;
|
||||
size_t normalGCHeap;
|
||||
size_t normalMallocHeap;
|
||||
size_t gcHeap;
|
||||
size_t mallocHeap;
|
||||
};
|
||||
|
||||
// Holds data about a notable string (one which uses more than
|
||||
@ -353,7 +349,7 @@ struct ZoneStats : js::ZoneStatsPod
|
||||
size_t n = ZoneStatsPod::sizeOfLiveGCThings();
|
||||
for (size_t i = 0; i < notableStrings.length(); i++) {
|
||||
const JS::NotableStringInfo& info = notableStrings[i];
|
||||
n += info.totalGCHeapSizeOf();
|
||||
n += info.gcHeap;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -56,7 +56,15 @@ InefficientNonFlatteningStringHashPolicy::hash(const Lookup &l)
|
||||
chars = ownedChars;
|
||||
}
|
||||
|
||||
return mozilla::HashString(chars, l->length());
|
||||
// We include the result of isShort() in the hash. This is because it is
|
||||
// possible for a particular string (i.e. unique char sequence) to have one
|
||||
// or more copies as short strings and one or more copies as non-short
|
||||
// strings, and treating them separately for the purposes of notable string
|
||||
// detection makes things simpler. In practice, although such collisions
|
||||
// do happen, they are sufficiently rare that they are unlikely to have a
|
||||
// significant effect on which strings are considered notable.
|
||||
return mozilla::AddToHash(mozilla::HashString(chars, l->length()),
|
||||
l->isShort());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@ -66,6 +74,10 @@ InefficientNonFlatteningStringHashPolicy::match(const JSString *const &k, const
|
||||
if (k->length() != l->length())
|
||||
return false;
|
||||
|
||||
// Just like in hash(), we must consider isShort() for the two strings.
|
||||
if (k->isShort() != l->isShort())
|
||||
return false;
|
||||
|
||||
const jschar *c1;
|
||||
ScopedJSFreePtr<jschar> ownedChars1;
|
||||
if (k->hasPureChars()) {
|
||||
@ -277,11 +289,17 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin
|
||||
case JSTRACE_STRING: {
|
||||
JSString *str = static_cast<JSString *>(thing);
|
||||
|
||||
bool isShort = str->isShort();
|
||||
size_t strCharsSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf_);
|
||||
MOZ_ASSERT_IF(str->isShort(), strCharsSize == 0);
|
||||
|
||||
size_t shortStringThingSize = str->isShort() ? thingSize : 0;
|
||||
size_t normalStringThingSize = !str->isShort() ? thingSize : 0;
|
||||
|
||||
if (isShort) {
|
||||
zStats->stringsShortGCHeap += thingSize;
|
||||
MOZ_ASSERT(strCharsSize == 0);
|
||||
} else {
|
||||
zStats->stringsNormalGCHeap += thingSize;
|
||||
zStats->stringsNormalMallocHeap += strCharsSize;
|
||||
}
|
||||
|
||||
// This string hashing is expensive. Its results are unused when doing
|
||||
// coarse-grained measurements, and skipping it more than doubles the
|
||||
@ -289,18 +307,13 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin
|
||||
if (granularity == FineGrained) {
|
||||
ZoneStats::StringsHashMap::AddPtr p = zStats->strings.lookupForAdd(str);
|
||||
if (!p) {
|
||||
JS::StringInfo info(shortStringThingSize,
|
||||
normalStringThingSize, strCharsSize);
|
||||
JS::StringInfo info(isShort, thingSize, strCharsSize);
|
||||
zStats->strings.add(p, str, info);
|
||||
} else {
|
||||
p->value().add(shortStringThingSize, normalStringThingSize, strCharsSize);
|
||||
p->value().add(isShort, thingSize, strCharsSize);
|
||||
}
|
||||
}
|
||||
|
||||
zStats->stringsShortGCHeap += shortStringThingSize;
|
||||
zStats->stringsNormalGCHeap += normalStringThingSize;
|
||||
zStats->stringsNormalMallocHeap += strCharsSize;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -402,7 +415,7 @@ FindNotableStrings(ZoneStats &zStats)
|
||||
|
||||
// If this string is too small, or if we can't grow the notableStrings
|
||||
// vector, skip this string.
|
||||
if (info.totalSizeOf() < NotableStringInfo::notableSize() ||
|
||||
if (info.gcHeap + info.mallocHeap < NotableStringInfo::notableSize() ||
|
||||
!zStats.notableStrings.growBy(1))
|
||||
continue;
|
||||
|
||||
@ -410,12 +423,16 @@ FindNotableStrings(ZoneStats &zStats)
|
||||
|
||||
// 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.stringsShortGCHeap >= info.shortGCHeap);
|
||||
MOZ_ASSERT(zStats.stringsNormalGCHeap >= info.normalGCHeap);
|
||||
MOZ_ASSERT(zStats.stringsNormalMallocHeap >= info.normalMallocHeap);
|
||||
zStats.stringsShortGCHeap -= info.shortGCHeap;
|
||||
zStats.stringsNormalGCHeap -= info.normalGCHeap;
|
||||
zStats.stringsNormalMallocHeap -= info.normalMallocHeap;
|
||||
if (info.isShort) {
|
||||
MOZ_ASSERT(zStats.stringsShortGCHeap >= info.gcHeap);
|
||||
zStats.stringsShortGCHeap -= info.gcHeap;
|
||||
MOZ_ASSERT(info.mallocHeap == 0);
|
||||
} else {
|
||||
MOZ_ASSERT(zStats.stringsNormalGCHeap >= info.gcHeap);
|
||||
MOZ_ASSERT(zStats.stringsNormalMallocHeap >= info.mallocHeap);
|
||||
zStats.stringsNormalGCHeap -= info.gcHeap;
|
||||
zStats.stringsNormalMallocHeap -= info.mallocHeap;
|
||||
}
|
||||
}
|
||||
|
||||
// zStats.strings holds unrooted JSString pointers, which we don't want to
|
||||
|
@ -1864,8 +1864,8 @@ ReportZoneStats(const JS::ZoneStats &zStats,
|
||||
// bucket.
|
||||
# define STRING_LENGTH "string(length="
|
||||
if (FindInReadable(NS_LITERAL_CSTRING(STRING_LENGTH), notableString)) {
|
||||
stringsNotableAboutMemoryGCHeap += info.totalGCHeapSizeOf();
|
||||
stringsNotableAboutMemoryMallocHeap += info.normalMallocHeap;
|
||||
stringsNotableAboutMemoryGCHeap += info.gcHeap;
|
||||
stringsNotableAboutMemoryMallocHeap += info.mallocHeap;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1884,7 +1884,7 @@ ReportZoneStats(const JS::ZoneStats &zStats,
|
||||
|
||||
REPORT_BYTES2(path + NS_LITERAL_CSTRING("gc-heap"),
|
||||
KIND_NONHEAP,
|
||||
info.totalGCHeapSizeOf(),
|
||||
info.gcHeap,
|
||||
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 "
|
||||
@ -1893,12 +1893,12 @@ ReportZoneStats(const JS::ZoneStats &zStats,
|
||||
"is short enough. If so, the string won't have any memory reported "
|
||||
"under 'string-chars'.",
|
||||
JS::NotableStringInfo::notableSize()));
|
||||
gcTotal += info.totalGCHeapSizeOf();
|
||||
gcTotal += info.gcHeap;
|
||||
|
||||
if (info.normalMallocHeap > 0) {
|
||||
if (info.mallocHeap > 0) {
|
||||
REPORT_BYTES2(path + NS_LITERAL_CSTRING("malloc-heap"),
|
||||
KIND_HEAP,
|
||||
info.normalMallocHeap,
|
||||
info.mallocHeap,
|
||||
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 "
|
||||
|
Loading…
Reference in New Issue
Block a user