diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index 2707d380103a..ae3c54f3f322 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -32,6 +32,7 @@ #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" @@ -1598,53 +1599,62 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript( return; } - nsCOMPtr 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 script(cx); - nsCOMPtr 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); + if (XRE_IsParentProcess()) { + script = ScriptPreloader::GetSingleton().GetCachedScript(cx, url); } - JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength, - JS::SourceBufferHolder::GiveOwnership); + if (!script) { + nsCOMPtr channel; + NS_NewChannel(getter_AddRefs(channel), + uri, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + nsIContentPolicy::TYPE_OTHER); - 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())) { + if (!channel) { return; } - JSContext* cx = jsapi.cx(); + + nsCOMPtr 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; + } + JS::CompileOptions options(cx, JSVERSION_LATEST); options.setFileAndLine(url.get(), 1); options.setNoScriptRval(true); - JS::Rooted script(cx); if (aRunInGlobalScope) { if (!JS::Compile(cx, options, srcBuf, &script)) { @@ -1654,18 +1664,21 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript( } 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); } }