Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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 */
#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)) ||
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 {
AutoEnterIonBackend() {
#ifdef DEBUG
JitContext* jcx = GetJitContext();
#ifdef DEBUG
~AutoEnterIonBackend() {
JitContext* jcx = GetJitContext();
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) &&
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 */