diff memory_profiler.cpp @ 60:4bafda49e56e

Modified get GC roots to work w/ things other than just objects.
author Atul Varma <varmaa@toolness.com>
date Thu, 25 Jun 2009 00:21:19 -0700
parents ab600a5e6516
children 44849dbd9017
line wrap: on
line diff
--- a/memory_profiler.cpp	Wed Jun 24 22:10:57 2009 -0700
+++ b/memory_profiler.cpp	Thu Jun 25 00:21:19 2009 -0700
@@ -112,24 +112,6 @@
   }
 }
 
-static intN countRoots(void *rp, const char *name, void *data)
-{
-  return JS_MAP_GCROOT_NEXT;
-}
-
-static intN rootMapFun(void *rp, const char *name, void *data)
-{
-  jsval **currIndex = (jsval **) data;
-
-  // TODO: This will only work if the gcthing is a pointer to a JSObject
-  // pointer.
-
-  JSObject **obj = (JSObject **) rp;
-  **currIndex = INT_TO_JSVAL((unsigned int) *obj);
-  *currIndex++;
-  return JS_MAP_GCROOT_NEXT;
-}
-
 static JSBool getChildrenInfo(JSContext *cx, JSObject *info,
                               JSObject *target, JSContext *targetCx)
 {
@@ -228,22 +210,48 @@
   return JS_TRUE;
 }
 
+typedef struct RootMapStruct {
+  JSBool rval;
+  int length;
+  JSContext *cx;
+  JSObject *array;
+};
+
+static intN rootMapFun(void *rp, const char *name, void *data)
+{
+  jsval **val = (jsval **) rp;
+  if (JSVAL_IS_OBJECT(**val)) {
+    RootMapStruct *roots = (RootMapStruct *) data;
+    jsval id = INT_TO_JSVAL((unsigned int) *val);
+    if (!JS_SetElement(roots->cx, roots->array, roots->length, &id)) {
+      roots->rval = JS_FALSE;
+      return JS_MAP_GCROOT_STOP;
+    }
+    roots->length++;
+  }
+  return JS_MAP_GCROOT_NEXT;
+}
+
 static JSBool getGCRoots(JSContext *cx, JSObject *obj, uintN argc,
                          jsval *argv, jsval *rval)
 {
-  uint32 numRoots = JS_MapGCRoots(tracingState.runtime, countRoots, NULL);
-  jsval rootList[numRoots];
-  jsval *currIndex = rootList;
+  RootMapStruct roots;
+  roots.array = JS_NewArrayObject(cx, 0, NULL);
+  roots.length = 0;
+  roots.rval = JS_TRUE;
+  roots.cx = cx;
 
-  JS_MapGCRoots(tracingState.runtime, rootMapFun, &currIndex);
-
-  JSObject *roots = JS_NewArrayObject(cx, numRoots, rootList);
-  if (roots == NULL) {
+  if (roots.array == NULL) {
     JS_ReportError(cx, "Creating array failed.");
     return JS_FALSE;
   }
 
-  *rval = OBJECT_TO_JSVAL(roots);
+  JS_MapGCRoots(tracingState.runtime, rootMapFun, &roots);
+
+  if (roots.rval == JS_FALSE)
+    return JS_FALSE;
+
+  *rval = OBJECT_TO_JSVAL(roots.array);
   return JS_TRUE;
 }