Bug 1458339 part 2 - Use shared memory to initialize the JS engine. r=smaug,tcampbell,necko-reviewers

This modification relies on the shared memory implemented in Bug 1698045 and on
the ability to encode and decode self-hosted content from Bug 1668361 to
optimize the JS engine initialization by making the parent process encode the
self-hosted stencil, such that all other runtime initialization would only have
to decode it, including content processes.

Differential Revision: https://phabricator.services.mozilla.com/D110578
This commit is contained in:
Nicolas B. Pierron 2021-05-12 13:57:56 +00:00
Родитель 6605d80bb3
Коммит 965cab1dbc
5 изменённых файлов: 68 добавлений и 5 удалений

Просмотреть файл

@ -25,6 +25,7 @@
#include "jsfriendapi.h"
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/ContextOptions.h"
#include "js/Initialization.h"
#include "js/LocaleSensitive.h"
#include "js/WasmFeatures.h"
#include "mozilla/ArrayUtils.h"
@ -64,6 +65,7 @@
#include "nsXPCOMPrivate.h"
#include "OSFileConstants.h"
#include "xpcpublic.h"
#include "XPCSelfHostedShmem.h"
#if defined(XP_MACOSX)
# include "nsMacUtilsImpl.h"
@ -729,7 +731,12 @@ bool InitJSContextForWorker(WorkerPrivate* aWorkerPrivate,
JS::InitConsumeStreamCallback(aWorkerCx, ConsumeStream,
FetchUtil::ReportJSStreamError);
if (!JS::InitSelfHostedCode(aWorkerCx)) {
// When available, set the self-hosted shared memory to be read, so that we
// can decode the self-hosted content instead of parsing it.
auto& shm = xpc::SelfHostedShmem::GetSingleton();
JS::SelfHostedCache selfHostedContent = shm.Content();
if (!JS::InitSelfHostedCode(aWorkerCx, selfHostedContent)) {
NS_WARNING("Could not init self-hosted code!");
return false;
}

Просмотреть файл

@ -18,6 +18,8 @@
#include "mozilla/EventQueue.h"
#include "mozilla/ThreadEventQueue.h"
#include "js/Exception.h"
#include "js/Initialization.h"
#include "XPCSelfHostedShmem.h"
namespace mozilla {
namespace dom {
@ -369,7 +371,12 @@ void WorkletThread::EnsureCycleCollectedJSContext(JSRuntime* aParentRuntime) {
JS_SetNativeStackQuota(context->Context(),
WORKLET_CONTEXT_NATIVE_STACK_LIMIT);
if (!JS::InitSelfHostedCode(context->Context())) {
// When available, set the self-hosted shared memory to be read, so that we
// can decode the self-hosted content instead of parsing it.
auto& shm = xpc::SelfHostedShmem::GetSingleton();
JS::SelfHostedCache selfHostedContent = shm.Content();
if (!JS::InitSelfHostedCode(context->Context(), selfHostedContent)) {
// TODO: error propagation
return;
}

Просмотреть файл

@ -13,6 +13,7 @@
#include "xpcpublic.h"
#include "XPCWrapper.h"
#include "XPCJSMemoryReporter.h"
#include "XPCSelfHostedShmem.h"
#include "WrapperFactory.h"
#include "mozJSComponentLoader.h"
#include "nsNetUtil.h"
@ -40,6 +41,7 @@
#include "jsapi.h"
#include "js/ArrayBuffer.h"
#include "js/ContextOptions.h"
#include "js/Initialization.h"
#include "js/MemoryMetrics.h"
#include "js/OffThreadScriptCompilation.h"
#include "js/WasmFeatures.h"
@ -794,6 +796,9 @@ void xpc::SetPrefableRealmOptions(JS::RealmOptions& options) {
.setIteratorHelpersEnabled(sIteratorHelpersEnabled);
}
// Mirrored value of javascript.options.self_hosted.use_shared_memory.
static bool sSelfHostedUseSharedMemory = false;
static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
// Prefs that require a restart are handled here. This includes the
// process-wide JIT options because toggling these at runtime can easily cause
@ -830,6 +835,7 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
cx, JSJITCOMPILER_JIT_TRUSTEDPRINCIPALS_ENABLE, false);
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_NATIVE_REGEXP_ENABLE,
false);
sSelfHostedUseSharedMemory = false;
} else {
JS_SetGlobalJitCompilerOption(
cx, JSJITCOMPILER_BASELINE_ENABLE,
@ -843,6 +849,9 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
JS_SetGlobalJitCompilerOption(
cx, JSJITCOMPILER_NATIVE_REGEXP_ENABLE,
StaticPrefs::javascript_options_native_regexp_DoNotUseDirectly());
sSelfHostedUseSharedMemory =
StaticPrefs::
javascript_options_self_hosted_use_shared_memory_DoNotUseDirectly();
}
JS_SetOffthreadIonCompilationEnabled(
@ -1170,6 +1179,16 @@ bool DispatchOffThreadTask(js::UniquePtr<RunnableTask> task) {
return true;
}
static bool CreateSelfHostedSharedMemory(JSContext* aCx,
JS::SelfHostedCache aBuf) {
auto& shm = xpc::SelfHostedShmem::GetSingleton();
MOZ_RELEASE_ASSERT(shm.Content().IsEmpty());
// Failures within InitFromParent output warnings but do not cause
// unrecoverable failures.
shm.InitFromParent(aBuf);
return true;
}
nsresult XPCJSContext::Initialize() {
SetHelperThreadTaskCallback(&DispatchOffThreadTask);
@ -1340,7 +1359,18 @@ nsresult XPCJSContext::Initialize() {
NS_ABORT_OOM(0); // Size is unknown.
}
if (!JS::InitSelfHostedCode(cx)) {
// When available, set the self-hosted shared memory to be read, so that we
// can decode the self-hosted content instead of parsing it.
auto& shm = xpc::SelfHostedShmem::GetSingleton();
JS::SelfHostedCache selfHostedContent = shm.Content();
JS::SelfHostedWriter writer = nullptr;
if (XRE_IsParentProcess() && sSelfHostedUseSharedMemory) {
// Only the Parent process has permissions to write to the self-hosted
// shared memory.
writer = CreateSelfHostedSharedMemory;
}
if (!JS::InitSelfHostedCode(cx, selfHostedContent, writer)) {
// Note: If no exception is pending, failure is due to OOM.
if (!JS_IsExceptionPending(cx) || JS_IsThrowingOutOfMemory(cx)) {
NS_ABORT_OOM(0); // Size is unknown.

Просмотреть файл

@ -5779,6 +5779,15 @@
value: false
mirror: always
# Whether the Parent process allocates and shares memory with all content
# processes. This is mirrored once, as the parent process will do this
# allocation early on.
- name: javascript.options.self_hosted.use_shared_memory
type: bool
value: true
mirror: always # LoadStartupJSPrefs
do_not_use_directly: true
# Streams API.
- name: javascript.options.streams
type: RelaxedAtomicBool

Просмотреть файл

@ -17,6 +17,7 @@
#include "jsfriendapi.h"
#include "js/CompilationAndEvaluation.h" // JS::Compile
#include "js/ContextOptions.h"
#include "js/Initialization.h"
#include "js/PropertySpec.h"
#include "js/SourceText.h" // JS::Source{Ownership,Text}
#include "js/Utility.h"
@ -34,6 +35,8 @@
# include "nsMacUtilsImpl.h"
#endif
#include "XPCSelfHostedShmem.h"
namespace mozilla {
namespace net {
@ -642,8 +645,15 @@ class JSContextWrapper {
JS::SetWarningReporter(mContext, PACWarningReporter);
if (!JS::InitSelfHostedCode(mContext)) {
return NS_ERROR_OUT_OF_MEMORY;
// When available, set the self-hosted shared memory to be read, so that
// we can decode the self-hosted content instead of parsing it.
{
auto& shm = xpc::SelfHostedShmem::GetSingleton();
JS::SelfHostedCache selfHostedContent = shm.Content();
if (!JS::InitSelfHostedCode(mContext, selfHostedContent)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
JS::RealmOptions options;