зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1599226) for causing hazards busatges CLOSED TREE
Backed out changeset 05b2d3c59b88 (bug 1599226) Backed out changeset 528083f7cf98 (bug 1599226) Backed out changeset ad782d625431 (bug 1599226)
This commit is contained in:
Родитель
52d630ef26
Коммит
c2195932ec
|
@ -44,7 +44,6 @@
|
|||
#include "gc/Zone.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/InlinableNatives.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "jit/JitRealm.h"
|
||||
#include "js/Array.h" // JS::NewArrayObject
|
||||
#include "js/ArrayBuffer.h" // JS::{DetachArrayBuffer,GetArrayBufferLengthAndData,NewArrayBufferWithContents}
|
||||
|
@ -2992,7 +2991,7 @@ static_assert(JitWarmupResetLimit <=
|
|||
static bool testingFunc_inJit(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!jit::IsBaselineJitEnabled(cx)) {
|
||||
if (!jit::IsBaselineJitEnabled()) {
|
||||
return ReturnStringCopy(cx, args, "Baseline is disabled.");
|
||||
}
|
||||
|
||||
|
@ -6117,7 +6116,7 @@ static bool BaselineCompile(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!jit::IsBaselineJitEnabled(cx)) {
|
||||
if (!jit::IsBaselineJitEnabled()) {
|
||||
returnedStr = "baseline disabled";
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ bool jit::Bailout(BailoutStack* sp, BaselineBailoutInfo** bailoutInfo) {
|
|||
JitSpew(JitSpew_IonBailouts, "Took bailout! Snapshot offset: %d",
|
||||
frame.snapshotOffset());
|
||||
|
||||
MOZ_ASSERT(IsBaselineJitEnabled(cx));
|
||||
MOZ_ASSERT(IsBaselineJitEnabled());
|
||||
|
||||
*bailoutInfo = nullptr;
|
||||
bool success = BailoutIonToBaseline(cx, bailoutData.activation(), frame,
|
||||
|
@ -136,7 +136,7 @@ bool jit::InvalidationBailout(InvalidationBailoutStack* sp,
|
|||
// Note: the frame size must be computed before we return from this function.
|
||||
*frameSizeOut = frame.frameSize();
|
||||
|
||||
MOZ_ASSERT(IsBaselineJitEnabled(cx));
|
||||
MOZ_ASSERT(IsBaselineJitEnabled());
|
||||
|
||||
*bailoutInfo = nullptr;
|
||||
bool success = BailoutIonToBaseline(cx, bailoutData.activation(), frame, true,
|
||||
|
|
|
@ -198,7 +198,7 @@ MethodStatus jit::BaselineCompile(JSContext* cx, JSScript* script,
|
|||
cx->check(script);
|
||||
MOZ_ASSERT(!script->hasBaselineScript());
|
||||
MOZ_ASSERT(script->canBaselineCompile());
|
||||
MOZ_ASSERT(IsBaselineJitEnabled(cx));
|
||||
MOZ_ASSERT(IsBaselineJitEnabled());
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Baseline script compilation",
|
||||
JS::ProfilingCategoryPair::JS_BaselineCompilation);
|
||||
|
@ -235,7 +235,7 @@ static MethodStatus CanEnterBaselineJIT(JSContext* cx, HandleScript script,
|
|||
return Method_Skipped;
|
||||
}
|
||||
|
||||
if (!IsBaselineJitEnabled(cx)) {
|
||||
if (!IsBaselineJitEnabled()) {
|
||||
script->disableBaselineCompile();
|
||||
return Method_CantCompile;
|
||||
}
|
||||
|
|
|
@ -584,21 +584,6 @@ class BaselineInterpreter {
|
|||
MOZ_MUST_USE bool GenerateBaselineInterpreter(JSContext* cx,
|
||||
BaselineInterpreter& interpreter);
|
||||
|
||||
inline bool IsBaselineJitEnabled(JSContext* cx) {
|
||||
if (MOZ_UNLIKELY(!IsBaselineInterpreterEnabled())) {
|
||||
return false;
|
||||
}
|
||||
if (MOZ_LIKELY(JitOptions.baselineJit)) {
|
||||
return true;
|
||||
}
|
||||
if (JitOptions.jitForTrustedPrincipals) {
|
||||
JS::Realm* realm = js::GetContextRealm(cx);
|
||||
return realm && JS::GetRealmPrincipals(realm) &&
|
||||
JS::GetRealmPrincipals(realm)->isSystemOrAddonPrincipal();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
|
|
@ -78,6 +78,84 @@ using mozilla::DebugOnly;
|
|||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
// Assert that JitCode is gc::Cell aligned.
|
||||
JS_STATIC_ASSERT(sizeof(JitCode) % gc::CellAlignBytes == 0);
|
||||
|
||||
static MOZ_THREAD_LOCAL(JitContext*) TlsJitContext;
|
||||
|
||||
static JitContext* CurrentJitContext() {
|
||||
if (!TlsJitContext.init()) {
|
||||
return nullptr;
|
||||
}
|
||||
return TlsJitContext.get();
|
||||
}
|
||||
|
||||
void jit::SetJitContext(JitContext* ctx) { TlsJitContext.set(ctx); }
|
||||
|
||||
JitContext* jit::GetJitContext() {
|
||||
MOZ_ASSERT(CurrentJitContext());
|
||||
return CurrentJitContext();
|
||||
}
|
||||
|
||||
JitContext* jit::MaybeGetJitContext() { return CurrentJitContext(); }
|
||||
|
||||
JitContext::JitContext(CompileRuntime* rt, CompileRealm* realm,
|
||||
TempAllocator* temp)
|
||||
: prev_(CurrentJitContext()), realm_(realm), temp(temp), runtime(rt) {
|
||||
MOZ_ASSERT(rt);
|
||||
MOZ_ASSERT(realm);
|
||||
MOZ_ASSERT(temp);
|
||||
SetJitContext(this);
|
||||
}
|
||||
|
||||
JitContext::JitContext(JSContext* cx, TempAllocator* temp)
|
||||
: prev_(CurrentJitContext()),
|
||||
realm_(CompileRealm::get(cx->realm())),
|
||||
cx(cx),
|
||||
temp(temp),
|
||||
runtime(CompileRuntime::get(cx->runtime())) {
|
||||
SetJitContext(this);
|
||||
}
|
||||
|
||||
JitContext::JitContext(TempAllocator* temp)
|
||||
: prev_(CurrentJitContext()), temp(temp) {
|
||||
#ifdef DEBUG
|
||||
isCompilingWasm_ = true;
|
||||
#endif
|
||||
SetJitContext(this);
|
||||
}
|
||||
|
||||
JitContext::JitContext() : JitContext(nullptr) {}
|
||||
|
||||
JitContext::~JitContext() { SetJitContext(prev_); }
|
||||
|
||||
bool jit::InitializeJit() {
|
||||
if (!TlsJitContext.init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CheckLogging();
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
const char* env = getenv("CACHEIR_LOGS");
|
||||
if (env && env[0] && env[0] != '0') {
|
||||
CacheIRSpewer::singleton().init(env);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
InitARMFlags();
|
||||
#endif
|
||||
|
||||
// Note: these flags need to be initialized after the InitARMFlags call above.
|
||||
JitOptions.supportsFloatingPoint = MacroAssembler::SupportsFloatingPoint();
|
||||
JitOptions.supportsUnalignedAccesses =
|
||||
MacroAssembler::SupportsUnalignedAccesses();
|
||||
|
||||
CheckPerf();
|
||||
return true;
|
||||
}
|
||||
|
||||
JitRuntime::JitRuntime()
|
||||
: nextCompilationId_(0),
|
||||
exceptionTailOffset_(0),
|
||||
|
@ -1992,7 +2070,7 @@ static MethodStatus Compile(JSContext* cx, HandleScript script,
|
|||
BaselineFrame* osrFrame, uint32_t osrFrameSize,
|
||||
jsbytecode* osrPc, bool forceRecompile = false) {
|
||||
MOZ_ASSERT(jit::IsIonEnabled(cx));
|
||||
MOZ_ASSERT(jit::IsBaselineJitEnabled(cx));
|
||||
MOZ_ASSERT(jit::IsBaselineJitEnabled());
|
||||
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Ion script compilation",
|
||||
|
@ -2853,6 +2931,20 @@ size_t jit::SizeOfIonData(JSScript* script,
|
|||
return result;
|
||||
}
|
||||
|
||||
bool jit::JitSupportsSimd() { return js::jit::MacroAssembler::SupportsSimd(); }
|
||||
|
||||
bool jit::JitSupportsAtomics() {
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
// Bug 1146902, bug 1077318: Enable Ion inlining of Atomics
|
||||
// operations on ARM only when the CPU has byte, halfword, and
|
||||
// doubleword load-exclusive and store-exclusive instructions,
|
||||
// until we can add support for systems that don't have those.
|
||||
return js::jit::HasLDSTREXBHD();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// If you change these, please also change the comment in TempAllocator.
|
||||
/* static */ const size_t TempAllocator::BallastSize = 16 * 1024;
|
||||
/* static */ const size_t TempAllocator::PreferredLifoChunkSize = 32 * 1024;
|
||||
|
|
154
js/src/jit/Ion.h
154
js/src/jit/Ion.h
|
@ -10,9 +10,7 @@
|
|||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Result.h"
|
||||
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/CompileWrappers.h"
|
||||
#include "jit/JitContext.h"
|
||||
#include "jit/JitOptions.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/Realm.h"
|
||||
|
@ -21,6 +19,124 @@
|
|||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class TempAllocator;
|
||||
|
||||
enum MethodStatus {
|
||||
Method_Error,
|
||||
Method_CantCompile,
|
||||
Method_Skipped,
|
||||
Method_Compiled
|
||||
};
|
||||
|
||||
enum class AbortReason : uint8_t {
|
||||
Alloc,
|
||||
Inlining,
|
||||
PreliminaryObjects,
|
||||
Disable,
|
||||
Error,
|
||||
NoAbort
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
using AbortReasonOr = mozilla::Result<V, AbortReason>;
|
||||
using mozilla::Err;
|
||||
using mozilla::Ok;
|
||||
|
||||
static_assert(sizeof(AbortReasonOr<Ok>) <= sizeof(uintptr_t),
|
||||
"Unexpected size of AbortReasonOr<Ok>");
|
||||
static_assert(sizeof(AbortReasonOr<bool>) <= sizeof(uintptr_t),
|
||||
"Unexpected size of AbortReasonOr<bool>");
|
||||
|
||||
// A JIT context is needed to enter into either an JIT method or an instance
|
||||
// of a JIT compiler. It points to a temporary allocator and the active
|
||||
// JSContext, either of which may be nullptr, and the active realm, which
|
||||
// will not be nullptr.
|
||||
|
||||
class JitContext {
|
||||
JitContext* prev_ = nullptr;
|
||||
CompileRealm* realm_ = nullptr;
|
||||
int assemblerCount_ = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Whether this thread is actively Ion compiling (does not include Wasm or
|
||||
// IonBuilder).
|
||||
bool inIonBackend_ = false;
|
||||
|
||||
// Whether this thread is actively Ion compiling in a context where a minor
|
||||
// GC could happen simultaneously. If this is true, this thread cannot use
|
||||
// any pointers into the nursery.
|
||||
bool inIonBackendSafeForMinorGC_ = false;
|
||||
|
||||
bool isCompilingWasm_ = false;
|
||||
bool oom_ = false;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Running context when executing on the main thread. Not available during
|
||||
// compilation.
|
||||
JSContext* cx = nullptr;
|
||||
|
||||
// Allocator for temporary memory during compilation.
|
||||
TempAllocator* temp = nullptr;
|
||||
|
||||
// Wrappers with information about the current runtime/realm for use
|
||||
// during compilation.
|
||||
CompileRuntime* runtime = nullptr;
|
||||
|
||||
// Constructor for compilations happening on the main thread.
|
||||
JitContext(JSContext* cx, TempAllocator* temp);
|
||||
|
||||
// Constructor for off-thread Ion compilations.
|
||||
JitContext(CompileRuntime* rt, CompileRealm* realm, TempAllocator* temp);
|
||||
|
||||
// Constructors for Wasm compilation.
|
||||
explicit JitContext(TempAllocator* temp);
|
||||
JitContext();
|
||||
|
||||
~JitContext();
|
||||
|
||||
int getNextAssemblerId() { return assemblerCount_++; }
|
||||
|
||||
CompileRealm* maybeRealm() const { return realm_; }
|
||||
CompileRealm* realm() const {
|
||||
MOZ_ASSERT(maybeRealm());
|
||||
return maybeRealm();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool isCompilingWasm() { return isCompilingWasm_; }
|
||||
bool hasOOM() { return oom_; }
|
||||
void setOOM() { oom_ = true; }
|
||||
|
||||
bool inIonBackend() const { return inIonBackend_; }
|
||||
|
||||
bool inIonBackendSafeForMinorGC() const {
|
||||
return inIonBackendSafeForMinorGC_;
|
||||
}
|
||||
|
||||
void enterIonBackend(bool safeForMinorGC) {
|
||||
MOZ_ASSERT(!inIonBackend_);
|
||||
MOZ_ASSERT(!inIonBackendSafeForMinorGC_);
|
||||
inIonBackend_ = true;
|
||||
inIonBackendSafeForMinorGC_ = safeForMinorGC;
|
||||
}
|
||||
void leaveIonBackend() {
|
||||
MOZ_ASSERT(inIonBackend_);
|
||||
inIonBackend_ = false;
|
||||
inIonBackendSafeForMinorGC_ = false;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Process-wide initialization of JIT data structures.
|
||||
MOZ_MUST_USE bool InitializeJit();
|
||||
|
||||
// Get and set the current JIT context.
|
||||
JitContext* GetJitContext();
|
||||
JitContext* MaybeGetJitContext();
|
||||
|
||||
void SetJitContext(JitContext* ctx);
|
||||
|
||||
bool CanIonCompileScript(JSContext* cx, JSScript* script);
|
||||
bool CanIonInlineScript(JSScript* script);
|
||||
|
||||
|
@ -49,6 +165,23 @@ MethodStatus CanEnterIon(JSContext* cx, RunState& state);
|
|||
|
||||
MethodStatus Recompile(JSContext* cx, HandleScript script, bool force);
|
||||
|
||||
enum JitExecStatus {
|
||||
// The method call had to be aborted due to a stack limit check. This
|
||||
// error indicates that Ion never attempted to clean up frames.
|
||||
JitExec_Aborted,
|
||||
|
||||
// The method call resulted in an error, and IonMonkey has cleaned up
|
||||
// frames.
|
||||
JitExec_Error,
|
||||
|
||||
// The method call succeeded and returned a value.
|
||||
JitExec_Ok
|
||||
};
|
||||
|
||||
static inline bool IsErrorStatus(JitExecStatus status) {
|
||||
return status == JitExec_Error || status == JitExec_Aborted;
|
||||
}
|
||||
|
||||
struct EnterJitData;
|
||||
|
||||
// Walk the stack and invalidate active Ion frames for the invalid scripts.
|
||||
|
@ -138,19 +271,12 @@ void ForbidCompilation(JSContext* cx, JSScript* script);
|
|||
|
||||
size_t SizeOfIonData(JSScript* script, mozilla::MallocSizeOf mallocSizeOf);
|
||||
|
||||
bool JitSupportsSimd();
|
||||
bool JitSupportsAtomics();
|
||||
|
||||
inline bool IsIonEnabled(JSContext* cx) {
|
||||
if (MOZ_UNLIKELY(!IsBaselineJitEnabled(cx) || cx->options().disableIon())) {
|
||||
return false;
|
||||
}
|
||||
if (MOZ_LIKELY(JitOptions.ion)) {
|
||||
return true;
|
||||
}
|
||||
if (JitOptions.jitForTrustedPrincipals) {
|
||||
JS::Realm* realm = js::GetContextRealm(cx);
|
||||
return realm && JS::GetRealmPrincipals(realm) &&
|
||||
JS::GetRealmPrincipals(realm)->isSystemOrAddonPrincipal();
|
||||
}
|
||||
return false;
|
||||
return IsBaselineJitEnabled() && JitOptions.ion &&
|
||||
!cx->options().disableIon();
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
|
|
|
@ -4537,7 +4537,7 @@ bool jit::AnalyzeNewScriptDefiniteProperties(
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!jit::IsIonEnabled(cx) || !jit::IsBaselineJitEnabled(cx) ||
|
||||
if (!jit::IsIonEnabled(cx) || !jit::IsBaselineJitEnabled() ||
|
||||
!CanBaselineInterpretScript(script)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ EnterJitStatus js::jit::MaybeEnterJit(JSContext* cx, RunState& state) {
|
|||
}
|
||||
|
||||
// Try to Baseline-compile.
|
||||
if (jit::IsBaselineJitEnabled(cx)) {
|
||||
if (jit::IsBaselineJitEnabled()) {
|
||||
jit::MethodStatus status =
|
||||
jit::CanEnterBaselineMethod<BaselineTier::Compiler>(cx, state);
|
||||
if (status == jit::Method_Error) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "jit/InlineList.h"
|
||||
#include "jit/JitContext.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
||||
namespace js {
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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 "jit/JitContext.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "gc/FreeOp.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "jit/AliasAnalysis.h"
|
||||
#include "jit/AlignmentMaskAnalysis.h"
|
||||
#include "jit/BacktrackingAllocator.h"
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/BaselineInspector.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/CacheIRSpewer.h"
|
||||
#include "jit/CodeGenerator.h"
|
||||
#include "jit/EdgeCaseAnalysis.h"
|
||||
#include "jit/EffectiveAddressAnalysis.h"
|
||||
#include "jit/FoldLinearArithConstants.h"
|
||||
#include "jit/InstructionReordering.h"
|
||||
#include "jit/IonAnalysis.h"
|
||||
#include "jit/IonBuilder.h"
|
||||
#include "jit/IonIC.h"
|
||||
#include "jit/IonOptimizationLevels.h"
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "jit/JitCommon.h"
|
||||
#include "jit/JitRealm.h"
|
||||
#include "jit/JitSpewer.h"
|
||||
#include "jit/LICM.h"
|
||||
#include "jit/Linker.h"
|
||||
#include "jit/LIR.h"
|
||||
#include "jit/Lowering.h"
|
||||
#include "jit/PerfSpewer.h"
|
||||
#include "jit/RangeAnalysis.h"
|
||||
#include "jit/ScalarReplacement.h"
|
||||
#include "jit/Sink.h"
|
||||
#include "jit/StupidAllocator.h"
|
||||
#include "jit/ValueNumbering.h"
|
||||
#include "jit/WasmBCE.h"
|
||||
#include "js/Printf.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "util/Memory.h"
|
||||
#include "util/Windows.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
#include "vm/Realm.h"
|
||||
#include "vm/TraceLogging.h"
|
||||
#ifdef MOZ_VTUNE
|
||||
# include "vtune/VTuneWrapper.h"
|
||||
#endif
|
||||
|
||||
#include "debugger/DebugAPI-inl.h"
|
||||
#include "gc/GC-inl.h"
|
||||
#include "jit/JitFrames-inl.h"
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "jit/shared/Lowering-shared-inl.h"
|
||||
#include "vm/EnvironmentObject-inl.h"
|
||||
#include "vm/GeckoProfiler-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
||||
#include "vm/Realm-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
|
||||
#if defined(ANDROID)
|
||||
# include <sys/system_properties.h>
|
||||
#endif
|
||||
|
||||
using mozilla::DebugOnly;
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
// Assert that JitCode is gc::Cell aligned.
|
||||
JS_STATIC_ASSERT(sizeof(JitCode) % gc::CellAlignBytes == 0);
|
||||
|
||||
static MOZ_THREAD_LOCAL(JitContext*) TlsJitContext;
|
||||
|
||||
static JitContext* CurrentJitContext() {
|
||||
if (!TlsJitContext.init()) {
|
||||
return nullptr;
|
||||
}
|
||||
return TlsJitContext.get();
|
||||
}
|
||||
|
||||
void jit::SetJitContext(JitContext* ctx) { TlsJitContext.set(ctx); }
|
||||
|
||||
JitContext* jit::GetJitContext() {
|
||||
MOZ_ASSERT(CurrentJitContext());
|
||||
return CurrentJitContext();
|
||||
}
|
||||
|
||||
JitContext* jit::MaybeGetJitContext() { return CurrentJitContext(); }
|
||||
|
||||
JitContext::JitContext(CompileRuntime* rt, CompileRealm* realm,
|
||||
TempAllocator* temp)
|
||||
: prev_(CurrentJitContext()), realm_(realm), temp(temp), runtime(rt) {
|
||||
MOZ_ASSERT(rt);
|
||||
MOZ_ASSERT(realm);
|
||||
MOZ_ASSERT(temp);
|
||||
SetJitContext(this);
|
||||
}
|
||||
|
||||
JitContext::JitContext(JSContext* cx, TempAllocator* temp)
|
||||
: prev_(CurrentJitContext()),
|
||||
realm_(CompileRealm::get(cx->realm())),
|
||||
cx(cx),
|
||||
temp(temp),
|
||||
runtime(CompileRuntime::get(cx->runtime())) {
|
||||
SetJitContext(this);
|
||||
}
|
||||
|
||||
JitContext::JitContext(TempAllocator* temp)
|
||||
: prev_(CurrentJitContext()), temp(temp) {
|
||||
#ifdef DEBUG
|
||||
isCompilingWasm_ = true;
|
||||
#endif
|
||||
SetJitContext(this);
|
||||
}
|
||||
|
||||
JitContext::JitContext() : JitContext(nullptr) {}
|
||||
|
||||
JitContext::~JitContext() { SetJitContext(prev_); }
|
||||
|
||||
bool jit::InitializeJit() {
|
||||
if (!TlsJitContext.init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CheckLogging();
|
||||
|
||||
#ifdef JS_CACHEIR_SPEW
|
||||
const char* env = getenv("CACHEIR_LOGS");
|
||||
if (env && env[0] && env[0] != '0') {
|
||||
CacheIRSpewer::singleton().init(env);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
InitARMFlags();
|
||||
#endif
|
||||
|
||||
// Note: these flags need to be initialized after the InitARMFlags call above.
|
||||
JitOptions.supportsFloatingPoint = MacroAssembler::SupportsFloatingPoint();
|
||||
JitOptions.supportsUnalignedAccesses =
|
||||
MacroAssembler::SupportsUnalignedAccesses();
|
||||
|
||||
CheckPerf();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool jit::JitSupportsSimd() { return js::jit::MacroAssembler::SupportsSimd(); }
|
||||
|
||||
bool jit::JitSupportsAtomics() {
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
// Bug 1146902, bug 1077318: Enable Ion inlining of Atomics
|
||||
// operations on ARM only when the CPU has byte, halfword, and
|
||||
// doubleword load-exclusive and store-exclusive instructions,
|
||||
// until we can add support for systems that don't have those.
|
||||
return js::jit::HasLDSTREXBHD();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#ifndef jit_JitContext_h
|
||||
#define jit_JitContext_h
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Result.h"
|
||||
|
||||
#include "jit/CompileWrappers.h"
|
||||
#include "jit/JitOptions.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/Realm.h"
|
||||
#include "vm/TypeInference.h"
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class TempAllocator;
|
||||
|
||||
enum MethodStatus {
|
||||
Method_Error,
|
||||
Method_CantCompile,
|
||||
Method_Skipped,
|
||||
Method_Compiled
|
||||
};
|
||||
|
||||
enum class AbortReason : uint8_t {
|
||||
Alloc,
|
||||
Inlining,
|
||||
PreliminaryObjects,
|
||||
Disable,
|
||||
Error,
|
||||
NoAbort
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
using AbortReasonOr = mozilla::Result<V, AbortReason>;
|
||||
using mozilla::Err;
|
||||
using mozilla::Ok;
|
||||
|
||||
static_assert(sizeof(AbortReasonOr<Ok>) <= sizeof(uintptr_t),
|
||||
"Unexpected size of AbortReasonOr<Ok>");
|
||||
static_assert(sizeof(AbortReasonOr<bool>) <= sizeof(uintptr_t),
|
||||
"Unexpected size of AbortReasonOr<bool>");
|
||||
|
||||
// A JIT context is needed to enter into either an JIT method or an instance
|
||||
// of a JIT compiler. It points to a temporary allocator and the active
|
||||
// JSContext, either of which may be nullptr, and the active realm, which
|
||||
// will not be nullptr.
|
||||
|
||||
class JitContext {
|
||||
JitContext* prev_ = nullptr;
|
||||
CompileRealm* realm_ = nullptr;
|
||||
int assemblerCount_ = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Whether this thread is actively Ion compiling (does not include Wasm or
|
||||
// IonBuilder).
|
||||
bool inIonBackend_ = false;
|
||||
|
||||
// Whether this thread is actively Ion compiling in a context where a minor
|
||||
// GC could happen simultaneously. If this is true, this thread cannot use
|
||||
// any pointers into the nursery.
|
||||
bool inIonBackendSafeForMinorGC_ = false;
|
||||
|
||||
bool isCompilingWasm_ = false;
|
||||
bool oom_ = false;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Running context when executing on the main thread. Not available during
|
||||
// compilation.
|
||||
JSContext* cx = nullptr;
|
||||
|
||||
// Allocator for temporary memory during compilation.
|
||||
TempAllocator* temp = nullptr;
|
||||
|
||||
// Wrappers with information about the current runtime/realm for use
|
||||
// during compilation.
|
||||
CompileRuntime* runtime = nullptr;
|
||||
|
||||
// Constructor for compilations happening on the main thread.
|
||||
JitContext(JSContext* cx, TempAllocator* temp);
|
||||
|
||||
// Constructor for off-thread Ion compilations.
|
||||
JitContext(CompileRuntime* rt, CompileRealm* realm, TempAllocator* temp);
|
||||
|
||||
// Constructors for Wasm compilation.
|
||||
explicit JitContext(TempAllocator* temp);
|
||||
JitContext();
|
||||
|
||||
~JitContext();
|
||||
|
||||
int getNextAssemblerId() { return assemblerCount_++; }
|
||||
|
||||
CompileRealm* maybeRealm() const { return realm_; }
|
||||
CompileRealm* realm() const {
|
||||
MOZ_ASSERT(maybeRealm());
|
||||
return maybeRealm();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool isCompilingWasm() { return isCompilingWasm_; }
|
||||
bool hasOOM() { return oom_; }
|
||||
void setOOM() { oom_ = true; }
|
||||
|
||||
bool inIonBackend() const { return inIonBackend_; }
|
||||
|
||||
bool inIonBackendSafeForMinorGC() const {
|
||||
return inIonBackendSafeForMinorGC_;
|
||||
}
|
||||
|
||||
void enterIonBackend(bool safeForMinorGC) {
|
||||
MOZ_ASSERT(!inIonBackend_);
|
||||
MOZ_ASSERT(!inIonBackendSafeForMinorGC_);
|
||||
inIonBackend_ = true;
|
||||
inIonBackendSafeForMinorGC_ = safeForMinorGC;
|
||||
}
|
||||
void leaveIonBackend() {
|
||||
MOZ_ASSERT(inIonBackend_);
|
||||
inIonBackend_ = false;
|
||||
inIonBackendSafeForMinorGC_ = false;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Process-wide initialization of JIT data structures.
|
||||
MOZ_MUST_USE bool InitializeJit();
|
||||
|
||||
// Get and set the current JIT context.
|
||||
JitContext* GetJitContext();
|
||||
JitContext* MaybeGetJitContext();
|
||||
|
||||
void SetJitContext(JitContext* ctx);
|
||||
|
||||
enum JitExecStatus {
|
||||
// The method call had to be aborted due to a stack limit check. This
|
||||
// error indicates that Ion never attempted to clean up frames.
|
||||
JitExec_Aborted,
|
||||
|
||||
// The method call resulted in an error, and IonMonkey has cleaned up
|
||||
// frames.
|
||||
JitExec_Error,
|
||||
|
||||
// The method call succeeded and returned a value.
|
||||
JitExec_Ok
|
||||
};
|
||||
|
||||
static inline bool IsErrorStatus(JitExecStatus status) {
|
||||
return status == JitExec_Error || status == JitExec_Aborted;
|
||||
}
|
||||
|
||||
bool JitSupportsSimd();
|
||||
bool JitSupportsAtomics();
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_JitContext_h */
|
|
@ -138,10 +138,6 @@ DefaultJitOptions::DefaultJitOptions() {
|
|||
// Whether the IonMonkey JIT is enabled.
|
||||
SET_DEFAULT(ion, true);
|
||||
|
||||
// Whether the IonMonkey and Baseline JITs are enabled for Trusted Principals.
|
||||
// (Ignored if ion or baselineJit is set to true.)
|
||||
SET_DEFAULT(jitForTrustedPrincipals, false);
|
||||
|
||||
// Whether the RegExp JIT is enabled.
|
||||
SET_DEFAULT(nativeRegExp, true);
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ struct DefaultJitOptions {
|
|||
bool baselineInterpreter;
|
||||
bool baselineJit;
|
||||
bool ion;
|
||||
bool jitForTrustedPrincipals;
|
||||
bool nativeRegExp;
|
||||
bool forceInlineCaches;
|
||||
bool fullDebugChecks;
|
||||
|
@ -140,6 +139,10 @@ inline bool IsBaselineInterpreterEnabled() {
|
|||
#endif
|
||||
}
|
||||
|
||||
inline bool IsBaselineJitEnabled() {
|
||||
return IsBaselineInterpreterEnabled() && JitOptions.baselineJit;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef jit_Label_h
|
||||
#define jit_Label_h
|
||||
|
||||
#include "jit/JitContext.h"
|
||||
#include "jit/Ion.h"
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
|
|
@ -54,7 +54,6 @@ UNIFIED_SOURCES += [
|
|||
'IonOptimizationLevels.cpp',
|
||||
'Jit.cpp',
|
||||
'JitcodeMap.cpp',
|
||||
'JitContext.cpp',
|
||||
'JitFrames.cpp',
|
||||
'JitOptions.cpp',
|
||||
'JitScript.cpp',
|
||||
|
|
|
@ -5339,17 +5339,6 @@ JS_PUBLIC_API void JS_SetGlobalJitCompilerOption(JSContext* cx,
|
|||
JitSpew(js::jit::JitSpew_IonScripts, "Disable ion");
|
||||
}
|
||||
break;
|
||||
case JSJITCOMPILER_JIT_TRUSTEDPRINCIPALS_ENABLE:
|
||||
if (value == 1) {
|
||||
jit::JitOptions.jitForTrustedPrincipals = true;
|
||||
JitSpew(js::jit::JitSpew_IonScripts,
|
||||
"Enable ion and baselinejit for trusted principals");
|
||||
} else if (value == 0) {
|
||||
jit::JitOptions.jitForTrustedPrincipals = false;
|
||||
JitSpew(js::jit::JitSpew_IonScripts,
|
||||
"Disable ion and baselinejit for trusted principals");
|
||||
}
|
||||
break;
|
||||
case JSJITCOMPILER_ION_FREQUENT_BAILOUT_THRESHOLD:
|
||||
if (value == uint32_t(-1)) {
|
||||
jit::DefaultJitOptions defaultValues;
|
||||
|
|
|
@ -2767,7 +2767,6 @@ extern JS_PUBLIC_API void JS_SetOffthreadIonCompilationEnabled(JSContext* cx,
|
|||
Register(ION_GVN_ENABLE, "ion.gvn.enable") \
|
||||
Register(ION_FORCE_IC, "ion.forceinlineCaches") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
Register(JIT_TRUSTEDPRINCIPALS_ENABLE, "jit_trustedprincipals.enable") \
|
||||
Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
|
||||
Register(ION_FREQUENT_BAILOUT_THRESHOLD, "ion.frequent-bailout-threshold") \
|
||||
Register(BASELINE_INTERPRETER_ENABLE, "blinterp.enable") \
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "jsapi.h"
|
||||
|
||||
#include "ds/Fifo.h"
|
||||
#include "jit/JitContext.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "js/BinASTFormat.h" // JS::BinASTFormat
|
||||
#include "js/CompileOptions.h"
|
||||
#include "js/SourceText.h"
|
||||
|
|
|
@ -789,8 +789,6 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
|
|||
bool useBaselineInterp = Preferences::GetBool(JS_OPTIONS_DOT_STR "blinterp");
|
||||
bool useBaselineJit = Preferences::GetBool(JS_OPTIONS_DOT_STR "baselinejit");
|
||||
bool useIon = Preferences::GetBool(JS_OPTIONS_DOT_STR "ion");
|
||||
bool useJitForTrustedPrincipals =
|
||||
Preferences::GetBool(JS_OPTIONS_DOT_STR "jit_trustedprincipals");
|
||||
bool useNativeRegExp =
|
||||
Preferences::GetBool(JS_OPTIONS_DOT_STR "native_regexp");
|
||||
|
||||
|
@ -840,7 +838,6 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
|
|||
useBaselineInterp = false;
|
||||
useBaselineJit = false;
|
||||
useIon = false;
|
||||
useJitForTrustedPrincipals = false;
|
||||
useNativeRegExp = false;
|
||||
}
|
||||
}
|
||||
|
@ -850,8 +847,6 @@ static void LoadStartupJSPrefs(XPCJSContext* xpccx) {
|
|||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_ENABLE,
|
||||
useBaselineJit);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_ENABLE, useIon);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_JIT_TRUSTEDPRINCIPALS_ENABLE,
|
||||
useJitForTrustedPrincipals);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_NATIVE_REGEXP_ENABLE,
|
||||
useNativeRegExp);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче