Bug 1359653: Part 7 - Use the script preloader for loading frame scripts. r=billm draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 02 May 2017 15:16:55 -0700
changeset 572142 75ed7960fab0b95588501a44f6e167dcffec3a9c
parent 572141 d3cf736c40291469aa2fa76a99d22361133613cc
child 572143 b8ad8d8a1930363146f30f1b3d7133f232af1aa4
push id57000
push usermaglione.k@gmail.com
push dateWed, 03 May 2017 19:40:22 +0000
reviewersbillm
bugs1359653
milestone55.0a1
Bug 1359653: Part 7 - Use the script preloader for loading frame scripts. r=billm MozReview-Commit-ID: L0EjM0Uomfb
dom/base/nsFrameMessageManager.cpp
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -27,16 +27,17 @@
 #include "nsIMemoryReporter.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIDOMClassInfo.h"
 #include "xpcpublic.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/IntentionalCrash.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ScriptPreloader.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/ProcessGlobal.h"
 #include "mozilla/dom/SameProcessMessageQueue.h"
 #include "mozilla/dom/ScriptSettings.h"
@@ -1593,84 +1594,96 @@ nsMessageManagerScriptExecutor::TryCache
   rv = NS_URIChainHasFlags(uri,
                            nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
                            &hasFlags);
   if (NS_FAILED(rv) || !hasFlags) {
     NS_WARNING("Will not load a frame script!");
     return;
   }
 
-  nsCOMPtr<nsIChannel> channel;
-  NS_NewChannel(getter_AddRefs(channel),
-                uri,
-                nsContentUtils::GetSystemPrincipal(),
-                nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-                nsIContentPolicy::TYPE_OTHER);
-
-  if (!channel) {
+  // Compile the script in the compilation scope instead of the current global
+  // to avoid keeping the current compartment alive.
+  AutoJSAPI jsapi;
+  if (!jsapi.Init(xpc::CompilationScope())) {
     return;
   }
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JSScript*> script(cx);
 
-  nsCOMPtr<nsIInputStream> input;
-  rv = channel->Open2(getter_AddRefs(input));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  nsString dataString;
-  char16_t* dataStringBuf = nullptr;
-  size_t dataStringLength = 0;
-  uint64_t avail64 = 0;
-  if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
-    if (avail64 > UINT32_MAX) {
+  if (XRE_IsParentProcess()) {
+    script = ScriptPreloader::GetSingleton().GetCachedScript(cx, url);
+  }
+
+  if (!script) {
+    nsCOMPtr<nsIChannel> channel;
+    NS_NewChannel(getter_AddRefs(channel),
+                  uri,
+                  nsContentUtils::GetSystemPrincipal(),
+                  nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                  nsIContentPolicy::TYPE_OTHER);
+
+    if (!channel) {
       return;
     }
-    nsCString buffer;
-    uint32_t avail = (uint32_t)std::min(avail64, (uint64_t)UINT32_MAX);
-    if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
+
+    nsCOMPtr<nsIInputStream> input;
+    rv = channel->Open2(getter_AddRefs(input));
+    NS_ENSURE_SUCCESS_VOID(rv);
+    nsString dataString;
+    char16_t* dataStringBuf = nullptr;
+    size_t dataStringLength = 0;
+    uint64_t avail64 = 0;
+    if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
+      if (avail64 > UINT32_MAX) {
+        return;
+      }
+      nsCString buffer;
+      uint32_t avail = (uint32_t)std::min(avail64, (uint64_t)UINT32_MAX);
+      if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
+        return;
+      }
+      nsScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
+                                     EmptyString(), nullptr,
+                                     dataStringBuf, dataStringLength);
+    }
+
+    JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
+                                  JS::SourceBufferHolder::GiveOwnership);
+
+    if (!dataStringBuf || dataStringLength == 0) {
       return;
     }
-    nsScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
-                                   EmptyString(), nullptr,
-                                   dataStringBuf, dataStringLength);
-  }
 
-  JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
-                                JS::SourceBufferHolder::GiveOwnership);
-
-  if (dataStringBuf && dataStringLength > 0) {
-    // Compile the script in the compilation scope instead of the current global
-    // to avoid keeping the current compartment alive.
-    AutoJSAPI jsapi;
-    if (!jsapi.Init(xpc::CompilationScope())) {
-      return;
-    }
-    JSContext* cx = jsapi.cx();
     JS::CompileOptions options(cx, JSVERSION_LATEST);
     options.setFileAndLine(url.get(), 1);
     options.setNoScriptRval(true);
-    JS::Rooted<JSScript*> script(cx);
 
     if (aRunInGlobalScope) {
       if (!JS::Compile(cx, options, srcBuf, &script)) {
         return;
       }
     // We're going to run these against some non-global scope.
     } else if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
       return;
     }
+  }
 
-    MOZ_ASSERT(script);
-    aScriptp.set(script);
+  MOZ_ASSERT(script);
+  aScriptp.set(script);
 
-    nsAutoCString scheme;
-    uri->GetScheme(scheme);
-    // We don't cache data: scripts!
-    if (aShouldCache && !scheme.EqualsLiteral("data")) {
-      // Root the object also for caching.
-      auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
-      sCachedScripts->Put(aURL, holder);
+  nsAutoCString scheme;
+  uri->GetScheme(scheme);
+  // We don't cache data: scripts!
+  if (aShouldCache && !scheme.EqualsLiteral("data")) {
+    if (XRE_IsParentProcess()) {
+      ScriptPreloader::GetSingleton().NoteScript(url, url, script);
     }
+    // Root the object also for caching.
+    auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
+    sCachedScripts->Put(aURL, holder);
   }
 }
 
 void
 nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
   const nsAString& aURL,
   bool aRunInGlobalScope)
 {