summaryrefslogtreecommitdiff
path: root/js/src/jit/Ion.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/Ion.h')
-rw-r--r--js/src/jit/Ion.h221
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 */