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 }