comparison 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
comparison
equal deleted inserted replaced
56:b36c15de56f6 57:1fd63ee398dc
47 JSDHashTable visited; 47 JSDHashTable visited;
48 48
49 // Whether the tracing operation is successful or failed. 49 // Whether the tracing operation is successful or failed.
50 JSBool result; 50 JSBool result;
51 51
52 // Class to look for.
53 JSClass *classp;
54
55 // Runtime that we're tracing. 52 // Runtime that we're tracing.
56 JSRuntime *runtime; 53 JSRuntime *runtime;
57 54
58 // Structure required to use JS tracing functions. 55 // Structure required to use JS tracing functions.
59 JSTracer tracer; 56 JSTracer tracer;
60 }; 57 };
61 58
62 // Static singleton for tracking the state of tracing the JS heap. 59 // Static singleton for tracking the state of tracing the JS heap.
63 static TracingState tracingState; 60 static TracingState tracingState;
64 61
65 // JSTraceCallback for heap dumping and other operations. 62 typedef struct ChildTracingState {
66 63 int num;
67 static void traceCallback(JSTracer *trc, void *thing, uint32 kind) 64 void **things;
65 uint32 *kinds;
66 JSTracer tracer;
67 };
68
69 static ChildTracingState childTracingState;
70
71 // JSTraceCallback to build a hashtable of children.
72 static void childCountBuilder(JSTracer *trc, void *thing, uint32 kind)
73 {
74 childTracingState.num++;
75 }
76
77 // JSTraceCallback to build a hashtable of children.
78 static void childBuilder(JSTracer *trc, void *thing, uint32 kind)
79 {
80 *childTracingState.kinds = kind;
81 childTracingState.kinds++;
82 *childTracingState.things = thing;
83 childTracingState.things++;
84 }
85
86 // JSTraceCallback to build a hashtable of existing object references.
87 static void visitedBuilder(JSTracer *trc, void *thing, uint32 kind)
68 { 88 {
69 switch (kind) { 89 switch (kind) {
70 case JSTRACE_OBJECT: 90 case JSTRACE_OBJECT:
71 JSDHashEntryStub *entry = (JSDHashEntryStub *) 91 JSDHashEntryStub *entry = (JSDHashEntryStub *)
72 JS_DHashTableOperate(&tracingState.visited, 92 JS_DHashTableOperate(&tracingState.visited,
103 **currIndex = INT_TO_JSVAL((unsigned int) rp); 123 **currIndex = INT_TO_JSVAL((unsigned int) rp);
104 *currIndex++; 124 *currIndex++;
105 return JS_MAP_GCROOT_NEXT; 125 return JS_MAP_GCROOT_NEXT;
106 } 126 }
107 127
128 static JSBool getChildrenInfo(JSContext *cx, JSObject *info,
129 JSObject *target, JSContext *targetCx)
130 {
131 childTracingState.tracer.context = targetCx;
132 childTracingState.tracer.callback = childCountBuilder;
133 childTracingState.num = 0;
134 JS_TraceChildren(&childTracingState.tracer, target, JSTRACE_OBJECT);
135
136 void *things[childTracingState.num];
137 uint32 kinds[childTracingState.num];
138
139 childTracingState.things = things;
140 childTracingState.kinds = kinds;
141
142 childTracingState.tracer.callback = childBuilder;
143 JS_TraceChildren(&childTracingState.tracer, target, JSTRACE_OBJECT);
144
145 int numObjectChildren = 0;
146 for (int i = 0; i < childTracingState.num; i++) {
147 if (kinds[i] == JSTRACE_OBJECT)
148 numObjectChildren++;
149 }
150
151 jsval childrenVals[numObjectChildren];
152
153 int currChild = 0;
154 for (int i = 0; i < childTracingState.num; i++) {
155 if (kinds[i] == JSTRACE_OBJECT) {
156 childrenVals[currChild] = INT_TO_JSVAL((unsigned int) things[i]);
157 currChild += 1;
158 }
159 }
160
161 JSObject *children = JS_NewArrayObject(cx, numObjectChildren, childrenVals);
162 if (children == NULL) {
163 JS_ReportOutOfMemory(cx);
164 return JS_FALSE;
165 }
166
167 return JS_DefineProperty(cx, info, "children", OBJECT_TO_JSVAL(children),
168 NULL, NULL, JSPROP_ENUMERATE);
169 }
170
108 static JSBool getObjInfo(JSContext *cx, JSObject *obj, uintN argc, 171 static JSBool getObjInfo(JSContext *cx, JSObject *obj, uintN argc,
109 jsval *argv, jsval *rval) 172 jsval *argv, jsval *rval)
110 { 173 {
111 uint32 id; 174 uint32 id;
112 175
148 NULL, NULL, JSPROP_ENUMERATE)) { 211 NULL, NULL, JSPROP_ENUMERATE)) {
149 JS_ReportOutOfMemory(cx); 212 JS_ReportOutOfMemory(cx);
150 return JS_FALSE; 213 return JS_FALSE;
151 } 214 }
152 215
216 if (!getChildrenInfo(cx, info, target, targetCx))
217 return JS_FALSE;
218
153 *rval = OBJECT_TO_JSVAL(info); 219 *rval = OBJECT_TO_JSVAL(info);
154 } else 220 } else
155 *rval = JSVAL_NULL; 221 *rval = JSVAL_NULL;
156 222
157 return JS_TRUE; 223 return JS_TRUE;
195 } 261 }
196 262
197 tracingState.runtime = JS_GetRuntime(cx); 263 tracingState.runtime = JS_GetRuntime(cx);
198 tracingState.result = JS_TRUE; 264 tracingState.result = JS_TRUE;
199 tracingState.tracer.context = cx; 265 tracingState.tracer.context = cx;
200 tracingState.tracer.callback = traceCallback; 266 tracingState.tracer.callback = visitedBuilder;
201 JS_TraceRuntime(&tracingState.tracer); 267 JS_TraceRuntime(&tracingState.tracer);
202 268
203 if (!tracingState.result) 269 if (!tracingState.result)
204 return JS_FALSE; 270 return JS_FALSE;
205 271