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/JitCode.h"
17 #include "jit/JitOptions.h"
18 #include "jit/JitSpewer.h"
19 #include "jit/MacroAssembler.h"
20 #include "jit/PerfSpewer.h"
21 #include "js/HeapAPI.h"
22 #include "vm/JSContext.h"
23
24 #if defined(ANDROID)
25 # include <sys/system_properties.h>
26 #endif
27
28 using namespace js;
29 using namespace js::jit;
30
31 namespace js::jit {
32 class TempAllocator;
33 }
34
35 // Assert that JitCode is gc::Cell aligned.
36 static_assert(sizeof(JitCode) % gc::CellAlignBytes == 0);
37
38 static MOZ_THREAD_LOCAL(JitContext*) TlsJitContext;
39
CurrentJitContext()40 static JitContext* CurrentJitContext() {
41 if (!TlsJitContext.init()) {
42 return nullptr;
43 }
44 return TlsJitContext.get();
45 }
46
SetJitContext(JitContext * ctx)47 void jit::SetJitContext(JitContext* ctx) { TlsJitContext.set(ctx); }
48
GetJitContext()49 JitContext* jit::GetJitContext() {
50 MOZ_ASSERT(CurrentJitContext());
51 return CurrentJitContext();
52 }
53
MaybeGetJitContext()54 JitContext* jit::MaybeGetJitContext() { return CurrentJitContext(); }
55
JitContext(CompileRuntime * rt,CompileRealm * realm,TempAllocator * temp)56 JitContext::JitContext(CompileRuntime* rt, CompileRealm* realm,
57 TempAllocator* temp)
58 : prev_(CurrentJitContext()), realm_(realm), temp(temp), runtime(rt) {
59 MOZ_ASSERT(rt);
60 MOZ_ASSERT(realm);
61 MOZ_ASSERT(temp);
62 SetJitContext(this);
63 }
64
JitContext(JSContext * cx,TempAllocator * temp)65 JitContext::JitContext(JSContext* cx, TempAllocator* temp)
66 : prev_(CurrentJitContext()),
67 realm_(CompileRealm::get(cx->realm())),
68 cx(cx),
69 temp(temp),
70 runtime(CompileRuntime::get(cx->runtime())) {
71 SetJitContext(this);
72 }
73
JitContext(TempAllocator * temp)74 JitContext::JitContext(TempAllocator* temp)
75 : prev_(CurrentJitContext()), temp(temp) {
76 #ifdef DEBUG
77 isCompilingWasm_ = true;
78 #endif
79 SetJitContext(this);
80 }
81
JitContext()82 JitContext::JitContext() : JitContext(nullptr) {}
83
~JitContext()84 JitContext::~JitContext() { SetJitContext(prev_); }
85
InitializeJit()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_ARM)
101 InitARMFlags();
102 #endif
103
104 // Note: jit flags need to be initialized after the InitARMFlags call above.
105 ComputeJitSupportFlags();
106
107 CheckPerf();
108 return true;
109 }
110
ComputeJitSupportFlags()111 void jit::ComputeJitSupportFlags() {
112 JitOptions.supportsFloatingPoint = MacroAssembler::SupportsFloatingPoint();
113 JitOptions.supportsUnalignedAccesses =
114 MacroAssembler::SupportsUnalignedAccesses();
115 }
116
JitSupportsWasmSimd()117 bool jit::JitSupportsWasmSimd() {
118 #if defined(ENABLE_WASM_SIMD)
119 return js::jit::MacroAssembler::SupportsWasmSimd();
120 #else
121 MOZ_CRASH("Do not call");
122 #endif
123 }
124
JitSupportsAtomics()125 bool jit::JitSupportsAtomics() {
126 #if defined(JS_CODEGEN_ARM)
127 // Bug 1146902, bug 1077318: Enable Ion inlining of Atomics
128 // operations on ARM only when the CPU has byte, halfword, and
129 // doubleword load-exclusive and store-exclusive instructions,
130 // until we can add support for systems that don't have those.
131 return js::jit::HasLDSTREXBHD();
132 #else
133 return true;
134 #endif
135 }
136