Bug 883450 - Assert that we're in a request whenever we create a Rooted<T>. r=terrence
authorBobby Holley <bobbyholley@gmail.com>
Thu, 20 Jun 2013 11:05:34 -0700
changeset 147345 ce7085b63b2b1a50ccfc87c42ba4dfe2c325507d
parent 147344 dd4b059747b807dbc6a2fcb005709291e4da3177
child 147346 1b63312924bae76c548a4b80e8627f963ec7c7ec
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs883450
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 883450 - Assert that we're in a request whenever we create a Rooted<T>. r=terrence
js/public/RootingAPI.h
js/src/jsfriendapi.cpp
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -492,39 +492,50 @@ struct GCMethods<T *>
         JS::HeapCellPostBarrier(reinterpret_cast<js::gc::Cell **>(vp));
     }
     static void relocate(T **vp) {
         JS::HeapCellRelocate(reinterpret_cast<js::gc::Cell **>(vp));
     }
 #endif
 };
 
+#if defined(DEBUG) && defined(JS_THREADSAFE)
+/* This helper allows us to assert that Rooted<T> is scoped within a request. */
+extern JS_PUBLIC_API(bool)
+IsInRequest(JSContext *cx);
+#endif
+
 } /* namespace js */
 
 namespace JS {
 
 /*
  * Local variable of type T whose value is always rooted. This is typically
  * used for local variables, or for non-rooted values being passed to a
  * function that requires a handle, e.g. Foo(Root<T>(cx, x)).
  *
  * If you want to add additional methods to Rooted for a specific
  * specialization, define a RootedBase<T> specialization containing them.
  */
 template <typename T>
 class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
 {
     void init(JSContext *cxArg) {
+        MOZ_ASSERT(cxArg);
+#ifdef JS_THREADSAFE
+        MOZ_ASSERT(js::IsInRequest(cxArg));
+#endif
 #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
         js::ContextFriendFields *cx = js::ContextFriendFields::get(cxArg);
         commonInit(cx->thingGCRooters);
 #endif
     }
 
     void init(js::PerThreadDataFriendFields *pt) {
+        MOZ_ASSERT(pt);
 #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
         commonInit(pt->thingGCRooters);
 #endif
     }
 
   public:
     Rooted(JSContext *cx
            MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -1103,8 +1103,16 @@ js_DefineOwnProperty(JSContext *cx, JSOb
     return DefineOwnProperty(cx, HandleObject(obj), id, descriptor, bp);
 }
 
 JS_FRIEND_API(JSBool)
 js_ReportIsNotFunction(JSContext *cx, const JS::Value& v)
 {
     return ReportIsNotFunction(cx, v);
 }
+
+#if defined(DEBUG) && defined(JS_THREADSAFE)
+JS_PUBLIC_API(bool)
+js::IsInRequest(JSContext *cx)
+{
+    return !!cx->runtime()->requestDepth;
+}
+#endif