Mercurial > spidermonkey-playground
diff memory_profiler.cpp @ 57:1fd63ee398dc
Added some really terrible code that adds a 'children' array property to object info.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Wed, 24 Jun 2009 19:38:05 -0700 |
parents | b36c15de56f6 |
children | 0b66a265df13 |
line wrap: on
line diff
--- a/memory_profiler.cpp Wed Jun 24 18:36:24 2009 -0700 +++ b/memory_profiler.cpp Wed Jun 24 19:38:05 2009 -0700 @@ -49,9 +49,6 @@ // Whether the tracing operation is successful or failed. JSBool result; - // Class to look for. - JSClass *classp; - // Runtime that we're tracing. JSRuntime *runtime; @@ -62,9 +59,32 @@ // Static singleton for tracking the state of tracing the JS heap. static TracingState tracingState; -// JSTraceCallback for heap dumping and other operations. +typedef struct ChildTracingState { + int num; + void **things; + uint32 *kinds; + JSTracer tracer; +}; + +static ChildTracingState childTracingState; -static void traceCallback(JSTracer *trc, void *thing, uint32 kind) +// JSTraceCallback to build a hashtable of children. +static void childCountBuilder(JSTracer *trc, void *thing, uint32 kind) +{ + childTracingState.num++; +} + +// JSTraceCallback to build a hashtable of children. +static void childBuilder(JSTracer *trc, void *thing, uint32 kind) +{ + *childTracingState.kinds = kind; + childTracingState.kinds++; + *childTracingState.things = thing; + childTracingState.things++; +} + +// JSTraceCallback to build a hashtable of existing object references. +static void visitedBuilder(JSTracer *trc, void *thing, uint32 kind) { switch (kind) { case JSTRACE_OBJECT: @@ -105,6 +125,49 @@ return JS_MAP_GCROOT_NEXT; } +static JSBool getChildrenInfo(JSContext *cx, JSObject *info, + JSObject *target, JSContext *targetCx) +{ + childTracingState.tracer.context = targetCx; + childTracingState.tracer.callback = childCountBuilder; + childTracingState.num = 0; + JS_TraceChildren(&childTracingState.tracer, target, JSTRACE_OBJECT); + + void *things[childTracingState.num]; + uint32 kinds[childTracingState.num]; + + childTracingState.things = things; + childTracingState.kinds = kinds; + + childTracingState.tracer.callback = childBuilder; + JS_TraceChildren(&childTracingState.tracer, target, JSTRACE_OBJECT); + + int numObjectChildren = 0; + for (int i = 0; i < childTracingState.num; i++) { + if (kinds[i] == JSTRACE_OBJECT) + numObjectChildren++; + } + + jsval childrenVals[numObjectChildren]; + + int currChild = 0; + for (int i = 0; i < childTracingState.num; i++) { + if (kinds[i] == JSTRACE_OBJECT) { + childrenVals[currChild] = INT_TO_JSVAL((unsigned int) things[i]); + currChild += 1; + } + } + + JSObject *children = JS_NewArrayObject(cx, numObjectChildren, childrenVals); + if (children == NULL) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + return JS_DefineProperty(cx, info, "children", OBJECT_TO_JSVAL(children), + NULL, NULL, JSPROP_ENUMERATE); +} + static JSBool getObjInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -150,6 +213,9 @@ return JS_FALSE; } + if (!getChildrenInfo(cx, info, target, targetCx)) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(info); } else *rval = JSVAL_NULL; @@ -197,7 +263,7 @@ tracingState.runtime = JS_GetRuntime(cx); tracingState.result = JS_TRUE; tracingState.tracer.context = cx; - tracingState.tracer.callback = traceCallback; + tracingState.tracer.callback = visitedBuilder; JS_TraceRuntime(&tracingState.tracer); if (!tracingState.result)