Bug 1316683 - Avoid going into SpiderMonkey for retrieving origin attributes; r=baku
☠☠ backed out by 2857884dea0e ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 18 Mar 2017 16:08:12 -0400
changeset 396804 fecc6abcf708eb09f5af40f50ad0a825842e43a1
parent 396803 3ec06476d7306e8a12f6ee4f56472948a3c114d6
child 396805 6f4a9281e405bd8e072f9d1ccef91b1523077e14
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1316683
milestone55.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 1316683 - Avoid going into SpiderMonkey for retrieving origin attributes; r=baku Our caller is C++ code, and the implementations are all also written in C++, so there is no reason to go through SpiderMonkey here. This patch also makes nsILoadContext builtinclass to ensure that the implementation is always native.
docshell/base/LoadContext.cpp
docshell/base/LoadContext.h
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsILoadContext.idl
dom/base/nsDocument.h
dom/ipc/TabParent.cpp
uriloader/prefetch/OfflineCacheUpdateParent.cpp
uriloader/prefetch/OfflineCacheUpdateParent.h
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -7,40 +7,16 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ScriptSettings.h" // for AutoJSAPI
 #include "nsContentUtils.h"
 #include "xpcpublic.h"
 
-bool
-nsILoadContext::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
-{
-  mozilla::dom::AutoJSAPI jsapi;
-  bool ok = jsapi.Init(xpc::PrivilegedJunkScope());
-  NS_ENSURE_TRUE(ok, false);
-  JS::Rooted<JS::Value> v(jsapi.cx());
-  nsresult rv = GetOriginAttributes(&v);
-  NS_ENSURE_SUCCESS(rv, false);
-  NS_ENSURE_TRUE(v.isObject(), false);
-  JS::Rooted<JSObject*> obj(jsapi.cx(), &v.toObject());
-
-  // If we're JS-implemented, the object will be left in a different (System-Principaled)
-  // scope, so we may need to enter its compartment.
-  MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj)));
-  JSAutoCompartment ac(jsapi.cx(), obj);
-
-  mozilla::OriginAttributes attrs;
-  ok = attrs.Init(jsapi.cx(), v);
-  NS_ENSURE_TRUE(ok, false);
-  aAttrs = attrs;
-  return true;
-}
-
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor)
 
 LoadContext::LoadContext(nsIPrincipal* aPrincipal,
                          nsILoadContext* aOptionalBase)
   : mTopFrameElement(nullptr)
   , mNestedFrameId(0)
@@ -176,16 +152,22 @@ LoadContext::GetOriginAttributes(JS::Mut
   JSContext* cx = nsContentUtils::GetCurrentJSContext();
   MOZ_ASSERT(cx);
 
   bool ok = ToJSValue(cx, mOriginAttributes, aAttrs);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
+NS_IMETHODIMP_(void)
+LoadContext::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
+{
+  aAttrs = mOriginAttributes;
+}
+
 NS_IMETHODIMP
 LoadContext::GetUseTrackingProtection(bool* aUseTrackingProtection)
 {
   MOZ_ASSERT(mIsNotNull);
 
   NS_ENSURE_ARG_POINTER(aUseTrackingProtection);
 
   *aUseTrackingProtection = mUseTrackingProtection;
--- a/docshell/base/LoadContext.h
+++ b/docshell/base/LoadContext.h
@@ -106,16 +106,18 @@ public:
   // Constructor for creating a LoadContext with a given principal's appId and
   // browser flag.
   explicit LoadContext(nsIPrincipal* aPrincipal,
                        nsILoadContext* aOptionalBase = nullptr);
 
 private:
   ~LoadContext() {}
 
+  void GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override;
+
   nsWeakPtr mTopFrameElement;
   uint64_t mNestedFrameId;
   bool mIsContent;
   bool mUseRemoteTabs;
   bool mUseTrackingProtection;
   OriginAttributes mOriginAttributes;
 #ifdef DEBUG
   bool mIsNotNull;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -14939,8 +14939,14 @@ nsDocShell::GetAwaitingLargeAlloc(bool* 
   nsCOMPtr<nsITabChild> tabChild = GetTabChild();
   if (!tabChild) {
     *aResult = false;
     return NS_OK;
   }
   *aResult = static_cast<TabChild*>(tabChild.get())->IsAwaitingLargeAlloc();
   return NS_OK;
 }
+
+NS_IMETHODIMP_(void)
+nsDocShell::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
+{
+  aAttrs = mOriginAttributes;
+}
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -801,16 +801,18 @@ protected:
   }
 
   uint32_t GetInheritedFrameType();
 
   bool HasUnloadedParent();
 
   void UpdateGlobalHistoryTitle(nsIURI* aURI);
 
+  void GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override;
+
   // Dimensions of the docshell
   nsIntRect mBounds;
   nsString mName;
   nsString mTitle;
   nsString mCustomUserAgent;
 
   /**
    * Content-Type Hint of the most-recently initiated load. Used for
--- a/docshell/base/nsILoadContext.idl
+++ b/docshell/base/nsILoadContext.idl
@@ -15,17 +15,17 @@ interface nsIDOMElement;
 #endif
 %}
 
 /**
  * An nsILoadContext represents the context of a load.  This interface
  * can be queried for various information about where the load is
  * happening.
  */
-[scriptable, uuid(2813a7a3-d084-4d00-acd0-f76620315c02)]
+[builtinclass, scriptable, uuid(2813a7a3-d084-4d00-acd0-f76620315c02)]
 interface nsILoadContext : nsISupports
 {
   /**
    * associatedWindow is the window with which the load is associated, if any.
    * Note that the load may be triggered by a document which is different from
    * the document in associatedWindow, and in fact the source of the load need
    * not be same-origin with the document in associatedWindow.  This attribute
    * may be null if there is no associated window.
@@ -134,15 +134,13 @@ interface nsILoadContext : nsISupports
    * nsILoadContext.
    */
   readonly attribute jsval originAttributes;
 
 %{C++
 #ifdef MOZILLA_INTERNAL_API
   /**
    * The C++ getter for origin attributes.
-   *
-   * Defined in LoadContext.cpp
    */
-  bool GetOriginAttributes(mozilla::OriginAttributes& aAttrs);
+  NS_IMETHOD_(void) GetOriginAttributes(mozilla::OriginAttributes& aAttrs) = 0;
 #endif
 %}
 };
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -439,42 +439,50 @@ protected:
     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
 
     // Use shims for interfaces that docshell implements directly so that we
     // don't hand out references to the docshell.  The shims should all allow
     // getInterface back on us, but other than that each one should only
     // implement one interface.
 
     // XXXbz I wish we could just derive the _allcaps thing from _i
-#define DECL_SHIM(_i, _allcaps)                                              \
+#define DECL_SHIM(_i, _allcaps, _customfwd)                                  \
     class _i##Shim final : public nsIInterfaceRequestor,                     \
                            public _i                                         \
     {                                                                        \
       ~_i##Shim() {}                                                         \
     public:                                                                  \
       _i##Shim(nsIInterfaceRequestor* aIfreq, _i* aRealPtr)                  \
         : mIfReq(aIfreq), mRealPtr(aRealPtr)                                 \
       {                                                                      \
         NS_ASSERTION(mIfReq, "Expected non-null here");                      \
         NS_ASSERTION(mRealPtr, "Expected non-null here");                    \
       }                                                                      \
       NS_DECL_ISUPPORTS                                                      \
       NS_FORWARD_NSIINTERFACEREQUESTOR(mIfReq->)                             \
       NS_FORWARD_##_allcaps(mRealPtr->)                                      \
+      _customfwd                                                             \
     private:                                                                 \
       nsCOMPtr<nsIInterfaceRequestor> mIfReq;                                \
       nsCOMPtr<_i> mRealPtr;                                                 \
     };
 
-    DECL_SHIM(nsILoadContext, NSILOADCONTEXT)
-    DECL_SHIM(nsIProgressEventSink, NSIPROGRESSEVENTSINK)
-    DECL_SHIM(nsIChannelEventSink, NSICHANNELEVENTSINK)
-    DECL_SHIM(nsISecurityEventSink, NSISECURITYEVENTSINK)
-    DECL_SHIM(nsIApplicationCacheContainer, NSIAPPLICATIONCACHECONTAINER)
+#define DECL_FORWARD_CPP_GETORIGINATTRIBUTES                                 \
+      NS_IMETHODIMP_(void)                                                   \
+        GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override      \
+      {                                                                      \
+        mRealPtr->GetOriginAttributes(aAttrs);                               \
+      }
+    DECL_SHIM(nsILoadContext, NSILOADCONTEXT, DECL_FORWARD_CPP_GETORIGINATTRIBUTES)
+    DECL_SHIM(nsIProgressEventSink, NSIPROGRESSEVENTSINK, )
+    DECL_SHIM(nsIChannelEventSink, NSICHANNELEVENTSINK, )
+    DECL_SHIM(nsISecurityEventSink, NSISECURITYEVENTSINK, )
+    DECL_SHIM(nsIApplicationCacheContainer, NSIAPPLICATIONCACHECONTAINER, )
 #undef DECL_SHIM
+#undef DECL_FORWARD_CPP_GETORIGINATTRIBUTES
   };
 
   /**
    * Add an ExternalResource for aURI.  aViewer and aLoadGroup might be null
    * when this is called if the URI didn't result in an XML document.  This
    * function makes sure to remove the pending load for aURI, if any, from our
    * hashtable, and to notify its observers, if any.
    */
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3003,16 +3003,17 @@ public:
   }
   NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL
   NS_IMETHOD GetIsContent(bool*) NO_IMPL
   NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
   NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool*) NO_IMPL
   NS_IMETHOD GetOriginAttributes(JS::MutableHandleValue) NO_IMPL
+  NS_IMETHOD_(void) GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override {}
   NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL
   NS_IMETHOD SetRemoteTabs(bool) NO_IMPL
   NS_IMETHOD GetUseTrackingProtection(bool*) NO_IMPL
   NS_IMETHOD SetUseTrackingProtection(bool) NO_IMPL
 #undef NO_IMPL
 
 protected:
   ~FakeChannel() {}
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -271,16 +271,24 @@ OfflineCacheUpdateParent::GetOriginAttri
     MOZ_ASSERT(cx);
 
     nsresult rv = mLoadingPrincipal->GetOriginAttributes(cx, aAttrs);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
+NS_IMETHODIMP_(void)
+OfflineCacheUpdateParent::GetOriginAttributes(mozilla::OriginAttributes& aAttrs)
+{
+    if (mLoadingPrincipal) {
+        aAttrs = mLoadingPrincipal->OriginAttributesRef();
+    }
+}
+
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetUseTrackingProtection(bool* aUseTrackingProtection)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetUseTrackingProtection(bool aUseTrackingProtection)
--- a/uriloader/prefetch/OfflineCacheUpdateParent.h
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.h
@@ -49,16 +49,18 @@ public:
     }
 
     explicit OfflineCacheUpdateParent();
 
     virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 private:
     ~OfflineCacheUpdateParent();
 
+    void GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override;
+
     bool mIPCClosed;
 
     nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
 };
 
 } // namespace docshell
 } // namespace mozilla