tor-browser

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

JitContext.cpp (3961B)


      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 #include "jit/JitContext.h"
      8 
      9 #include "mozilla/Assertions.h"
     10 #include "mozilla/ThreadLocal.h"
     11 
     12 #include <stdlib.h>
     13 
     14 #include "jit/CacheIRSpewer.h"
     15 #include "jit/CompileWrappers.h"
     16 #include "jit/Ion.h"
     17 #include "jit/JitCode.h"
     18 #include "jit/JitOptions.h"
     19 #include "jit/JitSpewer.h"
     20 #include "jit/MacroAssembler.h"
     21 #include "jit/PerfSpewer.h"
     22 #include "js/HeapAPI.h"
     23 #include "vm/JSContext.h"
     24 
     25 #ifdef JS_CODEGEN_ARM64
     26 #  include "jit/arm64/vixl/Cpu-vixl.h"
     27 #endif
     28 
     29 #if defined(ANDROID)
     30 #  include <sys/system_properties.h>
     31 #endif
     32 
     33 using namespace js;
     34 using namespace js::jit;
     35 
     36 namespace js::jit {
     37 class TempAllocator;
     38 }
     39 
     40 // Assert that JitCode is gc::Cell aligned.
     41 static_assert(sizeof(JitCode) % gc::CellAlignBytes == 0);
     42 
     43 static MOZ_THREAD_LOCAL(JitContext*) TlsJitContext;
     44 
     45 static JitContext* CurrentJitContext() {
     46  if (!TlsJitContext.init()) {
     47    return nullptr;
     48  }
     49  return TlsJitContext.get();
     50 }
     51 
     52 void jit::SetJitContext(JitContext* ctx) {
     53  MOZ_ASSERT(!TlsJitContext.get());
     54  TlsJitContext.set(ctx);
     55 }
     56 
     57 JitContext* jit::GetJitContext() {
     58  MOZ_ASSERT(CurrentJitContext());
     59  return CurrentJitContext();
     60 }
     61 
     62 JitContext* jit::MaybeGetJitContext() { return CurrentJitContext(); }
     63 
     64 JitContext::JitContext(CompileRuntime* rt) : runtime(rt) {
     65  MOZ_ASSERT(rt);
     66  SetJitContext(this);
     67 }
     68 
     69 JitContext::JitContext(JSContext* cx)
     70    : cx(cx), runtime(CompileRuntime::get(cx->runtime())) {
     71  SetJitContext(this);
     72 }
     73 
     74 JitContext::JitContext() {
     75 #ifdef DEBUG
     76  isCompilingWasm_ = true;
     77 #endif
     78  SetJitContext(this);
     79 }
     80 
     81 JitContext::~JitContext() {
     82  MOZ_ASSERT(TlsJitContext.get() == this);
     83  TlsJitContext.set(nullptr);
     84 }
     85 
     86 bool jit::InitializeJit() {
     87  if (!TlsJitContext.init()) {
     88    return false;
     89  }
     90 
     91  CheckLogging();
     92 
     93 #ifdef JS_CACHEIR_SPEW
     94  const char* env = getenv("CACHEIR_LOGS");
     95  if (env && env[0] && env[0] != '0') {
     96    CacheIRSpewer::singleton().init(env);
     97  }
     98 #endif
     99 
    100 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
    101  // Compute flags.
    102  js::jit::CPUInfo::ComputeFlags();
    103 #endif
    104 
    105 #if defined(JS_CODEGEN_ARM)
    106  ARMFlags::Init();
    107 #endif
    108 
    109 #ifdef JS_CODEGEN_ARM64
    110  // Initialize instruction cache flushing.
    111  vixl::CPU::SetUp();
    112 
    113  // Initialize supported CPU features.
    114  ARM64Flags::Init();
    115 #endif
    116 
    117 #ifdef JS_CODEGEN_MIPS64
    118  // Compute flags.
    119  MIPSFlags::Init();
    120 #endif
    121 
    122 #ifdef JS_CODEGEN_RISCV64
    123  RVFlags::Init();
    124 #endif
    125 
    126 #ifndef JS_CODEGEN_NONE
    127  MOZ_ASSERT(js::jit::CPUFlagsHaveBeenComputed());
    128 #endif
    129 
    130  // Note: jit flags need to be initialized after the ARMFlags::Init call above.
    131  // This is the final point where we can set disableJitBackend = true, before
    132  // we use this flag below with the HasJitBackend call.
    133  if (!MacroAssembler::SupportsFloatingPoint()) {
    134    JitOptions.disableJitBackend = true;
    135  }
    136  JitOptions.supportsUnalignedAccesses =
    137      MacroAssembler::SupportsUnalignedAccesses();
    138 
    139  if (HasJitBackend()) {
    140    if (!InitProcessExecutableMemory()) {
    141      return false;
    142    }
    143  }
    144 
    145  PerfSpewer::Init();
    146  return true;
    147 }
    148 
    149 void jit::ShutdownJit() {
    150  if (HasJitBackend() && !JSRuntime::hasLiveRuntimes()) {
    151    ReleaseProcessExecutableMemory();
    152  }
    153 }
    154 
    155 bool jit::JitSupportsWasmSimd() {
    156 #if defined(ENABLE_WASM_SIMD)
    157  return js::jit::MacroAssembler::SupportsWasmSimd();
    158 #else
    159  return false;
    160 #endif
    161 }
    162 
    163 bool jit::JitSupportsAtomics() {
    164 #if defined(JS_CODEGEN_ARM)
    165  // Bug 1146902, bug 1077318: Enable Ion inlining of Atomics
    166  // operations on ARM only when the CPU has byte, halfword, and
    167  // doubleword load-exclusive and store-exclusive instructions,
    168  // until we can add support for systems that don't have those.
    169  return js::jit::ARMFlags::HasLDSTREXBHD();
    170 #else
    171  return true;
    172 #endif
    173 }