changeset 51:8750e9ecf3af

Added a getGCRoots() function.
author Atul Varma <varmaa@toolness.com>
date Wed, 24 Jun 2009 17:29:27 -0700
parents 853f80bd3b4b
children a10cb805b5ab
files memory_profiler.cpp memory_profiler_server.js spidermonkey-playground.cpp tcb.js
diffstat 4 files changed, 54 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/memory_profiler.cpp	Wed Jun 24 16:40:51 2009 -0700
+++ b/memory_profiler.cpp	Wed Jun 24 17:29:27 2009 -0700
@@ -50,6 +50,12 @@
 
   // Class to look for.
   JSClass *classp;
+
+  // Runtime that we're tracing.
+  JSRuntime *runtime;
+
+  // Structure required to use JS tracing functions.
+  JSTracer tracer;
 };
 
 // Static singleton for tracking the state of tracing the JS heap.
@@ -87,17 +93,48 @@
   }
 }
 
+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;
+  **currIndex = INT_TO_JSVAL((unsigned int) rp);
+  *currIndex++;
+  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;
+
+  JS_MapGCRoots(tracingState.runtime, rootMapFun, &currIndex);
+
+  JSObject *roots = JS_NewArrayObject(cx, numRoots, rootList);
+  if (roots == NULL) {
+    JS_ReportError(cx, "Creating array failed.");
+    return JS_FALSE;
+  }
+
+  *rval = OBJECT_TO_JSVAL(roots);
+  return JS_TRUE;
+}
+
 static JSFunctionSpec server_global_functions[] = {
   JS_FS("print",          print,              1, 0, 0),
   JS_FS("ServerSocket",   createServerSocket, 0, 0, 0),
+  JS_FS("getGCRoots",     getGCRoots,         0, 0, 0),
   JS_FS_END
 };
 
 JSBool profileMemory(JSContext *cx, JSObject *obj, uintN argc,
                      jsval *argv, jsval *rval)
 {
-  JSTracer tracer;
-
   if (!JS_DHashTableInit(&tracingState.visited, JS_DHashGetStubOps(),
                          NULL, sizeof(JSDHashEntryStub),
                          JS_DHASH_DEFAULT_CAPACITY(100))) {
@@ -105,18 +142,18 @@
     return JS_FALSE;
   }
 
+  tracingState.runtime = JS_GetRuntime(cx);
   tracingState.result = JS_TRUE;
-  tracer.context = cx;
-  tracer.callback = traceCallback;
-  JS_TraceRuntime(&tracer);
+  tracingState.tracer.context = cx;
+  tracingState.tracer.callback = traceCallback;
+  JS_TraceRuntime(&tracingState.tracer);
 
   JS_DHashTableFinish(&tracingState.visited);
 
   if (!tracingState.result)
     return JS_FALSE;
 
-  JSRuntime *serverRuntime;
-  serverRuntime = JS_NewRuntime(8L * 1024L * 1024L);
+  JSRuntime *serverRuntime = JS_NewRuntime(8L * 1024L * 1024L);
   if (serverRuntime == NULL) {
     JS_ReportError(cx, "Couldn't create server JS runtime.");
     return JS_FALSE;
--- a/memory_profiler_server.js	Wed Jun 24 16:40:51 2009 -0700
+++ b/memory_profiler_server.js	Wed Jun 24 17:29:27 2009 -0700
@@ -1,3 +1,5 @@
+print("roots are " + getGCRoots());
+
 var socket = new ServerSocket();
 
 var PORT = 8080;
--- a/spidermonkey-playground.cpp	Wed Jun 24 16:40:51 2009 -0700
+++ b/spidermonkey-playground.cpp	Wed Jun 24 17:29:27 2009 -0700
@@ -416,6 +416,8 @@
   if (tcb_global == NULL)
     return 1;
 
+  JS_AddNamedRoot(tcb_cx, tcb_global, "TCB Global");
+
   /* Populate the tcb_global object with the standard globals,
      like Object and Array. */
   if (!JS_InitStandardClasses(tcb_cx, tcb_global))
@@ -459,6 +461,7 @@
   }
 
   /* Cleanup. */
+  JS_RemoveRoot(tcb_cx, tcb_global);
   JS_DestroyContext(tcb_cx);
   JS_DestroyRuntime(rt);
   JS_ShutDown();
--- a/tcb.js	Wed Jun 24 16:40:51 2009 -0700
+++ b/tcb.js	Wed Jun 24 17:29:27 2009 -0700
@@ -73,6 +73,11 @@
     print("  " + name + ": " + scopeChain[name]);
 }
 
+// TODO: Once profileMemory() is done, we crash, ever since we added
+// the TCB global as a named root. Probably a GC-related bug in some of the
+// wrapper code.
+profileMemory();
+
 // Load a sample SecurableModule and run some code in it.
 
 function SafeWrapper(object) {
@@ -238,5 +243,3 @@
   var boop = {bind: socket.bind};
   boop.bind("127.0.0.1", 8080);
 } catch (e) {}
-
-profileMemory();