diff options
Diffstat (limited to 'js/src/jit/Ion.h')
-rw-r--r-- | js/src/jit/Ion.h | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h new file mode 100644 index 0000000000..018eea5cb5 --- /dev/null +++ b/js/src/jit/Ion.h @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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_Ion_h +#define jit_Ion_h + +#include "mozilla/MemoryReporting.h" + +#include "jscntxt.h" +#include "jscompartment.h" + +#include "jit/CompileWrappers.h" +#include "jit/JitOptions.h" + +namespace js { +namespace jit { + +class TempAllocator; + +enum MethodStatus +{ + Method_Error, + Method_CantCompile, + Method_Skipped, + Method_Compiled +}; + +enum AbortReason { + AbortReason_Alloc, + AbortReason_Inlining, + AbortReason_PreliminaryObjects, + AbortReason_Disable, + AbortReason_Error, + AbortReason_NoAbort +}; + +// 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 compartment, which +// will not be nullptr. + +class JitContext +{ + public: + JitContext(JSContext* cx, TempAllocator* temp); + JitContext(ExclusiveContext* cx, TempAllocator* temp); + JitContext(CompileRuntime* rt, CompileCompartment* comp, TempAllocator* temp); + JitContext(CompileRuntime* rt, TempAllocator* temp); + explicit JitContext(CompileRuntime* rt); + explicit JitContext(TempAllocator* temp); + JitContext(); + ~JitContext(); + + // Running context when executing on the main thread. Not available during + // compilation. + JSContext* cx; + + // Allocator for temporary memory during compilation. + TempAllocator* temp; + + // Wrappers with information about the current runtime/compartment for use + // during compilation. + CompileRuntime* runtime; + CompileCompartment* compartment; + + bool onMainThread() const { + return runtime && runtime->onMainThread(); + } + bool hasProfilingScripts() const { + return runtime && !!runtime->profilingScripts(); + } + + int getNextAssemblerId() { + return assemblerCount_++; + } + private: + JitContext* prev_; + int assemblerCount_; +}; + +// Initialize Ion statically for all JSRuntimes. +MOZ_MUST_USE bool InitializeIon(); + +// Get and set the current JIT context. +JitContext* GetJitContext(); +JitContext* MaybeGetJitContext(); + +void SetJitContext(JitContext* ctx); + +bool CanIonCompileScript(JSContext* cx, JSScript* script, bool osr); + +MOZ_MUST_USE bool IonCompileScriptForBaseline(JSContext* cx, BaselineFrame* frame, jsbytecode* pc); + +MethodStatus CanEnter(JSContext* cx, RunState& state); +MethodStatus CanEnterUsingFastInvoke(JSContext* cx, HandleScript script, uint32_t numActualArgs); + +MethodStatus +Recompile(JSContext* cx, HandleScript script, BaselineFrame* osrFrame, jsbytecode* osrPc, + 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; + +MOZ_MUST_USE bool SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, + MutableHandle<GCVector<Value>> vals); + +JitExecStatus IonCannon(JSContext* cx, RunState& state); + +// Used to enter Ion from C++ natives like Array.map. Called from FastInvokeGuard. +JitExecStatus FastInvoke(JSContext* cx, HandleFunction fun, CallArgs& args); + +// Walk the stack and invalidate active Ion frames for the invalid scripts. +void Invalidate(TypeZone& types, FreeOp* fop, + const RecompileInfoVector& invalid, bool resetUses = true, + bool cancelOffThread = true); +void Invalidate(JSContext* cx, const RecompileInfoVector& invalid, bool resetUses = true, + bool cancelOffThread = true); +void Invalidate(JSContext* cx, JSScript* script, bool resetUses = true, + bool cancelOffThread = true); + +void ToggleBarriers(JS::Zone* zone, bool needs); + +class IonBuilder; +class MIRGenerator; +class LIRGraph; +class CodeGenerator; + +MOZ_MUST_USE bool OptimizeMIR(MIRGenerator* mir); +LIRGraph* GenerateLIR(MIRGenerator* mir); +CodeGenerator* GenerateCode(MIRGenerator* mir, LIRGraph* lir); +CodeGenerator* CompileBackEnd(MIRGenerator* mir); + +void AttachFinishedCompilations(JSContext* cx); +void FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder, + const AutoLockHelperThreadState& lock); + +void LinkIonScript(JSContext* cx, HandleScript calleescript); +uint8_t* LazyLinkTopActivation(JSContext* cx); + +static inline bool +IsIonEnabled(JSContext* cx) +{ + // The ARM64 Ion engine is not yet implemented. +#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64) + return false; +#else + return cx->options().ion() && + cx->options().baseline() && + cx->runtime()->jitSupportsFloatingPoint; +#endif +} + +inline bool +IsIonInlinablePC(jsbytecode* pc) { + // CALL, FUNCALL, FUNAPPLY, EVAL, NEW (Normal Callsites) + // GETPROP, CALLPROP, and LENGTH. (Inlined Getters) + // SETPROP, SETNAME, SETGNAME (Inlined Setters) + return IsCallPC(pc) || IsGetPropPC(pc) || IsSetPropPC(pc); +} + +inline bool +TooManyActualArguments(unsigned nargs) +{ + return nargs > JitOptions.maxStackArgs; +} + +inline bool +TooManyFormalArguments(unsigned nargs) +{ + return nargs >= SNAPSHOT_MAX_NARGS || TooManyActualArguments(nargs); +} + +inline size_t +NumLocalsAndArgs(JSScript* script) +{ + size_t num = 1 /* this */ + script->nfixed(); + if (JSFunction* fun = script->functionNonDelazifying()) + num += fun->nargs(); + return num; +} + +bool OffThreadCompilationAvailable(JSContext* cx); + +void ForbidCompilation(JSContext* cx, JSScript* script); + +void PurgeCaches(JSScript* script); +size_t SizeOfIonData(JSScript* script, mozilla::MallocSizeOf mallocSizeOf); +void DestroyJitScripts(FreeOp* fop, JSScript* script); +void TraceJitScripts(JSTracer* trc, JSScript* script); + +bool JitSupportsFloatingPoint(); +bool JitSupportsUnalignedAccesses(); +bool JitSupportsSimd(); +bool JitSupportsAtomics(); + +} // namespace jit +} // namespace js + +#endif /* jit_Ion_h */ |