forked from mirrors/gecko-dev
Bug 1732362 part 3 - Add an API to disable the JIT backend completely. r=iain
This adds a mechanism to permanently disable the JIT backend for the process. This lets us improve the sandbox for the socket process. Depends on D136723 Differential Revision: https://phabricator.services.mozilla.com/D136724
This commit is contained in:
parent
41b6a25500
commit
9a1036bf48
11 changed files with 84 additions and 25 deletions
|
|
@ -144,6 +144,15 @@ JS_PUBLIC_API bool InitSelfHostedCode(JSContext* cx,
|
|||
SelfHostedCache cache = nullptr,
|
||||
SelfHostedWriter writer = nullptr);
|
||||
|
||||
/*
|
||||
* Permanently disable the JIT backend for this process. This disables the JS
|
||||
* Baseline Interpreter, JIT compilers, regular expression JIT and support for
|
||||
* WebAssembly.
|
||||
*
|
||||
* If called, this *must* be called before JS_Init.
|
||||
*/
|
||||
JS_PUBLIC_API void DisableJitBackend();
|
||||
|
||||
} // namespace JS
|
||||
|
||||
/**
|
||||
|
|
|
|||
19
js/src/jit-test/tests/basic/disable-jit-backend.js
Normal file
19
js/src/jit-test/tests/basic/disable-jit-backend.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// |jit-test| --no-jit-backend
|
||||
|
||||
assertEq(wasmIsSupportedByHardware(), false);
|
||||
assertEq(wasmIsSupported(), false);
|
||||
assertEq(isAsmJSCompilationAvailable(), false);
|
||||
|
||||
function test() {
|
||||
var sum = 0;
|
||||
for (var i = 0; i < 15; i++) {
|
||||
sum += i;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
assertEq(test(), 105);
|
||||
|
||||
var re = /[\d][a-z]{3}[\d]/;
|
||||
for (var i = 0; i < 10; i++) {
|
||||
assertEq(re.exec("123foo456")[0], "3foo4");
|
||||
}
|
||||
|
|
@ -154,6 +154,10 @@ DefaultJitOptions::DefaultJitOptions() {
|
|||
// Toggles whether functions may be entered at loop headers.
|
||||
SET_DEFAULT(osr, true);
|
||||
|
||||
// Whether the JIT backend (used by JITs, Wasm, Baseline Interpreter) has been
|
||||
// disabled for this process. See JS::DisableJitBackend.
|
||||
SET_DEFAULT(disableJitBackend, false);
|
||||
|
||||
// Whether to enable extra code to perform dynamic validations.
|
||||
SET_DEFAULT(runExtraChecks, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct DefaultJitOptions {
|
|||
#endif
|
||||
bool checkRangeAnalysis;
|
||||
bool runExtraChecks;
|
||||
bool disableJitBackend;
|
||||
bool disableAma;
|
||||
bool disableEaa;
|
||||
bool disableEdgeCaseAnalysis;
|
||||
|
|
@ -136,14 +137,19 @@ struct DefaultJitOptions {
|
|||
|
||||
extern DefaultJitOptions JitOptions;
|
||||
|
||||
inline bool IsBaselineInterpreterEnabled() {
|
||||
#ifdef JS_CODEGEN_NONE
|
||||
inline bool HasJitBackend() {
|
||||
#if defined(JS_CODEGEN_NONE)
|
||||
return false;
|
||||
#else
|
||||
return JitOptions.baselineInterpreter && JitOptions.supportsFloatingPoint;
|
||||
return !JitOptions.disableJitBackend;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool IsBaselineInterpreterEnabled() {
|
||||
return HasJitBackend() && JitOptions.baselineInterpreter &&
|
||||
JitOptions.supportsFloatingPoint;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
|
||||
extern mozilla::Atomic<bool> fuzzingSafe;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
# include "jit/arm64/vixl/Cpu-vixl.h"
|
||||
#endif
|
||||
#include "jit/FlushICache.h" // js::jit::FlushICache
|
||||
#include "jit/JitOptions.h"
|
||||
#include "threading/LockGuard.h"
|
||||
#include "threading/Mutex.h"
|
||||
#include "util/Memory.h"
|
||||
|
|
@ -545,6 +546,7 @@ class ProcessExecutableMemory {
|
|||
pages_.init();
|
||||
|
||||
MOZ_RELEASE_ASSERT(!initialized());
|
||||
MOZ_RELEASE_ASSERT(HasJitBackend());
|
||||
MOZ_RELEASE_ASSERT(gc::SystemPageSize() <= ExecutableCodePageSize);
|
||||
|
||||
void* p = ReserveProcessExecutableMemory(MaxCodeBytesPerProcess);
|
||||
|
|
@ -603,6 +605,7 @@ void* ProcessExecutableMemory::allocate(size_t bytes,
|
|||
ProtectionSetting protection,
|
||||
MemCheckKind checkKind) {
|
||||
MOZ_ASSERT(initialized());
|
||||
MOZ_ASSERT(HasJitBackend());
|
||||
MOZ_ASSERT(bytes > 0);
|
||||
MOZ_ASSERT((bytes % ExecutableCodePageSize) == 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
--no-warp-generator
|
||||
--no-warp-async
|
||||
--large-arraybuffers
|
||||
--no-jit-backend
|
||||
|
||||
# GC-related
|
||||
# These 2 flags can cause the shell to slow down
|
||||
|
|
|
|||
|
|
@ -12245,6 +12245,9 @@ int main(int argc, char** argv) {
|
|||
"Disable functions that cause "
|
||||
"artificial OOMs") ||
|
||||
!op.addBoolOption('\0', "no-threads", "Disable helper threads") ||
|
||||
!op.addBoolOption(
|
||||
'\0', "no-jit-backend",
|
||||
"Disable the JIT backend completely for this process") ||
|
||||
#ifdef DEBUG
|
||||
!op.addBoolOption('\0', "dump-entrained-variables",
|
||||
"Print variables which are "
|
||||
|
|
@ -12345,6 +12348,11 @@ int main(int argc, char** argv) {
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Note: DisableJitBackend must be called before JS_InitWithFailureDiagnostic.
|
||||
if (op.getBoolOption("no-jit-backend")) {
|
||||
JS::DisableJitBackend();
|
||||
}
|
||||
|
||||
// Start the engine.
|
||||
if (const char* message = JS_InitWithFailureDiagnostic()) {
|
||||
fprintf(gErrFile->fp, "JS_Init failed: %s\n", message);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "jit/AtomicOperations.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "jit/JitCommon.h"
|
||||
#include "jit/JitOptions.h"
|
||||
#include "jit/ProcessExecutableMemory.h"
|
||||
#include "js/Utility.h"
|
||||
#include "threading/ProtectedData.h" // js::AutoNoteSingleThreadedRegion
|
||||
|
|
@ -175,7 +176,9 @@ JS_PUBLIC_API const char* JS::detail::InitWithFailureDiagnostic(
|
|||
|
||||
js::coverage::InitLCov();
|
||||
|
||||
RETURN_IF_FAIL(js::jit::InitProcessExecutableMemory());
|
||||
if (js::jit::HasJitBackend()) {
|
||||
RETURN_IF_FAIL(js::jit::InitProcessExecutableMemory());
|
||||
}
|
||||
|
||||
RETURN_IF_FAIL(js::MemoryProtectionExceptionHandler::install());
|
||||
|
||||
|
|
@ -242,11 +245,11 @@ JS_PUBLIC_API bool JS::InitSelfHostedCode(JSContext* cx, SelfHostedCache cache,
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef JS_CODEGEN_NONE
|
||||
if (!rt->createJitRuntime(cx)) {
|
||||
return false;
|
||||
if (js::jit::HasJitBackend()) {
|
||||
if (!rt->createJitRuntime(cx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -304,7 +307,9 @@ JS_PUBLIC_API void JS_ShutDown(void) {
|
|||
js::FinishDateTimeState();
|
||||
|
||||
if (!JSRuntime::hasLiveRuntimes()) {
|
||||
js::jit::ReleaseProcessExecutableMemory();
|
||||
if (js::jit::HasJitBackend()) {
|
||||
js::jit::ReleaseProcessExecutableMemory();
|
||||
}
|
||||
MOZ_ASSERT(!js::LiveMappedBufferCount());
|
||||
}
|
||||
|
||||
|
|
@ -333,3 +338,11 @@ JS_PUBLIC_API bool JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn,
|
|||
(defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86))
|
||||
void JS::SetAVXEnabled() { js::jit::CPUInfo::SetAVXEnabled(); }
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API void JS::DisableJitBackend() {
|
||||
MOZ_ASSERT(libraryInitState == InitState::Uninitialized,
|
||||
"DisableJitBackend must be called before JS_Init");
|
||||
MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
|
||||
"DisableJitBackend must be called before creating a JSContext");
|
||||
js::jit::JitOptions.disableJitBackend = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2112,11 +2112,9 @@ void JSScript::relazify(JSRuntime* rt) {
|
|||
js::Scope* scope = enclosingScope();
|
||||
UniquePtr<PrivateScriptData> scriptData;
|
||||
|
||||
#ifndef JS_CODEGEN_NONE
|
||||
// Any JIT compiles should have been released, so we already point to the
|
||||
// interpreter trampoline which supports lazy scripts.
|
||||
MOZ_ASSERT(isUsingInterpreterTrampoline(rt));
|
||||
#endif
|
||||
MOZ_ASSERT_IF(jit::HasJitBackend(), isUsingInterpreterTrampoline(rt));
|
||||
|
||||
// Without bytecode, the script counts are invalid so destroy them if they
|
||||
// still exist.
|
||||
|
|
@ -2363,11 +2361,10 @@ bool JSScript::fullyInitFromStencil(
|
|||
// here will be released by the UniquePtr.
|
||||
Rooted<UniquePtr<PrivateScriptData>> lazyData(cx);
|
||||
|
||||
#ifndef JS_CODEGEN_NONE
|
||||
// Whether we are a newborn script or an existing lazy script, we should
|
||||
// already be pointing to the interpreter trampoline.
|
||||
MOZ_ASSERT(script->isUsingInterpreterTrampoline(cx->runtime()));
|
||||
#endif
|
||||
MOZ_ASSERT_IF(jit::HasJitBackend(),
|
||||
script->isUsingInterpreterTrampoline(cx->runtime()));
|
||||
|
||||
// If we are using an existing lazy script, record enough info to be able to
|
||||
// rollback on failure.
|
||||
|
|
@ -3131,11 +3128,10 @@ BaseScript* BaseScript::New(JSContext* cx, JS::Handle<JSFunction*> function,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef JS_CODEGEN_NONE
|
||||
uint8_t* stubEntry = cx->runtime()->jitRuntime()->interpreterStub().value;
|
||||
#else
|
||||
uint8_t* stubEntry = nullptr;
|
||||
#endif
|
||||
if (jit::HasJitBackend()) {
|
||||
stubEntry = cx->runtime()->jitRuntime()->interpreterStub().value;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(function,
|
||||
function->compartment() == sourceObject->compartment());
|
||||
|
|
|
|||
|
|
@ -48,11 +48,7 @@ enum RegExpRunStatus : int32_t {
|
|||
};
|
||||
|
||||
inline bool IsNativeRegExpEnabled() {
|
||||
#ifdef JS_CODEGEN_NONE
|
||||
return false;
|
||||
#else
|
||||
return jit::JitOptions.nativeRegExp;
|
||||
#endif
|
||||
return jit::HasJitBackend() && jit::JitOptions.nativeRegExp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -382,10 +382,14 @@ bool wasm::ThreadsAvailable(JSContext* cx) {
|
|||
}
|
||||
|
||||
bool wasm::HasPlatformSupport(JSContext* cx) {
|
||||
#if !MOZ_LITTLE_ENDIAN() || defined(JS_CODEGEN_NONE) || defined(__wasi__)
|
||||
#if !MOZ_LITTLE_ENDIAN()
|
||||
return false;
|
||||
#else
|
||||
|
||||
if (!HasJitBackend()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gc::SystemPageSize() > wasm::PageSize) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue