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