зеркало из https://github.com/mozilla/pjs.git
Bug 720219 (part 1) - Clean up JS object measurement. r=bhackett.
--HG-- extra : rebase_source : ff9aa7da84814e6868fef88b56bcb038389d5fb9
This commit is contained in:
Родитель
698edc274c
Коммит
a4025d40f4
|
@ -101,6 +101,7 @@ struct CompartmentStats
|
|||
int64_t gcHeapXML;
|
||||
|
||||
int64_t objectSlots;
|
||||
int64_t objectElements;
|
||||
int64_t stringChars;
|
||||
int64_t shapesExtraTreeTables;
|
||||
int64_t shapesExtraDictTables;
|
||||
|
|
|
@ -130,7 +130,10 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
|||
} else {
|
||||
curr->gcHeapObjectsNonFunction += thingSize;
|
||||
}
|
||||
curr->objectSlots += obj->dynamicSlotSize(data->mallocSizeOf);
|
||||
size_t slotsSize, elementsSize;
|
||||
obj->sizeOfExcludingThis(data->mallocSizeOf, &slotsSize, &elementsSize);
|
||||
curr->objectSlots += slotsSize;
|
||||
curr->objectElements += elementsSize;
|
||||
break;
|
||||
}
|
||||
case JSTRACE_STRING:
|
||||
|
@ -272,7 +275,8 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
|||
data->gcHeapArenaUnused += stats.gcHeapArenaUnused;
|
||||
data->totalObjects += stats.gcHeapObjectsNonFunction +
|
||||
stats.gcHeapObjectsFunction +
|
||||
stats.objectSlots;
|
||||
stats.objectSlots +
|
||||
stats.objectElements;
|
||||
data->totalShapes += stats.gcHeapShapesTree +
|
||||
stats.gcHeapShapesDict +
|
||||
stats.gcHeapShapesBase +
|
||||
|
|
|
@ -979,7 +979,7 @@ JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
|
|||
JS_PUBLIC_API(size_t)
|
||||
JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return obj->slotsAndStructSize();
|
||||
return obj->computedSizeOfIncludingThis();
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
|
|
@ -3419,7 +3419,7 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
|
|||
* swaps can be performed infallibly.
|
||||
*/
|
||||
|
||||
if (a->structSize() == b->structSize())
|
||||
if (a->sizeOfThis() == b->sizeOfThis())
|
||||
return true;
|
||||
|
||||
/*
|
||||
|
@ -3512,7 +3512,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
|||
JS_ASSERT(a->isFunction() == b->isFunction());
|
||||
|
||||
/* Don't try to swap a JSFunction for a plain function JSObject. */
|
||||
JS_ASSERT_IF(a->isFunction(), a->structSize() == b->structSize());
|
||||
JS_ASSERT_IF(a->isFunction(), a->sizeOfThis() == b->sizeOfThis());
|
||||
|
||||
/*
|
||||
* Regexp guts are more complicated -- we would need to migrate the
|
||||
|
@ -3542,8 +3542,8 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
|||
#endif
|
||||
|
||||
/* Trade the guts of the objects. */
|
||||
const size_t size = a->structSize();
|
||||
if (size == b->structSize()) {
|
||||
const size_t size = a->sizeOfThis();
|
||||
if (size == b->sizeOfThis()) {
|
||||
/*
|
||||
* If the objects are the same size, then we make no assumptions about
|
||||
* whether they have dynamically allocated slots and instead just copy
|
||||
|
@ -4098,7 +4098,7 @@ JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
|
|||
*/
|
||||
JS_ASSERT(newCount < NELEMENTS_LIMIT);
|
||||
|
||||
size_t oldSize = Probes::objectResizeActive() ? slotsAndStructSize() : 0;
|
||||
size_t oldSize = Probes::objectResizeActive() ? computedSizeOfIncludingThis() : 0;
|
||||
size_t newSize = oldSize + (newCount - oldCount) * sizeof(Value);
|
||||
|
||||
/*
|
||||
|
@ -4167,7 +4167,7 @@ JSObject::shrinkSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
|
|||
if (isCall())
|
||||
return;
|
||||
|
||||
size_t oldSize = Probes::objectResizeActive() ? slotsAndStructSize() : 0;
|
||||
size_t oldSize = Probes::objectResizeActive() ? computedSizeOfIncludingThis() : 0;
|
||||
size_t newSize = oldSize - (oldCount - newCount) * sizeof(Value);
|
||||
|
||||
if (newCount == 0) {
|
||||
|
@ -4213,7 +4213,7 @@ JSObject::growElements(JSContext *cx, uintN newcap)
|
|||
uint32_t oldcap = getDenseArrayCapacity();
|
||||
JS_ASSERT(oldcap <= newcap);
|
||||
|
||||
size_t oldSize = Probes::objectResizeActive() ? slotsAndStructSize() : 0;
|
||||
size_t oldSize = Probes::objectResizeActive() ? computedSizeOfIncludingThis() : 0;
|
||||
|
||||
uint32_t nextsize = (oldcap <= CAPACITY_DOUBLING_MAX)
|
||||
? oldcap * 2
|
||||
|
@ -4256,7 +4256,7 @@ JSObject::growElements(JSContext *cx, uintN newcap)
|
|||
Debug_SetValueRangeToCrashOnTouch(elements + initlen, actualCapacity - initlen);
|
||||
|
||||
if (Probes::objectResizeActive())
|
||||
Probes::resizeObject(cx, this, oldSize, slotsAndStructSize());
|
||||
Probes::resizeObject(cx, this, oldSize, computedSizeOfIncludingThis());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4269,7 +4269,7 @@ JSObject::shrinkElements(JSContext *cx, uintN newcap)
|
|||
uint32_t oldcap = getDenseArrayCapacity();
|
||||
JS_ASSERT(newcap <= oldcap);
|
||||
|
||||
size_t oldSize = Probes::objectResizeActive() ? slotsAndStructSize() : 0;
|
||||
size_t oldSize = Probes::objectResizeActive() ? computedSizeOfIncludingThis() : 0;
|
||||
|
||||
/* Don't shrink elements below the minimum capacity. */
|
||||
if (oldcap <= SLOT_CAPACITY_MIN || !hasDynamicElements())
|
||||
|
@ -4288,7 +4288,7 @@ JSObject::shrinkElements(JSContext *cx, uintN newcap)
|
|||
elements = newheader->elements();
|
||||
|
||||
if (Probes::objectResizeActive())
|
||||
Probes::resizeObject(cx, this, oldSize, slotsAndStructSize());
|
||||
Probes::resizeObject(cx, this, oldSize, computedSizeOfIncludingThis());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -669,9 +669,12 @@ struct JSObject : js::gc::Cell
|
|||
|
||||
inline bool hasPropertyTable() const;
|
||||
|
||||
inline size_t structSize() const;
|
||||
inline size_t slotsAndStructSize() const;
|
||||
inline size_t dynamicSlotSize(JSMallocSizeOfFun mallocSizeOf) const;
|
||||
inline size_t sizeOfThis() const;
|
||||
inline size_t computedSizeOfIncludingThis() const;
|
||||
|
||||
/* mallocSizeOf can be NULL, in which case we compute the sizes analytically */
|
||||
inline void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf,
|
||||
size_t *slotsSize, size_t *elementsSize) const;
|
||||
|
||||
inline size_t numFixedSlots() const;
|
||||
|
||||
|
|
|
@ -1199,32 +1199,38 @@ JSObject::hasPropertyTable() const
|
|||
}
|
||||
|
||||
inline size_t
|
||||
JSObject::structSize() const
|
||||
JSObject::sizeOfThis() const
|
||||
{
|
||||
return arenaHeader()->getThingSize();
|
||||
}
|
||||
|
||||
inline size_t
|
||||
JSObject::slotsAndStructSize() const
|
||||
JSObject::computedSizeOfIncludingThis() const
|
||||
{
|
||||
return structSize() + dynamicSlotSize(NULL);
|
||||
size_t slotsSize, elementsSize;
|
||||
sizeOfExcludingThis(NULL, &slotsSize, &elementsSize);
|
||||
return sizeOfThis() + slotsSize + elementsSize;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
JSObject::dynamicSlotSize(JSMallocSizeOfFun mallocSizeOf) const
|
||||
inline void
|
||||
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf,
|
||||
size_t *slotsSize, size_t *elementsSize) const
|
||||
{
|
||||
size_t size = 0;
|
||||
if (hasDynamicSlots()) {
|
||||
size_t bytes = numDynamicSlots() * sizeof(js::Value);
|
||||
size += mallocSizeOf ? mallocSizeOf(slots, bytes) : bytes;
|
||||
size_t computedSize = numDynamicSlots() * sizeof(js::Value);
|
||||
*slotsSize = mallocSizeOf ? mallocSizeOf(slots, computedSize) : computedSize;
|
||||
} else {
|
||||
*slotsSize = 0;
|
||||
}
|
||||
if (hasDynamicElements()) {
|
||||
size_t bytes =
|
||||
size_t computedSize =
|
||||
(js::ObjectElements::VALUES_PER_HEADER +
|
||||
getElementsHeader()->capacity) * sizeof(js::Value);
|
||||
size += mallocSizeOf ? mallocSizeOf(getElementsHeader(), bytes) : bytes;
|
||||
*elementsSize =
|
||||
mallocSizeOf ? mallocSizeOf(getElementsHeader(), computedSize) : computedSize;
|
||||
} else {
|
||||
*elementsSize = 0;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
inline JSBool
|
||||
|
@ -1564,7 +1570,7 @@ NewObjectCache::fill(EntryIndex entry_, Class *clasp, gc::Cell *key, gc::AllocKi
|
|||
entry->key = key;
|
||||
entry->kind = kind;
|
||||
|
||||
entry->nbytes = obj->structSize();
|
||||
entry->nbytes = obj->sizeOfThis();
|
||||
js_memcpy(&entry->templateObject, obj, entry->nbytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ Probes::ETWCreateObject(JSContext *cx, JSObject *obj)
|
|||
|
||||
return EventWriteEvtObjectCreate(script_filename, lineno,
|
||||
ObjectClassname(obj), reinterpret_cast<uint64_t_t>(obj),
|
||||
obj ? obj->slotsAndStructSize() : 0) == ERROR_SUCCESS;
|
||||
obj ? obj->computedSizeOfIncludingThis() : 0) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -1513,6 +1513,13 @@ ReportCompartmentStats(const JS::CompartmentStats &stats,
|
|||
"'gc-heap/objects' instead." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
"object-elements"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.objectElements,
|
||||
"Memory allocated for the compartment's object element arrays, "
|
||||
"which are used to represent indexed object properties." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
"string-chars"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.stringChars,
|
||||
|
|
Загрузка…
Ссылка в новой задаче