summaryrefslogtreecommitdiffstats
path: root/js/src/jit/JitContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/JitContext.h')
-rw-r--r--js/src/jit/JitContext.h168
1 files changed, 168 insertions, 0 deletions
diff --git a/js/src/jit/JitContext.h b/js/src/jit/JitContext.h
new file mode 100644
index 0000000000..b19f2dd371
--- /dev/null
+++ b/js/src/jit/JitContext.h
@@ -0,0 +1,168 @@
+/* -*- 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/Assertions.h"
+#include "mozilla/Result.h"
+
+#include <stdint.h>
+
+#include "jstypes.h"
+
+struct JS_PUBLIC_API JSContext;
+
+namespace js {
+namespace jit {
+
+class CompileRealm;
+class CompileRuntime;
+class TempAllocator;
+
+enum MethodStatus {
+ Method_Error,
+ Method_CantCompile,
+ Method_Skipped,
+ Method_Compiled
+};
+
+// Use only even, non-zero values for errors, to allow using the UnusedZero and
+// HasFreeLSB optimizations for mozilla::Result (see specializations of
+// UnusedZero/HasFreeLSB below).
+enum class AbortReason : uint8_t {
+ NoAbort,
+ Alloc = 2,
+ Disable = 4,
+ Error = 6,
+};
+} // namespace jit
+} // namespace js
+
+namespace mozilla::detail {
+
+template <>
+struct UnusedZero<js::jit::AbortReason> : UnusedZeroEnum<js::jit::AbortReason> {
+};
+
+template <>
+struct HasFreeLSB<js::jit::AbortReason> {
+ static const bool value = true;
+};
+
+} // namespace mozilla::detail
+
+namespace js {
+namespace jit {
+
+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(mozilla::detail::SelectResultImpl<bool, AbortReason>::value ==
+ mozilla::detail::PackingStrategy::NullIsOk);
+static_assert(sizeof(AbortReasonOr<bool>) <= sizeof(uintptr_t),
+ "Unexpected size of AbortReasonOr<bool>");
+static_assert(sizeof(AbortReasonOr<uint16_t*>) == sizeof(uintptr_t),
+ "Unexpected size of AbortReasonOr<uint16_t*>");
+
+// A JIT context is needed for parts of the compiler backend such as the
+// MacroAssembler. It points to the JSContext (nullptr for off-thread
+// compilations or Wasm compilations) and also stores some extra information,
+// most of it only used in debug builds.
+//
+// JIT contexts must not be nested.
+
+class MOZ_RAII JitContext {
+#ifdef DEBUG
+ // Whether this thread is actively Ion compiling (does not include Wasm or
+ // WarpOracle).
+ bool inIonBackend_ = false;
+
+ bool isCompilingWasm_ = false;
+ bool oom_ = false;
+#endif
+
+ public:
+ // Running context when compiling on the main thread. Not available during
+ // off-thread compilation.
+ JSContext* cx = nullptr;
+
+ // Wrapper with information about the current runtime. nullptr for Wasm
+ // compilations.
+ CompileRuntime* runtime = nullptr;
+
+ // Constructor for compilations happening on the main thread.
+ explicit JitContext(JSContext* cx);
+
+ // Constructor for off-thread Ion compilations.
+ explicit JitContext(CompileRuntime* rt);
+
+ // Constructor for Wasm compilation.
+ JitContext();
+
+ ~JitContext();
+
+#ifdef DEBUG
+ bool isCompilingWasm() { return isCompilingWasm_; }
+ bool setIsCompilingWasm(bool flag) {
+ bool oldFlag = isCompilingWasm_;
+ isCompilingWasm_ = flag;
+ return oldFlag;
+ }
+ bool hasOOM() { return oom_; }
+ void setOOM() { oom_ = true; }
+
+ bool inIonBackend() const { return inIonBackend_; }
+
+ void enterIonBackend() {
+ MOZ_ASSERT(!inIonBackend_);
+ inIonBackend_ = true;
+ }
+ void leaveIonBackend() {
+ MOZ_ASSERT(inIonBackend_);
+ inIonBackend_ = false;
+ }
+#endif
+};
+
+// Process-wide initialization and shutdown of JIT data structures.
+[[nodiscard]] bool InitializeJit();
+void ShutdownJit();
+
+// 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 JitSupportsWasmSimd();
+bool JitSupportsAtomics();
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_JitContext_h */