diff options
Diffstat (limited to 'js/src/jit/Ion.h')
-rw-r--r-- | js/src/jit/Ion.h | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h new file mode 100644 index 0000000000..f48aa71726 --- /dev/null +++ b/js/src/jit/Ion.h @@ -0,0 +1,154 @@ +/* -*- 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_Ion_h +#define jit_Ion_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/Likely.h" +#include "mozilla/MemoryReporting.h" + +#include <stddef.h> +#include <stdint.h> + +#include "jsfriendapi.h" +#include "jspubtd.h" + +#include "jit/BaselineJIT.h" +#include "jit/IonTypes.h" +#include "jit/JitContext.h" +#include "jit/JitOptions.h" +#include "js/Principals.h" +#include "js/TypeDecls.h" +#include "vm/BytecodeUtil.h" +#include "vm/JSContext.h" +#include "vm/JSFunction.h" +#include "vm/JSScript.h" + +namespace js { + +class RunState; + +namespace jit { + +class BaselineFrame; + +bool CanIonCompileScript(JSContext* cx, JSScript* script); +bool CanIonInlineScript(JSScript* script); + +[[nodiscard]] bool IonCompileScriptForBaselineAtEntry(JSContext* cx, + BaselineFrame* frame); + +struct IonOsrTempData { + void* jitcode; + uint8_t* baselineFrame; + + static constexpr size_t offsetOfJitCode() { + return offsetof(IonOsrTempData, jitcode); + } + static constexpr size_t offsetOfBaselineFrame() { + return offsetof(IonOsrTempData, baselineFrame); + } +}; + +[[nodiscard]] bool IonCompileScriptForBaselineOSR(JSContext* cx, + BaselineFrame* frame, + uint32_t frameSize, + jsbytecode* pc, + IonOsrTempData** infoPtr); + +MethodStatus CanEnterIon(JSContext* cx, RunState& state); + +class MIRGenerator; +class LIRGraph; +class CodeGenerator; +class LazyLinkExitFrameLayout; +class WarpSnapshot; + +[[nodiscard]] bool OptimizeMIR(MIRGenerator* mir); +LIRGraph* GenerateLIR(MIRGenerator* mir); +CodeGenerator* GenerateCode(MIRGenerator* mir, LIRGraph* lir); +CodeGenerator* CompileBackEnd(MIRGenerator* mir, WarpSnapshot* snapshot); + +void LinkIonScript(JSContext* cx, HandleScript calleescript); +uint8_t* LazyLinkTopActivation(JSContext* cx, LazyLinkExitFrameLayout* frame); + +inline bool IsIonInlinableGetterOrSetterOp(JSOp op) { + // JSOp::GetProp, JSOp::CallProp, JSOp::Length, JSOp::GetElem, + // and JSOp::CallElem. (Inlined Getters) + // JSOp::SetProp, JSOp::SetName, JSOp::SetGName (Inlined Setters) + return IsGetPropOp(op) || IsGetElemOp(op) || IsSetPropOp(op); +} + +inline bool IsIonInlinableOp(JSOp op) { + // JSOp::Call, JSOp::FunCall, JSOp::Eval, JSOp::New (Normal Callsites) or an + // inlinable getter or setter. + return (IsInvokeOp(op) && !IsSpreadOp(op)) || + IsIonInlinableGetterOrSetterOp(op); +} + +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->function()) { + num += fun->nargs(); + } + return num; +} + +// Debugging RAII class which marks the current thread as performing an Ion +// backend compilation. +class MOZ_RAII AutoEnterIonBackend { + public: + AutoEnterIonBackend() { +#ifdef DEBUG + JitContext* jcx = GetJitContext(); + jcx->enterIonBackend(); +#endif + } + +#ifdef DEBUG + ~AutoEnterIonBackend() { + JitContext* jcx = GetJitContext(); + jcx->leaveIonBackend(); + } +#endif +}; + +bool OffThreadCompilationAvailable(JSContext* cx); + +void ForbidCompilation(JSContext* cx, JSScript* script); + +size_t SizeOfIonData(JSScript* script, mozilla::MallocSizeOf mallocSizeOf); + +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; +} + +// Implemented per-platform. Returns true if the flags will not require +// further (lazy) computation. +bool CPUFlagsHaveBeenComputed(); + +} // namespace jit +} // namespace js + +#endif /* jit_Ion_h */ |