Bug 1107639 - Use two phase construction rather than Maybe<PersistentRooted> r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 23 Jan 2015 10:23:57 +0000
changeset 225359 852a970ae0d29218bb5e92ee1d0110a7a06f1aa0
parent 225358 71097bb1ddcc73334d89d83e6e1f1b95f3a87f29
child 225360 de33f69c43fb5a0e9d532e98fccdd5e3ebcaa4fd
push id28159
push userryanvm@gmail.com
push dateFri, 23 Jan 2015 17:30:19 +0000
treeherdermozilla-central@a6bbabebed2f [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 two phase construction rather than Maybe<PersistentRooted> r=terrence
docshell/base/TimelineMarker.h
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
js/src/shell/js.cpp
js/xpconnect/src/XPCShellImpl.cpp
--- a/docshell/base/TimelineMarker.h
+++ b/docshell/base/TimelineMarker.h
@@ -70,31 +70,31 @@ public:
 
   const nsString& GetCause() const
   {
     return mCause;
   }
 
   JSObject* GetStack()
   {
-    if (mStackTrace) {
-      return mStackTrace->get();
+    if (mStackTrace.initialized()) {
+      return mStackTrace;
     }
     return nullptr;
   }
 
 protected:
 
   void CaptureStack()
   {
     JSContext* ctx = nsContentUtils::GetCurrentJSContext();
     if (ctx) {
       JS::RootedObject stack(ctx);
       if (JS::CaptureCurrentStack(ctx, &stack)) {
-        mStackTrace.emplace(ctx, stack.get());
+        mStackTrace.init(ctx, stack.get());
       } else {
         JS_ClearPendingException(ctx);
       }
     }
   }
 
 private:
 
@@ -102,12 +102,12 @@ private:
   TracingMetadata mMetaData;
   DOMHighResTimeStamp mTime;
   nsString mCause;
 
   // While normally it is not a good idea to make a persistent root,
   // in this case changing nsDocShell to participate in cycle
   // collection was deemed too invasive, and the markers are only held
   // here temporarily to boot.
-  mozilla::Maybe<JS::PersistentRooted<JSObject*>> mStackTrace;
+  JS::PersistentRooted<JSObject*> mStackTrace;
 };
 
 #endif /* TimelineMarker_h__ */
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -19,24 +19,24 @@
 #include "nsJSPrincipals.h"
 #include "jswrapper.h"
 
 extern PRLogModuleInfo *MCD;
 using mozilla::AutoSafeJSContext;
 
 //*****************************************************************************
 
-static mozilla::Maybe<JS::PersistentRooted<JSObject *> > autoconfigSb;
+static JS::PersistentRooted<JSObject *> autoconfigSb;
 
 nsresult CentralizedAdminPrefManagerInit()
 {
     nsresult rv;
 
     // If the sandbox is already created, no need to create it again.
-    if (autoconfigSb)
+    if (autoconfigSb.initialized())
         return NS_OK;
 
     // Grab XPConnect.
     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
@@ -48,24 +48,24 @@ nsresult CentralizedAdminPrefManagerInit
     // Create a sandbox.
     AutoSafeJSContext cx;
     nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
     rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(sandbox));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Unwrap, store and root the sandbox.
     NS_ENSURE_STATE(sandbox->GetJSObject());
-    autoconfigSb.emplace(cx, js::UncheckedUnwrap(sandbox->GetJSObject()));
+    autoconfigSb.init(cx, js::UncheckedUnwrap(sandbox->GetJSObject()));
 
     return NS_OK;
 }
 
 nsresult CentralizedAdminPrefManagerFinish()
 {
-    if (autoconfigSb) {
+    if (autoconfigSb.initialized()) {
         AutoSafeJSContext cx;
         autoconfigSb.reset();
         JS_MaybeGC(cx);
     }
     return NS_OK;
 }
 
 nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
@@ -98,19 +98,19 @@ nsresult EvaluateAdminConfigScript(const
 
     // Grab XPConnect.
     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     AutoSafeJSContext cx;
-    JSAutoCompartment ac(cx, *autoconfigSb);
+    JSAutoCompartment ac(cx, autoconfigSb);
 
     nsAutoCString script(js_buffer, length);
     JS::RootedValue v(cx);
     rv = xpc->EvalInSandboxObject(NS_ConvertASCIItoUTF16(script), filename, cx,
-                                  *autoconfigSb, &v);
+                                  autoconfigSb, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -124,17 +124,17 @@ static size_t gMaxStackSize = 128 * size
 
 /*
  * Limit the timeout to 30 minutes to prevent an overflow on platfoms
  * that represent the time internally in microseconds using 32-bit int.
  */
 static double MAX_TIMEOUT_INTERVAL = 1800.0;
 static double gTimeoutInterval = -1.0;
 static volatile bool gServiceInterrupt = false;
-static Maybe<JS::PersistentRootedValue> gInterruptFunc;
+static JS::PersistentRootedValue gInterruptFunc;
 
 static bool enableDisassemblyDumps = false;
 
 static bool printTiming = false;
 static const char *jsCacheDir = nullptr;
 static const char *jsCacheAsmJSPath = nullptr;
 static bool jsCachingEnabled = false;
 mozilla::Atomic<bool> jsCacheOpened(false);
@@ -359,17 +359,17 @@ ShellInterruptCallback(JSContext *cx)
 
     // Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to
     // true to distinguish watchdog or user triggered interrupts.
     // Do this first to prevent other interrupts that may occur while the
     // user-supplied callback is executing from re-entering the handler.
     gServiceInterrupt = false;
 
     bool result;
-    RootedValue interruptFunc(cx, *gInterruptFunc);
+    RootedValue interruptFunc(cx, gInterruptFunc);
     if (!interruptFunc.isNull()) {
         JS::AutoSaveExceptionState savedExc(cx);
         JSAutoCompartment ac(cx, &interruptFunc.toObject());
         RootedValue rval(cx);
         if (!JS_CallFunctionValue(cx, JS::NullPtr(), interruptFunc,
                                   JS::HandleValueArray::empty(), &rval))
         {
             return false;
@@ -3031,17 +3031,17 @@ ScheduleWatchdog(JSRuntime *rt, double t
 }
 
 static void
 CancelExecution(JSRuntime *rt)
 {
     gServiceInterrupt = true;
     JS_RequestInterruptCallback(rt);
 
-    if (!gInterruptFunc->get().isNull()) {
+    if (!gInterruptFunc.isNull()) {
         static const char msg[] = "Script runs for too long, terminating.\n";
         fputs(msg, stderr);
     }
 }
 
 static bool
 SetTimeoutValue(JSContext *cx, double t)
 {
@@ -3078,17 +3078,17 @@ Timeout(JSContext *cx, unsigned argc, Va
         return false;
 
     if (args.length() > 1) {
         RootedValue value(cx, args[1]);
         if (!value.isObject() || !value.toObject().is<JSFunction>()) {
             JS_ReportError(cx, "Second argument must be a timeout function");
             return false;
         }
-        *gInterruptFunc = value;
+        gInterruptFunc = value;
     }
 
     args.rval().setUndefined();
     return SetTimeoutValue(cx, t);
 }
 
 static bool
 InterruptIf(JSContext *cx, unsigned argc, Value *vp)
@@ -3149,17 +3149,17 @@ SetInterruptCallback(JSContext *cx, unsi
         return false;
     }
 
     RootedValue value(cx, args[0]);
     if (!value.isObject() || !value.toObject().is<JSFunction>()) {
         JS_ReportError(cx, "Argument must be a function");
         return false;
     }
-    *gInterruptFunc = value;
+    gInterruptFunc = value;
 
     args.rval().setUndefined();
     return true;
 }
 
 #ifdef DEBUG
 static bool
 StackDump(JSContext *cx, unsigned argc, Value *vp)
@@ -6034,17 +6034,17 @@ main(int argc, char **argv, char **envp)
     if (!rt)
         return 1;
 
     JS_SetErrorReporter(rt, my_ErrorReporter);
     JS::SetOutOfMemoryCallback(rt, my_OOMCallback, nullptr);
     if (!SetRuntimeOptions(rt, op))
         return 1;
 
-    gInterruptFunc.emplace(rt, NullValue());
+    gInterruptFunc.init(rt, NullValue());
 
     JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
     Maybe<JS::AutoDisableGenerationalGC> noggc;
     if (op.getBoolOption("no-ggc"))
         noggc.emplace(rt);
 
     size_t availMem = op.getIntOption("available-memory");
     if (availMem > 0)
@@ -6097,18 +6097,16 @@ main(int argc, char **argv, char **envp)
 #endif
 
     JS::SetLargeAllocationFailureCallback(rt, nullptr, nullptr);
 
     DestroyContext(cx, true);
 
     KillWatchdog();
 
-    gInterruptFunc.reset();
-
     MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
     for (size_t i = 0; i < workerThreads.length(); i++)
         PR_JoinThread(workerThreads[i]);
 
     noggc.reset();
 
     JS_DestroyRuntime(rt);
     JS_ShutDown();
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -565,23 +565,23 @@ Btoa(JSContext *cx, unsigned argc, Value
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!args.length())
         return true;
 
   return xpc::Base64Encode(cx, args[0], args.rval());
 }
 
-static Maybe<PersistentRootedValue> sScriptedInterruptCallback;
+static PersistentRootedValue sScriptedInterruptCallback;
 
 static bool
 XPCShellInterruptCallback(JSContext *cx)
 {
-    MOZ_ASSERT(sScriptedInterruptCallback);
-    RootedValue callback(cx, *sScriptedInterruptCallback);
+    MOZ_ASSERT(sScriptedInterruptCallback.initialized());
+    RootedValue callback(cx, sScriptedInterruptCallback);
 
     // If no interrupt callback was set by script, no-op.
     if (callback.isUndefined())
         return true;
 
     JSAutoCompartment ac(cx, &callback.toObject());
     RootedValue rv(cx);
     if (!JS_CallFunctionValue(cx, JS::NullPtr(), callback, JS::HandleValueArray::empty(), &rv) ||
@@ -593,38 +593,38 @@ XPCShellInterruptCallback(JSContext *cx)
     }
 
     return rv.toBoolean();
 }
 
 static bool
 SetInterruptCallback(JSContext *cx, unsigned argc, jsval *vp)
 {
-    MOZ_ASSERT(sScriptedInterruptCallback);
+    MOZ_ASSERT(sScriptedInterruptCallback.initialized());
 
     // Sanity-check args.
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     if (args.length() != 1) {
         JS_ReportError(cx, "Wrong number of arguments");
         return false;
     }
 
     // Allow callers to remove the interrupt callback by passing undefined.
     if (args[0].isUndefined()) {
-        *sScriptedInterruptCallback = UndefinedValue();
+        sScriptedInterruptCallback = UndefinedValue();
         return true;
     }
 
     // Otherwise, we should have a callable object.
     if (!args[0].isObject() || !JS::IsCallable(&args[0].toObject())) {
         JS_ReportError(cx, "Argument must be callable");
         return false;
     }
 
-    *sScriptedInterruptCallback = args[0];
+    sScriptedInterruptCallback = args[0];
 
     return true;
 }
 
 static bool
 SimulateActivityCallback(JSContext *cx, unsigned argc, jsval *vp)
 {
     // Sanity-check args.
@@ -1385,17 +1385,17 @@ XRE_XPCShellMain(int argc, char **argv, 
         if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) {
             printf("failed to get JSRuntime from nsJSRuntimeService!\n");
             return 1;
         }
 
         // Override the default XPConnect interrupt callback. We could store the
         // old one and restore it before shutting down, but there's not really a
         // reason to bother.
-        sScriptedInterruptCallback.emplace(rt, UndefinedValue());
+        sScriptedInterruptCallback.init(rt, UndefinedValue());
         JS_SetInterruptCallback(rt, XPCShellInterruptCallback);
 
         JS_SetErrorReporter(rt, XPCShellErrorReporter);
 
         dom::AutoJSAPI jsapi;
         jsapi.Init();
         cx = jsapi.cx();
 
@@ -1520,18 +1520,16 @@ XRE_XPCShellMain(int argc, char **argv, 
 
     if (!XRE_ShutdownTestShell())
         NS_ERROR("problem shutting down testshell");
 
     // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
     rv = NS_ShutdownXPCOM( nullptr );
     MOZ_ASSERT(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
 
-    sScriptedInterruptCallback.reset();
-
 #ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
     // test of late call and release (see above)
     JSContext* bogusCX;
     bogus->Peek(&bogusCX);
     bogus = nullptr;
 #endif
 
     appDir = nullptr;