tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

JitContext.h (4749B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef jit_JitContext_h
      8 #define jit_JitContext_h
      9 
     10 #include "mozilla/Assertions.h"
     11 #include "mozilla/Result.h"
     12 
     13 #include <stdint.h>
     14 
     15 #include "jstypes.h"
     16 
     17 struct JS_PUBLIC_API JSContext;
     18 
     19 namespace js {
     20 namespace jit {
     21 
     22 class CompileRealm;
     23 class CompileRuntime;
     24 class TempAllocator;
     25 
     26 enum MethodStatus {
     27  Method_Error,
     28  Method_CantCompile,
     29  Method_Skipped,
     30  Method_Compiled
     31 };
     32 
     33 // Use only even, non-zero values for errors, to allow using the UnusedZero and
     34 // HasFreeLSB optimizations for mozilla::Result (see specializations of
     35 // UnusedZero/HasFreeLSB below).
     36 enum class AbortReason : uint8_t {
     37  NoAbort,
     38  Alloc = 2,
     39  Disable = 4,
     40  Error = 6,
     41 };
     42 }  // namespace jit
     43 }  // namespace js
     44 
     45 namespace mozilla::detail {
     46 
     47 template <>
     48 struct UnusedZero<js::jit::AbortReason> : UnusedZeroEnum<js::jit::AbortReason> {
     49 };
     50 
     51 template <>
     52 struct HasFreeLSB<js::jit::AbortReason> {
     53  static const bool value = true;
     54 };
     55 
     56 }  // namespace mozilla::detail
     57 
     58 namespace js {
     59 namespace jit {
     60 
     61 template <typename V>
     62 using AbortReasonOr = mozilla::Result<V, AbortReason>;
     63 using mozilla::Err;
     64 using mozilla::Ok;
     65 
     66 static_assert(sizeof(AbortReasonOr<Ok>) <= sizeof(uintptr_t),
     67              "Unexpected size of AbortReasonOr<Ok>");
     68 static_assert(mozilla::detail::SelectResultImpl<bool, AbortReason>::value ==
     69              mozilla::detail::PackingStrategy::NullIsOk);
     70 static_assert(sizeof(AbortReasonOr<bool>) <= sizeof(uintptr_t),
     71              "Unexpected size of AbortReasonOr<bool>");
     72 static_assert(sizeof(AbortReasonOr<uint16_t*>) == sizeof(uintptr_t),
     73              "Unexpected size of AbortReasonOr<uint16_t*>");
     74 
     75 // A JIT context is needed for parts of the compiler backend such as the
     76 // MacroAssembler. It points to the JSContext (nullptr for off-thread
     77 // compilations or Wasm compilations) and also stores some extra information,
     78 // most of it only used in debug builds.
     79 //
     80 // JIT contexts must not be nested.
     81 
     82 class MOZ_RAII JitContext {
     83 #ifdef DEBUG
     84  // Whether this thread is actively Baseline compiling offthread
     85  bool inBaselineBackend_ = false;
     86 
     87  // Whether this thread is actively Ion compiling (does not include Wasm or
     88  // WarpOracle).
     89  bool inIonBackend_ = false;
     90 
     91  bool isCompilingWasm_ = false;
     92  bool oom_ = false;
     93 #endif
     94 
     95 public:
     96  // Running context when compiling on the main thread. Not available during
     97  // off-thread compilation.
     98  JSContext* cx = nullptr;
     99 
    100  // Wrapper with information about the current runtime. nullptr for Wasm
    101  // compilations.
    102  CompileRuntime* runtime = nullptr;
    103 
    104  // Constructor for compilations happening on the main thread.
    105  explicit JitContext(JSContext* cx);
    106 
    107  // Constructor for off-thread Ion compilations.
    108  explicit JitContext(CompileRuntime* rt);
    109 
    110  // Constructor for Wasm compilation.
    111  JitContext();
    112 
    113  ~JitContext();
    114 
    115 #ifdef DEBUG
    116  bool isCompilingWasm() { return isCompilingWasm_; }
    117  bool setIsCompilingWasm(bool flag) {
    118    bool oldFlag = isCompilingWasm_;
    119    isCompilingWasm_ = flag;
    120    return oldFlag;
    121  }
    122  bool hasOOM() { return oom_; }
    123  void setOOM() { oom_ = true; }
    124 
    125  bool inBaselineBackend() const { return inBaselineBackend_; }
    126  bool inIonBackend() const { return inIonBackend_; }
    127 
    128  void enterBaselineBackend() {
    129    MOZ_ASSERT(!inBaselineBackend_);
    130    inBaselineBackend_ = true;
    131  }
    132  void leaveBaselineBackend() {
    133    MOZ_ASSERT(inBaselineBackend_);
    134    inBaselineBackend_ = false;
    135  }
    136  void enterIonBackend() {
    137    MOZ_ASSERT(!inIonBackend_);
    138    inIonBackend_ = true;
    139  }
    140  void leaveIonBackend() {
    141    MOZ_ASSERT(inIonBackend_);
    142    inIonBackend_ = false;
    143  }
    144 #endif
    145 };
    146 
    147 // Process-wide initialization and shutdown of JIT data structures.
    148 [[nodiscard]] bool InitializeJit();
    149 void ShutdownJit();
    150 
    151 // Get and set the current JIT context.
    152 JitContext* GetJitContext();
    153 JitContext* MaybeGetJitContext();
    154 
    155 void SetJitContext(JitContext* ctx);
    156 
    157 enum JitExecStatus {
    158  // The method call had to be aborted due to a stack limit check. This
    159  // error indicates that Ion never attempted to clean up frames.
    160  JitExec_Aborted,
    161 
    162  // The method call resulted in an error, and IonMonkey has cleaned up
    163  // frames.
    164  JitExec_Error,
    165 
    166  // The method call succeeded and returned a value.
    167  JitExec_Ok
    168 };
    169 
    170 static inline bool IsErrorStatus(JitExecStatus status) {
    171  return status == JitExec_Error || status == JitExec_Aborted;
    172 }
    173 
    174 bool JitSupportsWasmSimd();
    175 bool JitSupportsAtomics();
    176 
    177 }  // namespace jit
    178 }  // namespace js
    179 
    180 #endif /* jit_JitContext_h */