tor-browser

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

MIRGenerator.h (6194B)


      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_MIRGenerator_h
      8 #define jit_MIRGenerator_h
      9 
     10 // This file declares the data structures used to build a control-flow graph
     11 // containing MIR.
     12 
     13 #include "mozilla/Assertions.h"
     14 #include "mozilla/Atomics.h"
     15 #include "mozilla/Attributes.h"
     16 #include "mozilla/Result.h"
     17 
     18 #include <stdarg.h>
     19 #include <stddef.h>
     20 #include <stdint.h>
     21 
     22 #include "jit/CompilationDependencyTracker.h"
     23 #include "jit/CompileInfo.h"
     24 #include "jit/CompileWrappers.h"
     25 #include "jit/JitAllocPolicy.h"
     26 #include "jit/JitContext.h"
     27 #include "jit/JitSpewer.h"
     28 #include "jit/PerfSpewer.h"
     29 #include "js/Utility.h"
     30 #include "vm/GeckoProfiler.h"
     31 
     32 namespace js {
     33 namespace jit {
     34 
     35 class BacktrackingAllocator;
     36 class JitRuntime;
     37 class MIRGraph;
     38 class OptimizationInfo;
     39 
     40 class MIRGenerator final {
     41 public:
     42  MIRGenerator(CompileRealm* realm, const JitCompileOptions& options,
     43               TempAllocator* alloc, MIRGraph* graph,
     44               const CompileInfo* outerInfo,
     45               const OptimizationInfo* optimizationInfo,
     46               const wasm::CodeMetadata* wasmCodeMeta = nullptr);
     47 
     48  TempAllocator& alloc() { return *alloc_; }
     49  MIRGraph& graph() { return *graph_; }
     50  [[nodiscard]] bool ensureBallast() { return alloc().ensureBallast(); }
     51  const JitRuntime* jitRuntime() const { return runtime->jitRuntime(); }
     52  const CompileInfo& outerInfo() const { return *outerInfo_; }
     53  const OptimizationInfo& optimizationInfo() const {
     54    return *optimizationInfo_;
     55  }
     56  bool hasProfilingScripts() const {
     57    return runtime && runtime->profilingScripts();
     58  }
     59 
     60  template <typename T>
     61  js::lifo_alloc_pointer<T*> allocate(size_t count = 1) {
     62    size_t bytes;
     63    if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) {
     64      return nullptr;
     65    }
     66    return static_cast<T*>(alloc().allocate(bytes));
     67  }
     68 
     69  // Set an error state and prints a message. Returns false so errors can be
     70  // propagated up.
     71  mozilla::GenericErrorResult<AbortReason> abort(AbortReason r);
     72  mozilla::GenericErrorResult<AbortReason> abort(AbortReason r,
     73                                                 const char* message, ...)
     74      MOZ_FORMAT_PRINTF(3, 4);
     75 
     76  mozilla::GenericErrorResult<AbortReason> abortFmt(AbortReason r,
     77                                                    const char* message,
     78                                                    va_list ap)
     79      MOZ_FORMAT_PRINTF(3, 0);
     80 
     81  // Collect the evaluation result of phases after WarpOracle, such that
     82  // off-thread compilation can report what error got encountered.
     83  void setOffThreadStatus(AbortReasonOr<Ok>&& result) {
     84    MOZ_ASSERT(offThreadStatus_.isOk());
     85    offThreadStatus_ = std::move(result);
     86  }
     87  const AbortReasonOr<Ok>& getOffThreadStatus() const {
     88    return offThreadStatus_;
     89  }
     90 
     91  [[nodiscard]] bool instrumentedProfiling() {
     92    if (!instrumentedProfilingIsCached_) {
     93      instrumentedProfiling_ = runtime->geckoProfiler().enabled();
     94      instrumentedProfilingIsCached_ = true;
     95    }
     96    return instrumentedProfiling_;
     97  }
     98 
     99  bool isProfilerInstrumentationEnabled() {
    100    return !compilingWasm() && instrumentedProfiling();
    101  }
    102 
    103  gc::Heap initialStringHeap() const {
    104    return stringsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured;
    105  }
    106 
    107  gc::Heap initialBigIntHeap() const {
    108    return bigIntsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured;
    109  }
    110 
    111  // Whether the main thread is trying to cancel this build.
    112  bool shouldCancel(const char* why) const { return cancelBuild_; }
    113  void cancel() { cancelBuild_ = true; }
    114 
    115  bool compilingWasm() const { return outerInfo_->compilingWasm(); }
    116 
    117  uint32_t wasmMaxStackArgBytes() const {
    118    MOZ_ASSERT(compilingWasm());
    119    return wasmMaxStackArgBytes_;
    120  }
    121  void accumulateWasmMaxStackArgBytes(uint32_t n) {
    122    MOZ_ASSERT(compilingWasm());
    123    wasmMaxStackArgBytes_ = std::max(n, wasmMaxStackArgBytes_);
    124  }
    125 
    126  void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; }
    127  bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; }
    128 
    129  void setNeedsStaticStackAlignment() { needsStaticStackAlignment_ = true; }
    130  bool needsStaticStackAlignment() const { return needsStaticStackAlignment_; }
    131 
    132 public:
    133  CompileRealm* realm;
    134  CompileRuntime* runtime;
    135 
    136 private:
    137  // The CompileInfo for the outermost script.
    138  const CompileInfo* outerInfo_;
    139  const OptimizationInfo* optimizationInfo_;
    140  const wasm::CodeMetadata* wasmCodeMeta_;
    141 
    142  TempAllocator* alloc_;
    143  MIRGraph* graph_;
    144  AbortReasonOr<Ok> offThreadStatus_;
    145  mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_;
    146 
    147  uint32_t wasmMaxStackArgBytes_;
    148  bool needsOverrecursedCheck_;
    149  bool needsStaticStackAlignment_;
    150 
    151  bool instrumentedProfiling_;
    152  bool instrumentedProfilingIsCached_;
    153  bool stringsCanBeInNursery_;
    154  bool bigIntsCanBeInNursery_;
    155 
    156  bool disableLICM_ = false;
    157 
    158 public:
    159  void disableLICM() { disableLICM_ = true; }
    160  bool licmEnabled() const;
    161  bool branchHintingEnabled() const;
    162 
    163  const wasm::CodeMetadata* wasmCodeMeta() const {
    164    MOZ_ASSERT(wasmCodeMeta_);
    165    return wasmCodeMeta_;
    166  }
    167 
    168 public:
    169  const JitCompileOptions options;
    170 
    171 private:
    172 #ifdef JS_JITSPEW
    173  GraphSpewer* graphSpewer_ = nullptr;
    174 #endif
    175  JitSpewGraphSpewer jitSpewer_;
    176  IonPerfSpewer perfSpewer_;
    177 
    178 public:
    179 #ifdef JS_JITSPEW
    180  void setGraphSpewer(GraphSpewer* graphSpewer) {
    181    MOZ_ASSERT(!graphSpewer_);
    182    graphSpewer_ = graphSpewer;
    183  }
    184 #endif
    185  IonPerfSpewer& perfSpewer() { return perfSpewer_; }
    186 
    187  void spewBeginFunction(JSScript* function);
    188  void spewBeginWasmFunction(unsigned funcIndex);
    189  void spewPass(const char* name, BacktrackingAllocator* ra = nullptr);
    190  void spewEndFunction();
    191 
    192  CompilationDependencyTracker tracker;
    193 };
    194 
    195 class AutoSpewEndFunction {
    196 private:
    197  MIRGenerator* mir_;
    198 
    199 public:
    200  explicit AutoSpewEndFunction(MIRGenerator* mir) : mir_(mir) {}
    201  ~AutoSpewEndFunction();
    202 };
    203 
    204 }  // namespace jit
    205 }  // namespace js
    206 
    207 #endif /* jit_MIRGenerator_h */