mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Measure type inference memory usage, bug 669958. r=njn
This commit is contained in:
parent
8853bbc4cc
commit
752b11eaa2
@ -286,6 +286,18 @@ ArenaNew(JSArenaPool &pool, const A &a, const B &b, const C &c, const D &d, cons
|
||||
return v ? new (v) T(a, b, c, d, e) : NULL;
|
||||
}
|
||||
|
||||
inline uintN
|
||||
ArenaAllocatedSize(const JSArenaPool &pool)
|
||||
{
|
||||
uintN res = 0;
|
||||
const JSArena *a = &pool.first;
|
||||
while (a) {
|
||||
res += (a->limit - (jsuword)a);
|
||||
a = a->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
@ -394,6 +394,18 @@ struct JS_FRIEND_API(JSCompartment) {
|
||||
|
||||
bool condenseTypes(JSContext *cx);
|
||||
|
||||
/* Data for tracking analysis/inference memory usage. */
|
||||
struct TypeInferenceMemoryStats
|
||||
{
|
||||
int64 scriptMain;
|
||||
int64 scriptSets;
|
||||
int64 objectMain;
|
||||
int64 objectSets;
|
||||
int64 poolMain;
|
||||
};
|
||||
|
||||
void getTypeInferenceMemoryStats(TypeInferenceMemoryStats *stats);
|
||||
|
||||
#ifdef JS_TRACER
|
||||
private:
|
||||
/*
|
||||
|
@ -516,6 +516,8 @@ public:
|
||||
}
|
||||
|
||||
TypeObject * persistentObject() { return object; }
|
||||
|
||||
size_t allocatedSize() { return sizeof(TypeConstraintBaseSubset); }
|
||||
};
|
||||
|
||||
void
|
||||
@ -556,6 +558,8 @@ public:
|
||||
void newObjectState(JSContext *cx, TypeObject*, bool) { checkAnalysis(cx); }
|
||||
|
||||
bool condensed() { return true; }
|
||||
|
||||
size_t allocatedSize() { return sizeof(TypeConstraintCondensed); }
|
||||
};
|
||||
|
||||
bool
|
||||
@ -4288,6 +4292,8 @@ class TypeIntermediateClearDefinite : public TypeIntermediate
|
||||
{
|
||||
return object->marked;
|
||||
}
|
||||
|
||||
size_t allocatedSize() { return sizeof(TypeIntermediateClearDefinite); }
|
||||
};
|
||||
|
||||
static bool
|
||||
@ -4829,6 +4835,8 @@ class TypeIntermediatePushed : public TypeIntermediate
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t allocatedSize() { return sizeof(TypeIntermediatePushed); }
|
||||
};
|
||||
|
||||
void
|
||||
@ -5634,3 +5642,76 @@ JSScript::sweepAnalysis(JSContext *cx)
|
||||
analysis_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
TypeSet::dynamicSize()
|
||||
{
|
||||
size_t res = 0;
|
||||
|
||||
if (objectCount >= 2)
|
||||
res += HashSetCapacity(objectCount) * sizeof(TypeObject *);
|
||||
|
||||
/* Get the total size of any heap-allocated constraints on this set. */
|
||||
TypeConstraint *constraint = constraintList;
|
||||
while (constraint) {
|
||||
res += constraint->allocatedSize();
|
||||
constraint = constraint->next;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
GetObjectListMemoryStats(TypeObject *object, JSCompartment::TypeInferenceMemoryStats *stats)
|
||||
{
|
||||
while (object) {
|
||||
stats->objectMain += sizeof(TypeObject);
|
||||
|
||||
if (object->propertyCount >= 2)
|
||||
stats->objectMain += HashSetCapacity(object->propertyCount) * sizeof(Property *);
|
||||
|
||||
unsigned count = object->getPropertyCount();
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
Property *prop = object->getProperty(i);
|
||||
if (prop) {
|
||||
stats->objectMain += sizeof(Property);
|
||||
stats->objectSets += prop->types.dynamicSize();
|
||||
}
|
||||
}
|
||||
|
||||
object = object->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GetScriptMemoryStats(JSScript *script, JSCompartment::TypeInferenceMemoryStats *stats)
|
||||
{
|
||||
GetObjectListMemoryStats(script->types.typeObjects, stats);
|
||||
|
||||
if (!script->types.typeArray)
|
||||
return;
|
||||
|
||||
unsigned count = script->types.numTypeSets();
|
||||
stats->scriptMain += count * sizeof(TypeSet);
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
stats->scriptSets += script->types.typeArray[i].dynamicSize();
|
||||
|
||||
TypeIntermediate *intermediate = script->types.intermediateList;
|
||||
while (intermediate) {
|
||||
stats->scriptMain += intermediate->allocatedSize();
|
||||
intermediate = intermediate->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::getTypeInferenceMemoryStats(TypeInferenceMemoryStats *stats)
|
||||
{
|
||||
GetObjectListMemoryStats(types.objects, stats);
|
||||
|
||||
for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
|
||||
JSScript *script = reinterpret_cast<JSScript *>(cursor);
|
||||
GetScriptMemoryStats(script, stats);
|
||||
}
|
||||
|
||||
stats->poolMain += ArenaAllocatedSize(pool);
|
||||
}
|
||||
|
@ -209,6 +209,8 @@ public:
|
||||
* of any script.
|
||||
*/
|
||||
virtual TypeObject * persistentObject() { return NULL; }
|
||||
|
||||
virtual size_t allocatedSize() { return 0; }
|
||||
};
|
||||
|
||||
/* Coarse flags for the contents of a type set. */
|
||||
@ -313,6 +315,7 @@ class TypeSet
|
||||
void print(JSContext *cx);
|
||||
|
||||
inline void destroy(JSContext *cx);
|
||||
size_t dynamicSize();
|
||||
|
||||
/* Whether this set contains a specific type. */
|
||||
inline bool hasType(jstype type);
|
||||
@ -487,6 +490,8 @@ class TypeIntermediate
|
||||
|
||||
/* Whether this subsumes a dynamic type pushed by the bytecode at offset. */
|
||||
virtual bool hasDynamicResult(uint32 offset, jstype type) { return false; }
|
||||
|
||||
virtual size_t allocatedSize() = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1348,6 +1348,7 @@ private:
|
||||
PRInt64 tjitDataAllocatorsMain;
|
||||
PRInt64 tjitDataAllocatorsReserve;
|
||||
#endif
|
||||
JSCompartment::TypeInferenceMemoryStats typeInferenceMemory;
|
||||
};
|
||||
|
||||
struct IterateData
|
||||
@ -1428,6 +1429,13 @@ private:
|
||||
: 0;
|
||||
}
|
||||
|
||||
static void
|
||||
GetCompartmentTypeInferenceMemorySize(JSCompartment *c,
|
||||
JSCompartment::TypeInferenceMemoryStats *stats)
|
||||
{
|
||||
c->getTypeInferenceMemoryStats(stats);
|
||||
}
|
||||
|
||||
#endif // JS_TRACER
|
||||
|
||||
static void
|
||||
@ -1451,6 +1459,7 @@ private:
|
||||
curr->tjitDataAllocatorsMain = GetCompartmentTjitDataAllocatorsMainSize(compartment);
|
||||
curr->tjitDataAllocatorsReserve = GetCompartmentTjitDataAllocatorsReserveSize(compartment);
|
||||
#endif
|
||||
GetCompartmentTypeInferenceMemorySize(compartment, &curr->typeInferenceMemory);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1638,6 +1647,34 @@ public:
|
||||
"Memory used by the trace JIT and held in reserve for VMAllocators "
|
||||
"in case of OOM.");
|
||||
#endif
|
||||
|
||||
DO(mkPath(name, "type-inference/script-main"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats->typeInferenceMemory.scriptMain,
|
||||
"Memory used during type inference to store type sets of variables "
|
||||
"and dynamically observed types.");
|
||||
|
||||
DO(mkPath(name, "type-inference/script-typesets"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats->typeInferenceMemory.scriptSets,
|
||||
"Memory used during type inference to hold the contents of type "
|
||||
"sets associated with scripts.");
|
||||
|
||||
DO(mkPath(name, "type-inference/object-main"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats->typeInferenceMemory.objectMain,
|
||||
"Memory used during type inference to store types and possible "
|
||||
"property types of JS objects.");
|
||||
|
||||
DO(mkPath(name, "type-inference/object-typesets"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats->typeInferenceMemory.objectSets,
|
||||
"Memory used during type inference to hold the contents of type "
|
||||
"sets associated with objects.");
|
||||
|
||||
/*
|
||||
* This is in a different category from the rest of type inference
|
||||
* data as this can be large but is volatile and cleared on GC.
|
||||
*/
|
||||
DO(mkPath(name, "type-inference-pools"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats->typeInferenceMemory.poolMain,
|
||||
"Memory used during type inference to hold transient analysis information.");
|
||||
}
|
||||
|
||||
JS_ASSERT(gcHeapChunkTotal % js::GC_CHUNK_SIZE == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user