Bug 993772 - Introduce a singleton compilation scope. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Sun, 20 Apr 2014 11:48:13 -0700
changeset 179771 d8be02486b860f9218bbef870a209eba01fb38ec
parent 179770 64e9e6c601b7d911809d8c175def17eea15a6107
child 179772 3c13321cab204019759d46d7962c5e2a744d4e82
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersmrbkap
bugs993772
milestone31.0a1
Bug 993772 - Introduce a singleton compilation scope. r=mrbkap
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -583,16 +583,24 @@ GetJunkScopeGlobal()
     // GetJunkScope would ideally never fail, currently it is not yet the case
     // unfortunately...(see Bug 874158)
     if (!junkScope)
         return nullptr;
     return GetNativeForGlobal(junkScope);
 }
 
 JSObject *
+GetCompilationScope()
+{
+    XPCJSRuntime *self = nsXPConnect::GetRuntimeInstance();
+    NS_ENSURE_TRUE(self, nullptr);
+    return self->GetCompilationScope();
+}
+
+JSObject *
 GetSafeJSContextGlobal()
 {
     return XPCJSRuntime::Get()->GetJSContextStack()->GetSafeJSContextGlobal();
 }
 
 nsGlobalWindow*
 WindowOrNull(JSObject *aObj)
 {
@@ -3040,16 +3048,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
    mWrappedJSToReleaseArray(),
    mNativesToReleaseArray(),
    mDoingFinalization(false),
    mVariantRoots(nullptr),
    mWrappedJSRoots(nullptr),
    mObjectHolderRoots(nullptr),
    mWatchdogManager(new WatchdogManager(MOZ_THIS_IN_INITIALIZER_LIST())),
    mJunkScope(MOZ_THIS_IN_INITIALIZER_LIST()->Runtime(), nullptr),
+   mCompilationScope(MOZ_THIS_IN_INITIALIZER_LIST()->Runtime(), nullptr),
    mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite())
 {
     DOM_InitInterfaces();
 
     // these jsids filled in later when we have a JSContext to work with.
     mStrIDs[0] = JSID_VOID;
 
     MOZ_ASSERT(Runtime());
@@ -3471,23 +3480,42 @@ XPCJSRuntime::RemoveContextCallback(xpcC
 }
 
 JSObject *
 XPCJSRuntime::GetJunkScope()
 {
     if (!mJunkScope) {
         AutoSafeJSContext cx;
         SandboxOptions options;
-        options.sandboxName.AssignASCII("XPConnect Junk Compartment");
+        options.sandboxName.AssignLiteral("XPConnect Junk Compartment");
         RootedValue v(cx);
         nsresult rv = CreateSandboxObject(cx, &v, nsContentUtils::GetSystemPrincipal(), options);
         NS_ENSURE_SUCCESS(rv, nullptr);
 
         mJunkScope = js::UncheckedUnwrap(&v.toObject());
     }
     return mJunkScope;
 }
 
+JSObject *
+XPCJSRuntime::GetCompilationScope()
+{
+    if (!mCompilationScope) {
+        AutoSafeJSContext cx;
+        SandboxOptions options;
+        options.sandboxName.AssignLiteral("XPConnect Compilation Compartment");
+        options.invisibleToDebugger = true;
+        RootedValue v(cx);
+        nsresult rv = CreateSandboxObject(cx, &v, /* principal = */ nullptr, options);
+        NS_ENSURE_SUCCESS(rv, nullptr);
+
+        mCompilationScope = js::UncheckedUnwrap(&v.toObject());
+    }
+    return mCompilationScope;
+}
+
+
 void
-XPCJSRuntime::DeleteJunkScope()
+XPCJSRuntime::DeleteSingletonScopes()
 {
     mJunkScope = nullptr;
+    mCompilationScope = nullptr;
 }
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -83,17 +83,17 @@ nsXPConnect::nsXPConnect()
 
     char* reportableEnv = PR_GetEnv("MOZ_REPORT_ALL_JS_EXCEPTIONS");
     if (reportableEnv && *reportableEnv)
         gReportAllJSExceptions = 1;
 }
 
 nsXPConnect::~nsXPConnect()
 {
-    mRuntime->DeleteJunkScope();
+    mRuntime->DeleteSingletonScopes();
     mRuntime->DestroyJSContextStack();
 
     // In order to clean up everything properly, we need to GC twice: once now,
     // to clean anything that can go away on its own (like the Junk Scope, which
     // we unrooted above), and once after forcing a bunch of shutdown in
     // XPConnect, to clean the stuff we forcibly disconnected. The forced
     // shutdown code defaults to leaking in a number of situations, so we can't
     // get by with only the second GC. :-(
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -552,17 +552,18 @@ public:
     static bool InterruptCallback(JSContext *cx);
     static void OutOfMemoryCallback(JSContext *cx);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
 
     JSObject* GetJunkScope();
-    void DeleteJunkScope();
+    JSObject* GetCompilationScope();
+    void DeleteSingletonScopes();
 
     PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
     void OnAfterProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp(); }
 
 private:
     XPCJSRuntime(); // no implementation
     XPCJSRuntime(nsXPConnect* aXPConnect);
 
@@ -593,16 +594,17 @@ private:
     XPCRootSetElem *mVariantRoots;
     XPCRootSetElem *mWrappedJSRoots;
     XPCRootSetElem *mObjectHolderRoots;
     nsTArray<xpcGCCallback> extraGCCallbacks;
     nsTArray<xpcContextCallback> extraContextCallbacks;
     nsRefPtr<WatchdogManager> mWatchdogManager;
     JS::GCSliceCallback mPrevGCSliceCallback;
     JS::PersistentRootedObject mJunkScope;
+    JS::PersistentRootedObject mCompilationScope;
     nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
 
     mozilla::TimeStamp mSlowScriptCheckpoint;
 
 #define XPCCCX_STRING_CACHE_SIZE 2
 
     mozilla::Maybe<nsString> mScratchStrings[XPCCCX_STRING_CACHE_SIZE];
 
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -431,16 +431,24 @@ GetJunkScope();
 /**
  * Returns the native global of the junk scope. See comment of GetJunkScope
  * about the conditions of using it.
  */
 nsIGlobalObject *
 GetJunkScopeGlobal();
 
 /**
+ * Shared compilation scope for XUL prototype documents and XBL
+ * precompilation. This compartment has a null principal. No code may run, and
+ * it is invisible to the debugger.
+ */
+JSObject *
+GetCompilationScope();
+
+/**
  * If |aObj| is a window, returns the associated nsGlobalWindow.
  * Otherwise, returns null.
  */
 nsGlobalWindow*
 WindowOrNull(JSObject *aObj);
 
 /*
  * Returns the dummy global associated with the SafeJSContext. Callers MUST