Bug 814229 (part 2) - Refactor storage of the "objects-extra" numbers.

--HG--
extra : rebase_source : 2125ae4446928fbc7432f22505565b9b246f960d
This commit is contained in:
Nicholas Nethercote 2012-11-21 17:07:42 -08:00
parent 615e573039
commit 8c3e8f0d58
7 changed files with 83 additions and 109 deletions

View File

@ -34,21 +34,33 @@ JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold();
namespace JS {
// Data for tracking memory usage of things hanging off objects.
struct ObjectsExtraSizes {
size_t slots;
size_t elements;
size_t argumentsData;
size_t regExpStatics;
size_t propertyIteratorData;
size_t ctypesData;
size_t private_; // The '_' suffix is required because |private| is a keyword.
// Note that this field is measured separately from the others.
ObjectsExtraSizes() { memset(this, 0, sizeof(ObjectsExtraSizes)); }
void add(ObjectsExtraSizes &sizes) {
this->slots += sizes.slots;
this->elements += sizes.elements;
this->argumentsData += sizes.argumentsData;
this->regExpStatics += sizes.regExpStatics;
this->propertyIteratorData += sizes.propertyIteratorData;
this->ctypesData += sizes.ctypesData;
this->private_ += sizes.private_;
}
};
// Data for tracking analysis/inference memory usage.
struct TypeInferenceSizes
{
TypeInferenceSizes()
: typeScripts(0)
, typeResults(0)
, analysisPool(0)
, typePool(0)
, pendingArrays(0)
, allocationSiteTables(0)
, arrayTypeTables(0)
, objectTypeTables(0)
, typeObjects(0)
{}
size_t typeScripts;
size_t typeResults;
size_t analysisPool;
@ -59,6 +71,8 @@ struct TypeInferenceSizes
size_t objectTypeTables;
size_t typeObjects;
TypeInferenceSizes() { memset(this, 0, sizeof(TypeInferenceSizes)); }
void add(TypeInferenceSizes &sizes) {
this->typeScripts += sizes.typeScripts;
this->typeResults += sizes.typeResults;
@ -161,13 +175,7 @@ struct CompartmentStats
#if JS_HAS_XML_SUPPORT
, gcHeapXML(0)
#endif
, objectsExtraSlots(0)
, objectsExtraElements(0)
, objectsExtraArgumentsData(0)
, objectsExtraRegExpStatics(0)
, objectsExtraPropertyIteratorData(0)
, objectsExtraCtypesData(0)
, objectsExtraPrivate(0)
, objectsExtra()
, stringCharsNonHuge(0)
, shapesExtraTreeTables(0)
, shapesExtraDictTables(0)
@ -180,6 +188,8 @@ struct CompartmentStats
, crossCompartmentWrappersTable(0)
, regexpCompartment(0)
, debuggeesSet(0)
, typeInference()
, hugeStrings()
{}
CompartmentStats(const CompartmentStats &other)
@ -204,13 +214,7 @@ struct CompartmentStats
#if JS_HAS_XML_SUPPORT
, gcHeapXML(other.gcHeapXML)
#endif
, objectsExtraSlots(other.objectsExtraSlots)
, objectsExtraElements(other.objectsExtraElements)
, objectsExtraArgumentsData(other.objectsExtraArgumentsData)
, objectsExtraRegExpStatics(other.objectsExtraRegExpStatics)
, objectsExtraPropertyIteratorData(other.objectsExtraPropertyIteratorData)
, objectsExtraCtypesData(other.objectsExtraCtypesData)
, objectsExtraPrivate(other.objectsExtraPrivate)
, objectsExtra(other.objectsExtra)
, stringCharsNonHuge(other.stringCharsNonHuge)
, shapesExtraTreeTables(other.shapesExtraTreeTables)
, shapesExtraDictTables(other.shapesExtraDictTables)
@ -223,7 +227,7 @@ struct CompartmentStats
, crossCompartmentWrappersTable(other.crossCompartmentWrappersTable)
, regexpCompartment(other.regexpCompartment)
, debuggeesSet(other.debuggeesSet)
, typeInferenceSizes(other.typeInferenceSizes)
, typeInference(other.typeInference)
{
hugeStrings.append(other.hugeStrings);
}
@ -254,14 +258,8 @@ struct CompartmentStats
#if JS_HAS_XML_SUPPORT
size_t gcHeapXML;
#endif
ObjectsExtraSizes objectsExtra;
size_t objectsExtraSlots;
size_t objectsExtraElements;
size_t objectsExtraArgumentsData;
size_t objectsExtraRegExpStatics;
size_t objectsExtraPropertyIteratorData;
size_t objectsExtraCtypesData;
size_t objectsExtraPrivate;
size_t stringCharsNonHuge;
size_t shapesExtraTreeTables;
size_t shapesExtraDictTables;
@ -275,7 +273,7 @@ struct CompartmentStats
size_t regexpCompartment;
size_t debuggeesSet;
TypeInferenceSizes typeInferenceSizes;
TypeInferenceSizes typeInference;
js::Vector<HugeStringInfo, 0, js::SystemAllocPolicy> hugeStrings;
// Add cStats's numbers to this object's numbers.
@ -303,14 +301,8 @@ struct CompartmentStats
#if JS_HAS_XML_SUPPORT
ADD(gcHeapXML);
#endif
objectsExtra.add(cStats.objectsExtra);
ADD(objectsExtraSlots);
ADD(objectsExtraElements);
ADD(objectsExtraArgumentsData);
ADD(objectsExtraRegExpStatics);
ADD(objectsExtraPropertyIteratorData);
ADD(objectsExtraCtypesData);
ADD(objectsExtraPrivate);
ADD(stringCharsNonHuge);
ADD(shapesExtraTreeTables);
ADD(shapesExtraDictTables);
@ -326,7 +318,7 @@ struct CompartmentStats
#undef ADD
typeInferenceSizes.add(cStats.typeInferenceSizes);
typeInference.add(cStats.typeInference);
hugeStrings.append(cStats.hugeStrings);
}

View File

@ -6547,8 +6547,8 @@ JSCompartment::sizeOfTypeInferenceData(TypeInferenceSizes *sizes, JSMallocSizeOf
}
}
void
TypeObject::sizeOfExcludingThis(TypeInferenceSizes *sizes, JSMallocSizeOfFun mallocSizeOf)
size_t
TypeObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf)
{
if (singleton) {
/*
@ -6557,8 +6557,8 @@ TypeObject::sizeOfExcludingThis(TypeInferenceSizes *sizes, JSMallocSizeOfFun mal
* charge this to 'temporary' as this is not for GC heap values.
*/
JS_ASSERT(!newScript);
return;
return 0;
}
sizes->typeObjects += mallocSizeOf(newScript);
return mallocSizeOf(newScript);
}

View File

@ -22,10 +22,6 @@
ForwardDeclareJS(Script);
namespace JS {
struct TypeInferenceSizes;
}
namespace js {
class TaggedProto
@ -1036,7 +1032,7 @@ struct TypeObject : gc::Cell
inline void clearProperties();
inline void sweep(FreeOp *fop);
void sizeOfExcludingThis(TypeInferenceSizes *sizes, JSMallocSizeOfFun mallocSizeOf);
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf);
/*
* Type objects don't have explicit finalizers. Memory owned by a type

View File

@ -94,7 +94,7 @@ StatsCompartmentCallback(JSRuntime *rt, void *data, JSCompartment *compartment)
// Measure the compartment object itself, and things hanging off it.
compartment->sizeOfIncludingThis(rtStats->mallocSizeOf,
&cStats.compartmentObject,
&cStats.typeInferenceSizes,
&cStats.typeInference,
&cStats.shapesCompartmentTables,
&cStats.crossCompartmentWrappersTable,
&cStats.regexpCompartment,
@ -151,24 +151,19 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin
} else {
cStats->gcHeapObjectsOrdinary += thingSize;
}
size_t slotsSize, elementsSize, argumentsDataSize, regExpStaticsSize,
propertyIteratorDataSize, ctypesDataSize;
obj->sizeOfExcludingThis(rtStats->mallocSizeOf, &slotsSize, &elementsSize,
&argumentsDataSize, &regExpStaticsSize,
&propertyIteratorDataSize, &ctypesDataSize);
cStats->objectsExtraSlots += slotsSize;
cStats->objectsExtraElements += elementsSize;
cStats->objectsExtraArgumentsData += argumentsDataSize;
cStats->objectsExtraRegExpStatics += regExpStaticsSize;
cStats->objectsExtraPropertyIteratorData += propertyIteratorDataSize;
cStats->objectsExtraCtypesData += ctypesDataSize;
ObjectsExtraSizes objectsExtra;
obj->sizeOfExcludingThis(rtStats->mallocSizeOf, &objectsExtra);
cStats->objectsExtra.add(objectsExtra);
// JSObject::sizeOfExcludingThis() doesn't measure objectsExtraPrivate,
// so we do it here.
if (ObjectPrivateVisitor *opv = closure->opv) {
js::Class *clazz = js::GetObjectClass(obj);
if (clazz->flags & JSCLASS_HAS_PRIVATE &&
clazz->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS)
{
cStats->objectsExtraPrivate += opv->sizeOfIncludingThis(GetObjectPrivate(obj));
cStats->objectsExtra.private_ += opv->sizeOfIncludingThis(GetObjectPrivate(obj));
}
}
break;
@ -255,7 +250,7 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin
{
types::TypeObject *obj = static_cast<types::TypeObject *>(thing);
cStats->gcHeapTypeObjects += thingSize;
obj->sizeOfExcludingThis(&cStats->typeInferenceSizes, rtStats->mallocSizeOf);
cStats->typeInference.typeObjects += obj->sizeOfExcludingThis(rtStats->mallocSizeOf);
break;
}
#if JS_HAS_XML_SUPPORT

View File

@ -28,6 +28,10 @@
#include "vm/ObjectImpl.h"
#include "vm/String.h"
namespace JS {
struct ObjectsExtraSizes;
}
namespace js {
class AutoPropDescArrayRooter;
@ -368,11 +372,7 @@ struct JSObject : public js::ObjectImpl
inline size_t computedSizeOfThisSlotsElements() const;
inline void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *slotsSize,
size_t *elementsSize, size_t *argumentsDataSize,
size_t *regExpStaticsSize,
size_t *propertyIteratorDataSize,
size_t *ctypesDataSize) const;
inline void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes);
bool hasIdempotentProtoChain() const;

View File

@ -31,6 +31,7 @@
#include "gc/Barrier.h"
#include "gc/Marking.h"
#include "gc/Root.h"
#include "js/MemoryMetrics.h"
#include "js/TemplateLib.h"
#include "vm/BooleanObject.h"
#include "vm/GlobalObject.h"
@ -999,35 +1000,25 @@ JSObject::computedSizeOfThisSlotsElements() const
}
inline void
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *slotsSize,
size_t *elementsSize, size_t *argumentsDataSize,
size_t *regExpStaticsSize, size_t *propertyIteratorDataSize,
size_t *ctypesDataSize) const
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes)
{
*slotsSize = 0;
if (hasDynamicSlots()) {
*slotsSize += mallocSizeOf(slots);
}
if (hasDynamicSlots())
sizes->slots = mallocSizeOf(slots);
*elementsSize = 0;
if (hasDynamicElements()) {
*elementsSize += mallocSizeOf(getElementsHeader());
}
if (hasDynamicElements())
sizes->elements = mallocSizeOf(getElementsHeader());
/* Other things may be measured in the future if DMD indicates it is worthwhile. */
*argumentsDataSize = 0;
*regExpStaticsSize = 0;
*propertyIteratorDataSize = 0;
*ctypesDataSize = 0;
// Other things may be measured in the future if DMD indicates it is worthwhile.
// Note that sizes->private_ is measured elsewhere.
if (isArguments()) {
*argumentsDataSize += asArguments().sizeOfMisc(mallocSizeOf);
sizes->argumentsData = asArguments().sizeOfMisc(mallocSizeOf);
} else if (isRegExpStatics()) {
*regExpStaticsSize += js::SizeOfRegExpStaticsData(this, mallocSizeOf);
sizes->regExpStatics = js::SizeOfRegExpStaticsData(this, mallocSizeOf);
} else if (isPropertyIterator()) {
*propertyIteratorDataSize += asPropertyIterator().sizeOfMisc(mallocSizeOf);
sizes->propertyIteratorData = asPropertyIterator().sizeOfMisc(mallocSizeOf);
} else {
// This must be the last case.
*ctypesDataSize += js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
sizes->ctypesData = js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
}
}

View File

@ -1597,7 +1597,7 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
#endif
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/slots"),
cStats.objectsExtraSlots,
cStats.objectsExtra.slots,
"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 "
@ -1605,32 +1605,32 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
"are not counted here, but in 'gc-heap/objects' instead.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements"),
cStats.objectsExtraElements,
cStats.objectsExtra.elements,
"Memory allocated for object element "
"arrays, which are used to represent indexed object "
"properties.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/arguments-data"),
cStats.objectsExtraArgumentsData,
cStats.objectsExtra.argumentsData,
"Memory allocated for data belonging to arguments objects.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/regexp-statics"),
cStats.objectsExtraRegExpStatics,
cStats.objectsExtra.regExpStatics,
"Memory allocated for data belonging to the RegExpStatics object.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/property-iterator-data"),
cStats.objectsExtraPropertyIteratorData,
cStats.objectsExtra.propertyIteratorData,
"Memory allocated for data belonging to property iterator objects.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/ctypes-data"),
cStats.objectsExtraCtypesData,
cStats.objectsExtra.ctypesData,
"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
// "dom" sub-tree rather than a "js" sub-tree.
CREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),
cStats.objectsExtraPrivate,
cStats.objectsExtra.private_,
"Memory used by orphan DOM nodes that are only reachable "
"from JavaScript objects.");
@ -1686,40 +1686,40 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
"Memory used by the debuggees set.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/type-scripts"),
cStats.typeInferenceSizes.typeScripts,
cStats.typeInference.typeScripts,
"Memory used by type sets associated with scripts.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/type-results"),
cStats.typeInferenceSizes.typeResults,
cStats.typeInference.typeResults,
"Memory used by dynamic type results produced by scripts.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/analysis-pool"),
cStats.typeInferenceSizes.analysisPool,
cStats.typeInference.analysisPool,
"Memory holding transient analysis information used during type inference and "
"compilation.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/type-pool"),
cStats.typeInferenceSizes.typePool,
cStats.typeInference.typePool,
"Memory holding contents of type sets and related data.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/pending-arrays"),
cStats.typeInferenceSizes.pendingArrays,
cStats.typeInference.pendingArrays,
"Memory used for solving constraints during type inference.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/allocation-site-tables"),
cStats.typeInferenceSizes.allocationSiteTables,
cStats.typeInference.allocationSiteTables,
"Memory indexing type objects associated with allocation sites.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/array-type-tables"),
cStats.typeInferenceSizes.arrayTypeTables,
cStats.typeInference.arrayTypeTables,
"Memory indexing type objects associated with array literals.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/object-type-tables"),
cStats.typeInferenceSizes.objectTypeTables,
cStats.typeInference.objectTypeTables,
"Memory indexing type objects associated with object literals.");
CREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/type-objects"),
cStats.typeInferenceSizes.typeObjects,
cStats.typeInference.typeObjects,
"Memory holding miscellaneous additional information associated with type "
"objects.");