Bug 1107639 - Use PersistentRooted rather than Add/RemoveRoot API is JSAPI tests r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 23 Jan 2015 10:23:57 +0000
changeset 225287 7427476ad3d406949221f41b5f5ac7bc14ee2d76
parent 225286 b60af7b7317cf2004a0b4c86e634e5dec6961a2d
child 225288 0f9dec52a4bd933efefbb7844dd16ef78d35cdd9
push id54520
push userjcoppeard@mozilla.com
push dateFri, 23 Jan 2015 10:26:00 +0000
treeherdermozilla-inbound@572c6cb0e79c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1107639
milestone38.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 1107639 - Use PersistentRooted rather than Add/RemoveRoot API is JSAPI tests r=terrence
js/src/jsapi-tests/testChromeBuffer.cpp
js/src/jsapi-tests/testNullRoot.cpp
js/src/jsapi-tests/testResolveRecursion.cpp
js/src/jsapi-tests/tests.cpp
js/src/jsapi-tests/tests.h
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -20,18 +20,18 @@ static const JSClass global_class = {
     nullptr,
     nullptr,
     nullptr,
     nullptr,
     nullptr,
     JS_GlobalObjectTraceHook
 };
 
-static JS::Heap<JSObject *> trusted_glob;
-static JS::Heap<JSObject *> trusted_fun;
+static JS::PersistentRootedObject trusted_glob;
+static JS::PersistentRootedObject trusted_fun;
 
 static bool
 CallTrusted(JSContext *cx, unsigned argc, jsval *vp)
 {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
     if (!JS_SaveFrameChain(cx))
         return false;
@@ -45,44 +45,39 @@ CallTrusted(JSContext *cx, unsigned argc
     JS_RestoreFrameChain(cx);
     return ok;
 }
 
 BEGIN_TEST(testChromeBuffer)
 {
     JS_SetTrustedPrincipals(rt, &system_principals);
 
-    trusted_glob = JS_NewGlobalObject(cx, &global_class, &system_principals, JS::FireOnNewGlobalHook);
+    trusted_glob.init(cx, JS_NewGlobalObject(cx, &global_class, &system_principals,
+                                             JS::FireOnNewGlobalHook));
     CHECK(trusted_glob);
 
-    if (!JS::AddNamedObjectRoot(cx, &trusted_glob, "trusted-global"))
-        return false;
-
     JS::RootedFunction fun(cx);
 
     /*
      * Check that, even after untrusted content has exhausted the stack, code
      * compiled with "trusted principals" can run using reserved trusted-only
      * buffer space.
      */
     {
         {
             JSAutoCompartment ac(cx, trusted_glob);
             const char *paramName = "x";
             const char *bytes = "return x ? 1 + trusted(x-1) : 0";
-            JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
             JS::AutoObjectVector emptyScopeChain(cx);
             CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
                                       1, &paramName, bytes, strlen(bytes), &fun));
-            CHECK(JS_DefineProperty(cx, global, "trusted", fun, JSPROP_ENUMERATE));
-            trusted_fun = JS_GetFunctionObject(fun);
-            if (!JS::AddNamedObjectRoot(cx, &trusted_fun, "trusted-function"))
-                return false;
+            CHECK(JS_DefineProperty(cx, trusted_glob, "trusted", fun, JSPROP_ENUMERATE));
+            trusted_fun.init(cx, JS_GetFunctionObject(fun));
         }
 
         JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
         CHECK(JS_WrapValue(cx, &v));
 
         const char *paramName = "trusted";
         const char *bytes = "try {                                      "
                             "    return untrusted(trusted);             "
@@ -118,23 +113,22 @@ BEGIN_TEST(testChromeBuffer)
                                 "} catch (e) {                          "
                                 "  /*                                   "
                                 "   * Careful!  We must not reenter JS  "
                                 "   * that might try to push a frame.   "
                                 "   */                                  "
                                 "  return 'From trusted: ' +            "
                                 "         e.name + ': ' + e.message;    "
                                 "}                                      ";
-            JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
             JS::AutoObjectVector emptyScopeChain(cx);
             CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
                                       1, &paramName, bytes, strlen(bytes), &fun));
-            CHECK(JS_DefineProperty(cx, global, "trusted", fun, JSPROP_ENUMERATE));
+            CHECK(JS_DefineProperty(cx, trusted_glob, "trusted", fun, JSPROP_ENUMERATE));
             trusted_fun = JS_GetFunctionObject(fun);
         }
 
         JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
         CHECK(JS_WrapValue(cx, &v));
 
         const char *paramName = "trusted";
         const char *bytes = "try {                                      "
@@ -159,23 +153,22 @@ BEGIN_TEST(testChromeBuffer)
     /*
      * Check that JS_SaveFrameChain called on the way from content to chrome
      * (say, as done by XPCJSContextSTack::Push) works.
      */
     {
         {
             JSAutoCompartment ac(cx, trusted_glob);
             const char *bytes = "return 42";
-            JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
             JS::AutoObjectVector emptyScopeChain(cx);
             CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
                                       0, nullptr, bytes, strlen(bytes), &fun));
-            CHECK(JS_DefineProperty(cx, global, "trusted", fun, JSPROP_ENUMERATE));
+            CHECK(JS_DefineProperty(cx, trusted_glob, "trusted", fun, JSPROP_ENUMERATE));
             trusted_fun = JS_GetFunctionObject(fun);
         }
 
         JS::RootedFunction fun(cx, JS_NewFunction(cx, CallTrusted, 0, 0, global, "callTrusted"));
         JS::RootedObject callTrusted(cx, JS_GetFunctionObject(fun));
 
         const char *paramName = "f";
         const char *bytes = "try {                                      "
@@ -193,16 +186,9 @@ BEGIN_TEST(testChromeBuffer)
         JS::RootedValue arg(cx, JS::ObjectValue(*callTrusted));
         JS::RootedValue rval(cx);
         CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, JS::HandleValueArray(arg), &rval));
         CHECK(rval.toInt32() == 42);
     }
 
     return true;
 }
-virtual void uninit() MOZ_OVERRIDE {
-    trusted_glob = nullptr;
-    trusted_fun = nullptr;
-    JS::RemoveObjectRoot(cx, &trusted_glob);
-    JS::RemoveObjectRoot(cx, &trusted_fun);
-    JSAPITest::uninit();
-}
 END_TEST(testChromeBuffer)
--- a/js/src/jsapi-tests/testNullRoot.cpp
+++ b/js/src/jsapi-tests/testNullRoot.cpp
@@ -4,30 +4,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testNullRoot)
 {
-    obj = nullptr;
-    CHECK(JS::AddObjectRoot(cx, &obj));
-
-    str = nullptr;
-    CHECK(JS::AddStringRoot(cx, &str));
-
-    script = nullptr;
-    CHECK(JS::AddNamedScriptRoot(cx, &script, "testNullRoot's script"));
+    obj.init(cx, nullptr);
+    str.init(cx, nullptr);
+    script.init(cx, nullptr);
 
     // This used to crash because obj was nullptr.
     JS_GC(cx->runtime());
 
-    JS::RemoveObjectRoot(cx, &obj);
-    JS::RemoveStringRoot(cx, &str);
-    JS::RemoveScriptRoot(cx, &script);
     return true;
 }
 
-JS::Heap<JSObject *> obj;
-JS::Heap<JSString *> str;
-JS::Heap<JSScript *> script;
+JS::PersistentRootedObject obj;
+JS::PersistentRootedString str;
+JS::PersistentRootedScript script;
 END_TEST(testNullRoot)
--- a/js/src/jsapi-tests/testResolveRecursion.cpp
+++ b/js/src/jsapi-tests/testResolveRecursion.cpp
@@ -20,23 +20,19 @@ BEGIN_TEST(testResolveRecursion)
         nullptr, // add
         nullptr, // delete
         nullptr, // get
         nullptr, // set
         nullptr, // enumerate
         my_resolve
     };
 
-    obj1 = obj2 = nullptr;
-    JS::AddObjectRoot(cx, &obj1);
-    JS::AddObjectRoot(cx, &obj2);
-
-    obj1 = JS_NewObject(cx, &my_resolve_class, JS::NullPtr(), JS::NullPtr());
+    obj1.init(cx, JS_NewObject(cx, &my_resolve_class, JS::NullPtr(), JS::NullPtr()));
     CHECK(obj1);
-    obj2 = JS_NewObject(cx, &my_resolve_class, JS::NullPtr(), JS::NullPtr());
+    obj2.init(cx, JS_NewObject(cx, &my_resolve_class, JS::NullPtr(), JS::NullPtr()));
     CHECK(obj2);
     JS_SetPrivate(obj1, this);
     JS_SetPrivate(obj2, this);
 
     JS::RootedValue obj1Val(cx, JS::ObjectValue(*obj1));
     JS::RootedValue obj2Val(cx, JS::ObjectValue(*obj2));
     CHECK(JS_DefineProperty(cx, global, "obj1", obj1Val, 0));
     CHECK(JS_DefineProperty(cx, global, "obj2", obj2Val, 0));
@@ -48,23 +44,21 @@ BEGIN_TEST(testResolveRecursion)
     JS::RootedValue v(cx);
     EVAL("obj1.x", &v);
     CHECK_SAME(v, JSVAL_FALSE);
     CHECK_EQUAL(resolveEntryCount, 4);
     CHECK_EQUAL(resolveExitCount, 4);
 
     obj1 = nullptr;
     obj2 = nullptr;
-    JS::RemoveObjectRoot(cx, &obj1);
-    JS::RemoveObjectRoot(cx, &obj2);
     return true;
 }
 
-JS::Heap<JSObject *> obj1;
-JS::Heap<JSObject *> obj2;
+JS::PersistentRootedObject obj1;
+JS::PersistentRootedObject obj2;
 int resolveEntryCount;
 int resolveExitCount;
 
 struct AutoIncrCounters {
 
     explicit AutoIncrCounters(cls_testResolveRecursion *t) : t(t) {
         t->resolveEntryCount++;
     }
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -16,89 +16,83 @@ bool JSAPITest::init()
 {
     rt = createRuntime();
     if (!rt)
         return false;
     cx = createContext();
     if (!cx)
         return false;
     JS_BeginRequest(cx);
-    JS::RootedObject global(cx, createGlobal());
+    global.init(rt);
+    createGlobal();
     if (!global)
         return false;
     JS_EnterCompartment(cx, global);
     return true;
 }
 
 void JSAPITest::uninit()
 {
     if (oldCompartment) {
         JS_LeaveCompartment(cx, oldCompartment);
         oldCompartment = nullptr;
     }
     if (global) {
         JS_LeaveCompartment(cx, nullptr);
-        JS::RemoveObjectRoot(cx, &global);
         global = nullptr;
     }
     if (cx) {
         JS_EndRequest(cx);
         JS_DestroyContext(cx);
         cx = nullptr;
     }
     if (rt) {
         destroyRuntime();
         rt = nullptr;
     }
 }
 
 bool JSAPITest::exec(const char *bytes, const char *filename, int lineno)
 {
     JS::RootedValue v(cx);
-    JS::HandleObject global = JS::HandleObject::fromMarkedLocation(this->global.unsafeGet());
     JS::CompileOptions opts(cx);
     opts.setFileAndLine(filename, lineno);
     return JS::Evaluate(cx, global, opts, bytes, strlen(bytes), &v) ||
         fail(JSAPITestString(bytes), filename, lineno);
 }
 
 bool JSAPITest::evaluate(const char *bytes, const char *filename, int lineno,
                          JS::MutableHandleValue vp)
 {
-    JS::HandleObject global = JS::HandleObject::fromMarkedLocation(this->global.unsafeGet());
     JS::CompileOptions opts(cx);
     opts.setFileAndLine(filename, lineno);
     return JS::Evaluate(cx, global, opts, bytes, strlen(bytes), vp) ||
         fail(JSAPITestString(bytes), filename, lineno);
 }
 
 bool JSAPITest::definePrint()
 {
-    JS::HandleObject global = JS::HandleObject::fromMarkedLocation(this->global.unsafeGet());
     return JS_DefineFunction(cx, global, "print", (JSNative) print, 0, 0);
 }
 
 JSObject * JSAPITest::createGlobal(JSPrincipals *principals)
 {
     /* Create the global object. */
     JS::CompartmentOptions options;
     options.setVersion(JSVERSION_LATEST);
     global = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook, options);
     if (!global)
         return nullptr;
-    JS::AddNamedObjectRoot(cx, &global, "test-global");
-    JS::HandleObject globalHandle = JS::HandleObject::fromMarkedLocation(global.unsafeGet());
-    JSAutoCompartment ac(cx, globalHandle);
+
+    JSAutoCompartment ac(cx, global);
 
     /* Populate the global object with the standard globals, like Object and
        Array. */
-    if (!JS_InitStandardClasses(cx, globalHandle)) {
+    if (!JS_InitStandardClasses(cx, global))
         global = nullptr;
-        JS::RemoveObjectRoot(cx, &global);
-    }
 
     return global;
 }
 
 int main(int argc, char *argv[])
 {
     int total = 0;
     int failures = 0;
@@ -119,18 +113,17 @@ int main(int argc, char *argv[])
         printf("%s\n", name);
         if (!test->init()) {
             printf("TEST-UNEXPECTED-FAIL | %s | Failed to initialize.\n", name);
             failures++;
             test->uninit();
             continue;
         }
 
-        JS::HandleObject global = JS::HandleObject::fromMarkedLocation(test->global.unsafeGet());
-        if (test->run(global)) {
+        if (test->run(test->global)) {
             printf("TEST-PASS | %s | ok\n", name);
         } else {
             JSAPITestString messages = test->messages();
             printf("%s | %s | %.*s\n",
                    (test->knownFail ? "TEST-KNOWN-FAIL" : "TEST-UNEXPECTED-FAIL"),
                    name, (int) messages.length(), messages.begin());
             if (!test->knownFail)
                 failures++;
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -51,23 +51,22 @@ inline JSAPITestString operator+(JSAPITe
 class JSAPITest
 {
   public:
     static JSAPITest *list;
     JSAPITest *next;
 
     JSRuntime *rt;
     JSContext *cx;
-    JS::Heap<JSObject *> global;
+    JS::PersistentRootedObject global;
     bool knownFail;
     JSAPITestString msgs;
     JSCompartment *oldCompartment;
 
-    JSAPITest() : rt(nullptr), cx(nullptr), global(nullptr),
-                  knownFail(false), oldCompartment(nullptr) {
+    JSAPITest() : rt(nullptr), cx(nullptr), knownFail(false), oldCompartment(nullptr) {
         next = list;
         list = this;
     }
 
     virtual ~JSAPITest() {
         MOZ_RELEASE_ASSERT(!rt);
         MOZ_RELEASE_ASSERT(!cx);
         MOZ_RELEASE_ASSERT(!global);