Bug 1316683 - Part 5: Avoid going into SpiderMonkey for retrieving origin attributes; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 18 Mar 2017 16:08:12 -0400
changeset 352537 adf1dbdf0042afc959cbe1cd2d817e196a36f36e
parent 352536 448f478547deb1aa7109a7eceb40b231a6514baa
child 352538 f52e34fa7a0b6b8fea22117b6e5dcc78150649ed
push id89107
push usereakhgari@mozilla.com
push dateWed, 12 Apr 2017 15:32:33 +0000
treeherdermozilla-inbound@adf1dbdf0042 [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 - Part 5: 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.
caps/nsScriptSecurityManager.cpp
docshell/base/LoadContext.cpp
docshell/base/SerializedLoadContext.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsILoadContext.idl
dom/ipc/TabParent.cpp
dom/offline/nsDOMOfflineResourceList.cpp
uriloader/prefetch/OfflineCacheUpdateParent.cpp
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -1182,18 +1182,17 @@ nsScriptSecurityManager::GetAppCodebaseP
 NS_IMETHODIMP
 nsScriptSecurityManager::
   GetLoadContextCodebasePrincipal(nsIURI* aURI,
                                   nsILoadContext* aLoadContext,
                                   nsIPrincipal** aPrincipal)
 {
   NS_ENSURE_STATE(aLoadContext);
   OriginAttributes docShellAttrs;
-  bool result = aLoadContext->GetOriginAttributes(docShellAttrs);
-  NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
+  aLoadContext->GetOriginAttributes(docShellAttrs);
 
   nsCOMPtr<nsIPrincipal> prin =
     BasePrincipal::CreateCodebasePrincipal(aURI, docShellAttrs);
   prin.forget(aPrincipal);
   return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
--- 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)
@@ -166,26 +142,32 @@ LoadContext::GetIsInIsolatedMozBrowserEl
 
   NS_ENSURE_ARG_POINTER(aIsInIsolatedMozBrowserElement);
 
   *aIsInIsolatedMozBrowserElement = mOriginAttributes.mInIsolatedMozBrowser;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LoadContext::GetOriginAttributes(JS::MutableHandleValue aAttrs)
+LoadContext::GetScriptableOriginAttributes(JS::MutableHandleValue aAttrs)
 {
   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/SerializedLoadContext.cpp
+++ b/docshell/base/SerializedLoadContext.cpp
@@ -57,19 +57,17 @@ void
 SerializedLoadContext::Init(nsILoadContext* aLoadContext)
 {
   if (aLoadContext) {
     mIsNotNull = true;
     mIsPrivateBitValid = true;
     aLoadContext->GetIsContent(&mIsContent);
     aLoadContext->GetUseRemoteTabs(&mUseRemoteTabs);
     aLoadContext->GetUseTrackingProtection(&mUseTrackingProtection);
-    if (!aLoadContext->GetOriginAttributes(mOriginAttributes)) {
-      NS_WARNING("GetOriginAttributes failed");
-    }
+    aLoadContext->GetOriginAttributes(mOriginAttributes);
   } else {
     mIsNotNull = false;
     mIsPrivateBitValid = false;
     // none of below values really matter when mIsNotNull == false:
     // we won't be GetInterfaced to nsILoadContext
     mIsContent = true;
     mUseRemoteTabs = false;
     mUseTrackingProtection = false;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -14515,17 +14515,17 @@ nsDocShell::GetIsTopLevelContentDocShell
     *aIsTopLevelContentDocShell = root.get() == static_cast<nsIDocShellTreeItem*>(this);
   }
 
   return NS_OK;
 }
 
 // Implements nsILoadContext.originAttributes
 NS_IMETHODIMP
-nsDocShell::GetOriginAttributes(JS::MutableHandle<JS::Value> aVal)
+nsDocShell::GetScriptableOriginAttributes(JS::MutableHandle<JS::Value> aVal)
 {
   JSContext* cx = nsContentUtils::GetCurrentJSContext();
   MOZ_ASSERT(cx);
 
   return GetOriginAttributes(cx, aVal);
 }
 
 // Implements nsIDocShell.GetOriginAttributes()
@@ -14967,8 +14967,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
@@ -229,17 +229,17 @@ public:
   NS_IMETHOD GetTopFrameElement(nsIDOMElement**) override;
   NS_IMETHOD GetNestedFrameId(uint64_t*) override;
   NS_IMETHOD GetIsContent(bool*) override;
   NS_IMETHOD GetUsePrivateBrowsing(bool*) override;
   NS_IMETHOD SetUsePrivateBrowsing(bool) override;
   NS_IMETHOD SetPrivateBrowsing(bool) override;
   NS_IMETHOD GetUseRemoteTabs(bool*) override;
   NS_IMETHOD SetRemoteTabs(bool) override;
-  NS_IMETHOD GetOriginAttributes(JS::MutableHandle<JS::Value>) override;
+  NS_IMETHOD GetScriptableOriginAttributes(JS::MutableHandle<JS::Value>) override;
 
   // Restores a cached presentation from history (mLSHE).
   // This method swaps out the content viewer and simulates loads for
   // subframes. It then simulates the completion of the toplevel load.
   nsresult RestoreFromHistory();
 
   // Perform a URI load from a refresh timer. This is just like the
   // ForceRefreshURI method on nsIRefreshURI, but makes sure to take
@@ -801,16 +801,18 @@ protected:
   }
 
   uint32_t GetInheritedFrameType();
 
   bool HasUnloadedParent();
 
   void UpdateGlobalHistoryTitle(nsIURI* aURI);
 
+  NS_IMETHOD_(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
@@ -4,28 +4,30 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface mozIDOMWindowProxy;
 interface nsIDOMElement;
 
+[ref] native OriginAttributes(mozilla::OriginAttributes);
+
 %{C++
 #ifdef MOZILLA_INTERNAL_API
 #include "mozilla/BasePrincipal.h" // for OriginAttributes
 #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.
@@ -128,21 +130,16 @@ interface nsILoadContext : nsISupports
    * containing document is chrome.
    */
   readonly attribute boolean isInIsolatedMozBrowserElement;
 
   /**
    * A dictionary of the non-default origin attributes associated with this
    * nsILoadContext.
    */
+  [binaryname(ScriptableOriginAttributes)]
   readonly attribute jsval originAttributes;
 
-%{C++
-#ifdef MOZILLA_INTERNAL_API
   /**
    * The C++ getter for origin attributes.
-   *
-   * Defined in LoadContext.cpp
    */
-  bool GetOriginAttributes(mozilla::OriginAttributes& aAttrs);
-#endif
-%}
+  [noscript, notxpcom] void GetOriginAttributes(out OriginAttributes aAttrs);
 };
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3014,17 +3014,18 @@ public:
     return NS_OK;
   }
   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 GetScriptableOriginAttributes(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/dom/offline/nsDOMOfflineResourceList.cpp
+++ b/dom/offline/nsDOMOfflineResourceList.cpp
@@ -811,18 +811,17 @@ nsDOMOfflineResourceList::CacheKeys()
 
   nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetOwner());
   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(window);
   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
 
   nsAutoCString originSuffix;
   if (loadContext) {
     mozilla::OriginAttributes oa;
-    bool ok = loadContext->GetOriginAttributes(oa);
-    NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
+    loadContext->GetOriginAttributes(oa);
 
     oa.CreateSuffix(originSuffix);
   }
 
   nsAutoCString groupID;
   mApplicationCacheService->BuildGroupIDForSuffix(
       mManifestURI, originSuffix, groupID);
 
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -258,29 +258,37 @@ OfflineCacheUpdateParent::SetRemoteTabs(
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
 {
     NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
     return mLoadingPrincipal->GetIsInIsolatedMozBrowserElement(aIsInIsolatedMozBrowserElement);
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetOriginAttributes(JS::MutableHandleValue aAttrs)
+OfflineCacheUpdateParent::GetScriptableOriginAttributes(JS::MutableHandleValue aAttrs)
 {
     NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
 
     JSContext* cx = nsContentUtils::GetCurrentJSContext();
     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)