Bug 1533302 part 3 - Use UniquePtr for CompartmentPrivate's XPCWrappedNativeScope. r=mccr8
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 09 Mar 2019 10:44:18 +0000
changeset 521252 ed23415c6ea0
parent 521251 0d7f08e68f75
child 521253 34a3d6b4f10f
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1533302
milestone67.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 1533302 part 3 - Use UniquePtr for CompartmentPrivate's XPCWrappedNativeScope. r=mccr8 `CompartmentPrivate::GetScope()` was added so callers don't have to do `scope.get()` manually. The `scope` field is now private and was renamed to `mScope`. Also replaces some `CompartmentPrivate::Get(obj)->scope` instances with `ObjectScope(obj)`. It's equivalent but shorter. Differential Revision: https://phabricator.services.mozilla.com/D22664
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCMaps.h
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -179,39 +179,37 @@ class AsyncFreeSnowWhite : public Runnab
  public:
   bool mContinuation;
   bool mActive;
   bool mPurge;
 };
 
 namespace xpc {
 
-CompartmentPrivate::CompartmentPrivate(JS::Compartment* c,
-                                       XPCWrappedNativeScope* scope,
-                                       mozilla::BasePrincipal* origin,
-                                       const SiteIdentifier& site)
+CompartmentPrivate::CompartmentPrivate(
+    JS::Compartment* c, mozilla::UniquePtr<XPCWrappedNativeScope> scope,
+    mozilla::BasePrincipal* origin, const SiteIdentifier& site)
     : originInfo(origin, site),
-      scope(scope),
       wantXrays(false),
       allowWaivers(true),
       isWebExtensionContentScript(false),
       allowCPOWs(false),
       isContentXBLCompartment(false),
       isUAWidgetCompartment(false),
       hasExclusiveExpandos(false),
       universalXPConnectEnabled(false),
       wasShutdown(false),
-      mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH)) {
+      mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH)),
+      mScope(std::move(scope)) {
   MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
 }
 
 CompartmentPrivate::~CompartmentPrivate() {
   MOZ_COUNT_DTOR(xpc::CompartmentPrivate);
   delete mWrappedJSMap;
-  delete scope;
 }
 
 void CompartmentPrivate::SystemIsBeingShutDown() {
   // We may call this multiple times when the compartment contains more than one
   // realm.
   if (!wasShutdown) {
     mWrappedJSMap->ShutdownMarker();
     wasShutdown = true;
@@ -239,19 +237,19 @@ void RealmPrivate::Init(HandleObject aGl
 
   nsIPrincipal* principal = GetRealmPrincipal(realm);
   Compartment* c = js::GetObjectCompartment(aGlobal);
 
   // Create the compartment private if needed.
   if (CompartmentPrivate* priv = CompartmentPrivate::Get(c)) {
     MOZ_ASSERT(priv->originInfo.IsSameOrigin(principal));
   } else {
-    auto* scope = new XPCWrappedNativeScope(c, aGlobal);
-    priv =
-        new CompartmentPrivate(c, scope, BasePrincipal::Cast(principal), aSite);
+    auto scope = mozilla::MakeUnique<XPCWrappedNativeScope>(c, aGlobal);
+    priv = new CompartmentPrivate(c, std::move(scope),
+                                  BasePrincipal::Cast(principal), aSite);
     JS_SetCompartmentPrivate(c, priv);
   }
 }
 
 static bool TryParseLocationURICandidate(
     const nsACString& uristr, RealmPrivate::LocationHint aLocationHint,
     nsIURI** aURI) {
   static NS_NAMED_LITERAL_CSTRING(kGRE, "resource://gre/");
@@ -588,20 +586,18 @@ bool EnableUniversalXPConnect(JSContext*
   bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
                                   js::AllCompartments());
   NS_ENSURE_TRUE(ok, false);
 
   // The Components object normally isn't defined for unprivileged web content,
   // but we define it when UniversalXPConnect is enabled to support legacy
   // tests.
   Compartment* comp = js::GetContextCompartment(cx);
-  XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->scope;
-  if (!scope) {
-    return true;
-  }
+  XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->GetScope();
+  MOZ_ASSERT(scope);
   scope->ForcePrivilegedComponents();
   return scope->AttachComponentsObject(cx);
 }
 
 bool CompartmentOriginInfo::IsSameOrigin(nsIPrincipal* aOther) const {
   return mOrigin->FastEquals(aOther);
 }
 
@@ -981,17 +977,17 @@ void XPCJSRuntime::WeakPointerCompartmen
   if (xpcComp) {
     xpcComp->UpdateWeakPointersAfterGC();
   }
 }
 
 void CompartmentPrivate::UpdateWeakPointersAfterGC() {
   mRemoteProxies.sweep();
   mWrappedJSMap->UpdateWeakPointersAfterGC();
-  scope->UpdateWeakPointersAfterGC();
+  mScope->UpdateWeakPointersAfterGC();
 }
 
 void XPCJSRuntime::CustomOutOfMemoryCallback() {
   if (!Preferences::GetBool("memory.dump_reports_on_oom")) {
     return;
   }
 
   nsCOMPtr<nsIMemoryInfoDumper> dumper =
--- a/js/xpconnect/src/XPCMaps.h
+++ b/js/xpconnect/src/XPCMaps.h
@@ -500,18 +500,17 @@ class JSObject2JSObjectMap {
     if (p) {
       JSObject* oldValue = p->value();
       p->value() = value;
       return oldValue;
     }
     if (!mTable.add(p, key, value)) {
       return nullptr;
     }
-    MOZ_ASSERT(xpc::CompartmentPrivate::Get(key)->scope->mWaiverWrapperMap ==
-               this);
+    MOZ_ASSERT(xpc::ObjectScope(key)->mWaiverWrapperMap == this);
     return value;
   }
 
   inline void Remove(JSObject* key) {
     MOZ_ASSERT(key, "bad param");
     mTable.remove(key);
   }
 
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -178,17 +178,17 @@ nsresult XPCWrappedNative::WrapNewGlobal
   aOptions.creationOptions().setTrace(XPCWrappedNative::Trace);
   xpc::SetPrefableRealmOptions(aOptions);
 
   RootedObject global(cx,
                       xpc::CreateGlobalObject(cx, clasp, principal, aOptions));
   if (!global) {
     return NS_ERROR_FAILURE;
   }
-  XPCWrappedNativeScope* scope = CompartmentPrivate::Get(global)->scope;
+  XPCWrappedNativeScope* scope = ObjectScope(global);
 
   // Immediately enter the global's realm, so that everything else we
   // create ends up there.
   JSAutoRealm ar(cx, global);
 
   // If requested, initialize the standard classes on the global.
   if (initStandardClasses && !JS::InitRealmStandardClasses(cx)) {
     return NS_ERROR_FAILURE;
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -212,18 +212,17 @@ bool XPCWrappedNativeScope::AllowContent
                                             xpc::GetRealmPrincipal(aRealm)));
   return mAllowContentXBLScope;
 }
 
 namespace xpc {
 JSObject* GetXBLScope(JSContext* cx, JSObject* contentScopeArg) {
   JS::RootedObject contentScope(cx, contentScopeArg);
   JSAutoRealm ar(cx, contentScope);
-  XPCWrappedNativeScope* nativeScope =
-      CompartmentPrivate::Get(contentScope)->scope;
+  XPCWrappedNativeScope* nativeScope = ObjectScope(contentScope);
 
   RootedObject scope(cx, nativeScope->EnsureContentXBLScope(cx));
   NS_ENSURE_TRUE(scope, nullptr);  // See bug 858642.
 
   scope = js::UncheckedUnwrap(scope);
   JS::ExposeObjectToActiveJS(scope);
   return scope;
 }
@@ -246,17 +245,17 @@ JSObject* GetUAWidgetScope(JSContext* cx
 
   scope = js::UncheckedUnwrap(scope);
   JS::ExposeObjectToActiveJS(scope);
   return scope;
 }
 
 bool AllowContentXBLScope(JS::Realm* realm) {
   JS::Compartment* comp = GetCompartmentForRealm(realm);
-  XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->scope;
+  XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->GetScope();
   MOZ_ASSERT(scope);
   return scope->AllowContentXBLScope(realm);
 }
 
 } /* namespace xpc */
 
 XPCWrappedNativeScope::~XPCWrappedNativeScope() {
   MOZ_COUNT_DTOR(XPCWrappedNativeScope);
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -414,18 +414,18 @@ static inline T UnexpectedFailure(T rv) 
 void xpc::TraceXPCGlobal(JSTracer* trc, JSObject* obj) {
   if (js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL) {
     mozilla::dom::TraceProtoAndIfaceCache(trc, obj);
   }
 
   // We might be called from a GC during the creation of a global, before we've
   // been able to set up the compartment private.
   if (xpc::CompartmentPrivate* priv = xpc::CompartmentPrivate::Get(obj)) {
-    MOZ_ASSERT(priv->scope);
-    priv->scope->TraceInside(trc);
+    MOZ_ASSERT(priv->GetScope());
+    priv->GetScope()->TraceInside(trc);
   }
 }
 
 namespace xpc {
 
 JSObject* CreateGlobalObject(JSContext* cx, const JSClass* clasp,
                              nsIPrincipal* principal,
                              JS::RealmOptions& aOptions) {
@@ -509,18 +509,17 @@ bool InitGlobalObject(JSContext* aJSCont
   // ends up there.
   JSAutoRealm ar(aJSContext, aGlobal);
 
   // Stuff coming through this path always ends up as a DOM global.
   MOZ_ASSERT(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL);
 
   if (!(aFlags & xpc::OMIT_COMPONENTS_OBJECT)) {
     // XPCCallContext gives us an active request needed to save/restore.
-    if (!CompartmentPrivate::Get(aGlobal)->scope->AttachComponentsObject(
-            aJSContext) ||
+    if (!ObjectScope(aGlobal)->AttachComponentsObject(aJSContext) ||
         !XPCNativeWrapper::AttachNewConstructorObject(aJSContext, aGlobal)) {
       return UnexpectedFailure(false);
     }
   }
 
   if (!(aFlags & xpc::DONT_FIRE_ONNEWGLOBALHOOK)) {
     JS_FireOnNewGlobalObject(aJSContext, aGlobal);
   }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2663,17 +2663,18 @@ class CompartmentOriginInfo {
 // compartment. Since compartments are trust domains, this means mostly
 // information needed to select the right security policy for cross-compartment
 // wrappers.
 class CompartmentPrivate {
   CompartmentPrivate() = delete;
   CompartmentPrivate(const CompartmentPrivate&) = delete;
 
  public:
-  CompartmentPrivate(JS::Compartment* c, XPCWrappedNativeScope* scope,
+  CompartmentPrivate(JS::Compartment* c,
+                     mozilla::UniquePtr<XPCWrappedNativeScope> scope,
                      mozilla::BasePrincipal* origin,
                      const mozilla::SiteIdentifier& site);
 
   ~CompartmentPrivate();
 
   static CompartmentPrivate* Get(JS::Compartment* compartment) {
     MOZ_ASSERT(compartment);
     void* priv = JS_GetCompartmentPrivate(compartment);
@@ -2695,24 +2696,22 @@ class CompartmentPrivate {
     // Only share if we're same-origin with the principal.
     if (!originInfo.IsSameOrigin(principal)) {
       return false;
     }
 
     // Don't share if we have any weird state set.
     return !wantXrays && !isWebExtensionContentScript &&
            !isContentXBLCompartment && !isUAWidgetCompartment &&
-           !universalXPConnectEnabled && scope->XBLScopeStateMatches(principal);
+           !universalXPConnectEnabled &&
+           mScope->XBLScopeStateMatches(principal);
   }
 
   CompartmentOriginInfo originInfo;
 
-  // Our XPCWrappedNativeScope.
-  XPCWrappedNativeScope* scope;
-
   // Controls whether this compartment gets Xrays to same-origin. This behavior
   // is deprecated, but is still the default for sandboxes for compatibity
   // reasons.
   bool wantXrays;
 
   // Controls whether this compartment is allowed to waive Xrays to content
   // that it subsumes. This should generally be true, except in cases where we
   // want to prevent code from depending on Xray Waivers (which might make it
@@ -2766,22 +2765,27 @@ class CompartmentPrivate {
   };
 
   typedef JS::GCHashMap<const void*, JS::Heap<JSObject*>,
                         mozilla::PointerHasher<const void*>,
                         js::SystemAllocPolicy, SweepPolicy>
       RemoteProxyMap;
   RemoteProxyMap& GetRemoteProxyMap() { return mRemoteProxies; }
 
+  XPCWrappedNativeScope* GetScope() { return mScope.get(); }
+
  private:
   JSObject2WrappedJSMap* mWrappedJSMap;
 
   // Cache holding proxy objects for Window objects (and their Location oject)
   // that are loaded in a different process.
   RemoteProxyMap mRemoteProxies;
+
+  // Our XPCWrappedNativeScope.
+  mozilla::UniquePtr<XPCWrappedNativeScope> mScope;
 };
 
 bool IsUniversalXPConnectEnabled(JS::Compartment* compartment);
 bool IsUniversalXPConnectEnabled(JSContext* cx);
 bool EnableUniversalXPConnect(JSContext* cx);
 
 inline void CrashIfNotInAutomation() { MOZ_RELEASE_ASSERT(IsInAutomation()); }
 
@@ -2891,17 +2895,17 @@ class RealmPrivate {
   nsCOMPtr<nsIURI> locationURI;
 
   bool TryParseLocationURI(LocationHint aType, nsIURI** aURI);
 
   nsTHashtable<nsPtrHashKey<JSStackFrameBase>> mJSStackFrames;
 };
 
 inline XPCWrappedNativeScope* ObjectScope(JSObject* obj) {
-  return CompartmentPrivate::Get(obj)->scope;
+  return CompartmentPrivate::Get(obj)->GetScope();
 }
 
 JSObject* NewOutObject(JSContext* cx);
 bool IsOutObject(JSContext* cx, JSObject* obj);
 
 nsresult HasInstance(JSContext* cx, JS::HandleObject objArg, const nsID* iid,
                      bool* bp);