Skip to content

Commit

Permalink
Bug 731618 - remove JSContext * parameter from heap iteration API. r=…
Browse files Browse the repository at this point in the history
…:Billm
  • Loading branch information
ibukanov committed Feb 29, 2012
1 parent 4a74e7d commit 0db648a
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 176 deletions.
12 changes: 7 additions & 5 deletions dom/workers/WorkerPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1534,11 +1534,13 @@ class CollectRuntimeStatsRunnable : public WorkerControlRunnable
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
JSAutoSuspendRequest asr(aCx);

*mSucceeded = mIsQuick
? JS::GetExplicitNonHeapForRuntime(JS_GetRuntime(aCx), static_cast<int64_t*>(mData), JsWorkerMallocSizeOf)
: JS::CollectRuntimeStats(JS_GetRuntime(aCx), static_cast<JS::RuntimeStats*>(mData));
JSRuntime *rt = JS_GetRuntime(aCx);
if (mIsQuick) {
*static_cast<int64_t*>(mData) = JS::GetExplicitNonHeapForRuntime(rt, JsWorkerMallocSizeOf);
*mSucceeded = true;
} else {
*mSucceeded = JS::CollectRuntimeStats(rt, static_cast<JS::RuntimeStats*>(mData));
}

{
MutexAutoLock lock(mMutex);
Expand Down
7 changes: 3 additions & 4 deletions js/public/MemoryMetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct TypeInferenceSizes
size_t temporary;
};

typedef void* (* GetNameCallback)(JSContext *cx, JSCompartment *c);
typedef void* (* GetNameCallback)(JSRuntime *rt, JSCompartment *c);
typedef void (* DestroyNameCallback)(void *string);

struct CompartmentStats
Expand Down Expand Up @@ -192,9 +192,8 @@ struct RuntimeStats
extern JS_PUBLIC_API(bool)
CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats);

extern JS_PUBLIC_API(bool)
GetExplicitNonHeapForRuntime(JSRuntime *rt, int64_t *amount,
JSMallocSizeOfFun mallocSizeOf);
extern JS_PUBLIC_API(int64_t)
GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf);

#endif /* JS_THREADSAFE */

Expand Down
136 changes: 56 additions & 80 deletions js/src/MemoryMetrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,27 @@ namespace JS {
using namespace js;

static void
StatsCompartmentCallback(JSContext *cx, void *data, JSCompartment *compartment)
StatsCompartmentCallback(JSRuntime *rt, void *data, JSCompartment *compartment)
{
// Append a new CompartmentStats to the vector.
RuntimeStats *rtStats = static_cast<RuntimeStats *>(data);

// CollectRuntimeStats reserves enough space.
MOZ_ALWAYS_TRUE(rtStats->compartmentStatsVector.growBy(1));
CompartmentStats &cStats = rtStats->compartmentStatsVector.back();
cStats.init(rtStats->getNameCb(cx, compartment), rtStats->destroyNameCb);
cStats.init(rtStats->getNameCb(rt, compartment), rtStats->destroyNameCb);
rtStats->currCompartmentStats = &cStats;

// Get the compartment-level numbers.
#ifdef JS_METHODJIT
cStats.mjitCode = compartment->sizeOfMjitCode();
#endif
compartment->sizeOfTypeInferenceData(cx, &cStats.typeInferenceSizes, rtStats->mallocSizeOf);
compartment->sizeOfTypeInferenceData(&cStats.typeInferenceSizes, rtStats->mallocSizeOf);
cStats.shapesCompartmentTables = compartment->sizeOfShapeTable(rtStats->mallocSizeOf);
}

static void
StatsChunkCallback(JSContext *cx, void *data, gc::Chunk *chunk)
StatsChunkCallback(JSRuntime *rt, void *data, gc::Chunk *chunk)
{
// Nb: This function is only called for dirty chunks, which is why we
// increment gcHeapChunkDirtyDecommitted.
Expand All @@ -86,7 +86,7 @@ StatsChunkCallback(JSContext *cx, void *data, gc::Chunk *chunk)
}

static void
StatsArenaCallback(JSContext *cx, void *data, gc::Arena *arena,
StatsArenaCallback(JSRuntime *rt, void *data, gc::Arena *arena,
JSGCTraceKind traceKind, size_t thingSize)
{
RuntimeStats *rtStats = static_cast<RuntimeStats *>(data);
Expand All @@ -103,7 +103,7 @@ StatsArenaCallback(JSContext *cx, void *data, gc::Arena *arena,
}

static void
StatsCellCallback(JSContext *cx, void *data, void *thing, JSGCTraceKind traceKind,
StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKind,
size_t thingSize)
{
RuntimeStats *rtStats = static_cast<RuntimeStats *>(data);
Expand Down Expand Up @@ -183,45 +183,35 @@ StatsCellCallback(JSContext *cx, void *data, void *thing, JSGCTraceKind traceKin
JS_PUBLIC_API(bool)
CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats)
{
JSContext *cx = JS_NewContext(rt, 0);
if (!cx)
if (!rtStats->compartmentStatsVector.reserve(rt->compartments.length()))
return false;

{
JSAutoRequest ar(cx);

if (!rtStats->compartmentStatsVector.reserve(rt->compartments.length()))
return false;

rtStats->gcHeapChunkCleanDecommitted =
rt->gcChunkPool.countCleanDecommittedArenas(rt) * gc::ArenaSize;
rtStats->gcHeapChunkCleanUnused =
size_t(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) * gc::ChunkSize -
rtStats->gcHeapChunkCleanDecommitted;
rtStats->gcHeapChunkTotal =
size_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) * gc::ChunkSize;

IterateCompartmentsArenasCells(cx, rtStats, StatsCompartmentCallback,
StatsArenaCallback, StatsCellCallback);
IterateChunks(cx, rtStats, StatsChunkCallback);

rtStats->runtimeObject = rtStats->mallocSizeOf(rt);

rt->sizeOfExcludingThis(rtStats->mallocSizeOf,
&rtStats->runtimeNormal,
&rtStats->runtimeTemporary,
&rtStats->runtimeRegexpCode,
&rtStats->runtimeStackCommitted,
&rtStats->runtimeGCMarker);

rtStats->runtimeAtomsTable =
rt->atomState.atoms.sizeOfExcludingThis(rtStats->mallocSizeOf);

for (ContextIter acx(rt); !acx.done(); acx.next())
rtStats->runtimeContexts += acx->sizeOfIncludingThis(rtStats->mallocSizeOf);
}

JS_DestroyContextNoGC(cx);

rtStats->gcHeapChunkCleanDecommitted =
rt->gcChunkPool.countCleanDecommittedArenas(rt) * gc::ArenaSize;
rtStats->gcHeapChunkCleanUnused =
size_t(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) * gc::ChunkSize -
rtStats->gcHeapChunkCleanDecommitted;
rtStats->gcHeapChunkTotal =
size_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) * gc::ChunkSize;

IterateCompartmentsArenasCells(rt, rtStats, StatsCompartmentCallback,
StatsArenaCallback, StatsCellCallback);
IterateChunks(rt, rtStats, StatsChunkCallback);

rtStats->runtimeObject = rtStats->mallocSizeOf(rt);

rt->sizeOfExcludingThis(rtStats->mallocSizeOf,
&rtStats->runtimeNormal,
&rtStats->runtimeTemporary,
&rtStats->runtimeRegexpCode,
&rtStats->runtimeStackCommitted,
&rtStats->runtimeGCMarker);

rtStats->runtimeAtomsTable =
rt->atomState.atoms.sizeOfExcludingThis(rtStats->mallocSizeOf);

for (ContextIter acx(rt); !acx.done(); acx.next())
rtStats->runtimeContexts += acx->sizeOfIncludingThis(rtStats->mallocSizeOf);

// This is initialized to all bytes stored in used chunks, and then we
// subtract used space from it each time around the loop.
Expand Down Expand Up @@ -298,51 +288,37 @@ CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats)
}

static void
ExplicitNonHeapCompartmentCallback(JSContext *cx, void *data, JSCompartment *compartment)
ExplicitNonHeapCompartmentCallback(JSRuntime *rt, void *data, JSCompartment *compartment)
{
#ifdef JS_METHODJIT
size_t *n = static_cast<size_t *>(data);
*n += compartment->sizeOfMjitCode();
#endif
}

JS_PUBLIC_API(bool)
GetExplicitNonHeapForRuntime(JSRuntime *rt, int64_t *amount,
JSMallocSizeOfFun mallocSizeOf)
JS_PUBLIC_API(int64_t)
GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf)
{
JSContext *cx = JS_NewContext(rt, 0);
if (!cx)
return false;

// explicit/<compartment>/gc-heap/*
*amount = int64_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) *
gc::ChunkSize;

{
JSAutoRequest ar(cx);

// explicit/<compartment>/mjit-code
size_t n = 0;
JS_IterateCompartments(cx, &n, ExplicitNonHeapCompartmentCallback);
*amount += n;

// explicit/runtime/regexp-code
// explicit/runtime/stack-committed
size_t regexpCode, stackCommitted;
rt->sizeOfExcludingThis(mallocSizeOf,
NULL,
NULL,
&regexpCode,
&stackCommitted,
NULL);

*amount += regexpCode;
*amount += stackCommitted;
}

JS_DestroyContextNoGC(cx);

return true;
size_t n = size_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) * gc::ChunkSize;

// explicit/<compartment>/mjit-code
JS_IterateCompartments(rt, &n, ExplicitNonHeapCompartmentCallback);

// explicit/runtime/regexp-code
// explicit/runtime/stack-committed
size_t regexpCode, stackCommitted;
rt->sizeOfExcludingThis(mallocSizeOf,
NULL,
NULL,
&regexpCode,
&stackCommitted,
NULL);

n += regexpCode;
n += stackCommitted;

return int64_t(n);
}

JS_PUBLIC_API(size_t)
Expand Down
5 changes: 2 additions & 3 deletions js/src/jsapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2685,16 +2685,15 @@ class JS_PUBLIC_API(JSAutoEnterCompartment)
JS_BEGIN_EXTERN_C
#endif

typedef void (*JSIterateCompartmentCallback)(JSContext *cx, void *data,
JSCompartment *compartment);
typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompartment *compartment);

/*
* This function calls |compartmentCallback| on every compartment. Beware that
* there is no guarantee that the compartment will survive after the callback
* returns.
*/
extern JS_PUBLIC_API(void)
JS_IterateCompartments(JSContext *cx, void *data,
JS_IterateCompartments(JSRuntime *rt, void *data,
JSIterateCompartmentCallback compartmentCallback);

extern JS_PUBLIC_API(JSObject *)
Expand Down
8 changes: 4 additions & 4 deletions js/src/jscompartment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,9 +689,9 @@ JSCompartment::updateForDebugMode(JSContext *cx)

/*
* Discard JIT code and bytecode analyses for any scripts that change
* debugMode. This assumes that 'comp' is in the same thread as 'cx'.
* debugMode.
*/
for (gc::CellIter i(cx, this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->debugMode != enabled) {
mjit::ReleaseScriptCode(cx, script);
Expand Down Expand Up @@ -739,7 +739,7 @@ JSCompartment::removeDebuggee(JSContext *cx,
void
JSCompartment::clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler)
{
for (gc::CellIter i(cx, this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasAnyBreakpointsOrStepMode())
script->clearBreakpointsIn(cx, dbg, handler);
Expand All @@ -749,7 +749,7 @@ JSCompartment::clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *ha
void
JSCompartment::clearTraps(JSContext *cx)
{
for (gc::CellIter i(cx, this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasAnyBreakpointsOrStepMode())
script->clearTraps(cx);
Expand Down
3 changes: 1 addition & 2 deletions js/src/jscompartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,7 @@ struct JSCompartment
js::RegExpCompartment regExps;

size_t sizeOfShapeTable(JSMallocSizeOfFun mallocSizeOf);
void sizeOfTypeInferenceData(JSContext *cx, JS::TypeInferenceSizes *stats,
JSMallocSizeOfFun mallocSizeOf);
void sizeOfTypeInferenceData(JS::TypeInferenceSizes *stats, JSMallocSizeOfFun mallocSizeOf);

/*
* Shared scope property tree, and arena-pool for allocating its nodes.
Expand Down
16 changes: 11 additions & 5 deletions js/src/jsdbgapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1629,20 +1629,26 @@ JS_DumpPCCounts(JSContext *cx, JSScript *script)
#endif
}

namespace {

typedef Vector<JSScript *, 0, SystemAllocPolicy> ScriptsToDump;

static void
DumpBytecodeScriptCallback(JSContext *cx, void *data, void *thing,
DumpBytecodeScriptCallback(JSRuntime *rt, void *data, void *thing,
JSGCTraceKind traceKind, size_t thingSize)
{
JS_ASSERT(traceKind == JSTRACE_SCRIPT);
JSScript *script = static_cast<JSScript *>(thing);
reinterpret_cast<Vector<JSScript *> *>(data)->append(script);
static_cast<ScriptsToDump *>(data)->append(script);
}

} /* anonymous namespace */

JS_PUBLIC_API(void)
JS_DumpCompartmentBytecode(JSContext *cx)
{
Vector<JSScript *> scripts(cx);
IterateCells(cx, cx->compartment, gc::FINALIZE_SCRIPT, &scripts, DumpBytecodeScriptCallback);
ScriptsToDump scripts;
IterateCells(cx->runtime, cx->compartment, gc::FINALIZE_SCRIPT, &scripts, DumpBytecodeScriptCallback);

for (size_t i = 0; i < scripts.length(); i++)
JS_DumpBytecode(cx, scripts[i]);
Expand All @@ -1651,7 +1657,7 @@ JS_DumpCompartmentBytecode(JSContext *cx)
JS_PUBLIC_API(void)
JS_DumpCompartmentPCCounts(JSContext *cx)
{
for (CellIter i(cx, cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
for (CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->pcCounters)
JS_DumpPCCounts(cx, script);
Expand Down
Loading

0 comments on commit 0db648a

Please sign in to comment.