Bug 797821 - Allow compartment privates to be lazily created when using them just for storing about:memory URIs. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Thu, 25 Oct 2012 17:01:07 +0200
changeset 111522 ed27c3a1eca3be9c673adda61cf7f5882239bed7
parent 111521 2a49f864998f02764c6c4f85b30414226e191870
child 111523 baf3468777a0cbae3483d8c528203be6b5fa10ce
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersmrbkap
bugs797821
milestone19.0a1
Bug 797821 - Allow compartment privates to be lazily created when using them just for storing about:memory URIs. r=mrbkap This will allow us to stop making nsXULPrototypeDocument and nsXBLDocumentInfo globals XPConnect globals.
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -208,21 +208,37 @@ ContextCallback(JSContext *cx, unsigned 
                 return false;
         } else if (operation == JSCONTEXT_DESTROY) {
             delete XPCContext::GetXPCContext(cx);
         }
     }
     return true;
 }
 
-xpc::CompartmentPrivate::~CompartmentPrivate()
+namespace xpc {
+
+CompartmentPrivate::~CompartmentPrivate()
 {
     MOZ_COUNT_DTOR(xpc::CompartmentPrivate);
 }
 
+CompartmentPrivate*
+EnsureCompartmentPrivate(JSObject *obj)
+{
+    JSCompartment *c = js::GetObjectCompartment(obj);
+    CompartmentPrivate *priv = GetCompartmentPrivate(c);
+    if (priv)
+        return priv;
+    priv = new CompartmentPrivate();
+    JS_SetCompartmentPrivate(c, priv);
+    return priv;
+}
+
+}
+
 static void
 CompartmentDestroyedCallback(JSFreeOp *fop, JSCompartment *compartment)
 {
     XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
     if (!self)
         return;
     XPCCompartmentSet &set = self->GetCompartmentSet();
 
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1082,18 +1082,18 @@ CreateGlobalObject(JSContext *cx, JSClas
     // Sandboxes and compilation scopes are exceptions. See bug 744034.
     CheckTypeInference(cx, clasp, principal);
 
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "using a principal off the main thread?");
 
     JSObject *global = JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal));
     if (!global)
         return nullptr;
+    EnsureCompartmentPrivate(global);
     JSCompartment *compartment = js::GetObjectCompartment(global);
-    JS_SetCompartmentPrivate(compartment, new xpc::CompartmentPrivate());
 
     XPCCompartmentSet& set = nsXPConnect::GetRuntimeInstance()->GetCompartmentSet();
     if (!set.put(compartment))
         return nullptr;
 
 #ifdef DEBUG
     // Verify that the right trace hook is called. Note that this doesn't
     // work right for wrapped globals, since the tracing situation there is
@@ -2398,32 +2398,24 @@ DumpJSHeap(FILE* file)
     }
     js::DumpHeapComplete(xpc->GetRuntime()->GetJSRuntime(), file);
 }
 
 void
 SetLocationForGlobal(JSObject *global, const nsACString& location)
 {
     MOZ_ASSERT(global);
-
-    CompartmentPrivate *priv = GetCompartmentPrivate(global);
-    MOZ_ASSERT(priv, "No compartment private");
-
-    priv->SetLocation(location);
+    EnsureCompartmentPrivate(global)->SetLocation(location);
 }
 
 void
 SetLocationForGlobal(JSObject *global, nsIURI *locationURI)
 {
     MOZ_ASSERT(global);
-
-    CompartmentPrivate *priv = GetCompartmentPrivate(global);
-    MOZ_ASSERT(priv, "No compartment private");
-
-    priv->SetLocation(locationURI);
+    EnsureCompartmentPrivate(global)->SetLocation(locationURI);
 }
 
 } // namespace xpc
 
 static void
 NoteJSChildGrayWrapperShim(void *data, void *thing)
 {
     TraversalTracer *trc = static_cast<TraversalTracer*>(data);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -4377,16 +4377,19 @@ public:
         locationURI = aLocationURI;
     }
 
 private:
     nsCString location;
     nsCOMPtr<nsIURI> locationURI;
 };
 
+CompartmentPrivate*
+EnsureCompartmentPrivate(JSObject *obj);
+
 inline CompartmentPrivate*
 GetCompartmentPrivate(JSCompartment *compartment)
 {
     MOZ_ASSERT(compartment);
     void *priv = JS_GetCompartmentPrivate(compartment);
     return static_cast<CompartmentPrivate*>(priv);
 }