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/CompileWrappers.h"
8
9 #include "gc/Heap.h"
10 #include "gc/Zone.h"
11 #include "jit/Ion.h"
12 #include "jit/JitRuntime.h"
13 #include "vm/Realm.h"
14
15 using namespace js;
16 using namespace js::jit;
17
runtime()18 JSRuntime* CompileRuntime::runtime() {
19 return reinterpret_cast<JSRuntime*>(this);
20 }
21
22 /* static */
get(JSRuntime * rt)23 CompileRuntime* CompileRuntime::get(JSRuntime* rt) {
24 return reinterpret_cast<CompileRuntime*>(rt);
25 }
26
27 #ifdef JS_GC_ZEAL
addressOfGCZealModeBits()28 const uint32_t* CompileRuntime::addressOfGCZealModeBits() {
29 return runtime()->gc.addressOfZealModeBits();
30 }
31 #endif
32
jitRuntime()33 const JitRuntime* CompileRuntime::jitRuntime() {
34 return runtime()->jitRuntime();
35 }
36
geckoProfiler()37 GeckoProfilerRuntime& CompileRuntime::geckoProfiler() {
38 return runtime()->geckoProfiler();
39 }
40
hadOutOfMemory()41 bool CompileRuntime::hadOutOfMemory() { return runtime()->hadOutOfMemory; }
42
profilingScripts()43 bool CompileRuntime::profilingScripts() { return runtime()->profilingScripts; }
44
names()45 const JSAtomState& CompileRuntime::names() { return *runtime()->commonNames; }
46
emptyString()47 const PropertyName* CompileRuntime::emptyString() {
48 return runtime()->emptyString;
49 }
50
staticStrings()51 const StaticStrings& CompileRuntime::staticStrings() {
52 return *runtime()->staticStrings;
53 }
54
wellKnownSymbols()55 const WellKnownSymbols& CompileRuntime::wellKnownSymbols() {
56 return *runtime()->wellKnownSymbols;
57 }
58
maybeWindowProxyClass()59 const JSClass* CompileRuntime::maybeWindowProxyClass() {
60 return runtime()->maybeWindowProxyClass();
61 }
62
mainContextPtr()63 const void* CompileRuntime::mainContextPtr() {
64 return runtime()->mainContextFromAnyThread();
65 }
66
addressOfTenuredAllocCount()67 uint32_t* CompileRuntime::addressOfTenuredAllocCount() {
68 return runtime()->mainContextFromAnyThread()->addressOfTenuredAllocCount();
69 }
70
addressOfJitStackLimit()71 const void* CompileRuntime::addressOfJitStackLimit() {
72 return runtime()->mainContextFromAnyThread()->addressOfJitStackLimit();
73 }
74
addressOfInterruptBits()75 const void* CompileRuntime::addressOfInterruptBits() {
76 return runtime()->mainContextFromAnyThread()->addressOfInterruptBits();
77 }
78
addressOfZone()79 const void* CompileRuntime::addressOfZone() {
80 return runtime()->mainContextFromAnyThread()->addressOfZone();
81 }
82
DOMcallbacks()83 const DOMCallbacks* CompileRuntime::DOMcallbacks() {
84 return runtime()->DOMcallbacks;
85 }
86
runtimeMatches(JSRuntime * rt)87 bool CompileRuntime::runtimeMatches(JSRuntime* rt) { return rt == runtime(); }
88
zone()89 Zone* CompileZone::zone() { return reinterpret_cast<Zone*>(this); }
90
91 /* static */
get(Zone * zone)92 CompileZone* CompileZone::get(Zone* zone) {
93 return reinterpret_cast<CompileZone*>(zone);
94 }
95
runtime()96 CompileRuntime* CompileZone::runtime() {
97 return CompileRuntime::get(zone()->runtimeFromAnyThread());
98 }
99
isAtomsZone()100 bool CompileZone::isAtomsZone() { return zone()->isAtomsZone(); }
101
102 #ifdef DEBUG
addressOfIonBailAfterCounter()103 const void* CompileRuntime::addressOfIonBailAfterCounter() {
104 return runtime()->jitRuntime()->addressOfIonBailAfterCounter();
105 }
106 #endif
107
addressOfNeedsIncrementalBarrier()108 const uint32_t* CompileZone::addressOfNeedsIncrementalBarrier() {
109 // Cast away relaxed atomic wrapper for JIT access to barrier state.
110 const mozilla::Atomic<uint32_t, mozilla::Relaxed>* ptr =
111 zone()->addressOfNeedsIncrementalBarrier();
112 return reinterpret_cast<const uint32_t*>(ptr);
113 }
114
addressOfFreeList(gc::AllocKind allocKind)115 gc::FreeSpan** CompileZone::addressOfFreeList(gc::AllocKind allocKind) {
116 return zone()->arenas.addressOfFreeList(allocKind);
117 }
118
addressOfNurseryPosition()119 void* CompileZone::addressOfNurseryPosition() {
120 return zone()->runtimeFromAnyThread()->gc.addressOfNurseryPosition();
121 }
122
addressOfStringNurseryPosition()123 void* CompileZone::addressOfStringNurseryPosition() {
124 // Objects and strings share a nursery, for now at least.
125 return zone()->runtimeFromAnyThread()->gc.addressOfNurseryPosition();
126 }
127
addressOfBigIntNurseryPosition()128 void* CompileZone::addressOfBigIntNurseryPosition() {
129 // Objects and BigInts share a nursery, for now at least.
130 return zone()->runtimeFromAnyThread()->gc.addressOfNurseryPosition();
131 }
132
addressOfNurseryCurrentEnd()133 const void* CompileZone::addressOfNurseryCurrentEnd() {
134 return zone()->runtimeFromAnyThread()->gc.addressOfNurseryCurrentEnd();
135 }
136
addressOfStringNurseryCurrentEnd()137 const void* CompileZone::addressOfStringNurseryCurrentEnd() {
138 // Although objects and strings share a nursery (and this may change)
139 // there is still a separate string end address. The only time it
140 // is different from the regular end address, is when nursery strings are
141 // disabled (it will be NULL).
142 //
143 // This function returns _a pointer to_ that end address.
144 return zone()->runtimeFromAnyThread()->gc.addressOfStringNurseryCurrentEnd();
145 }
146
addressOfBigIntNurseryCurrentEnd()147 const void* CompileZone::addressOfBigIntNurseryCurrentEnd() {
148 // Similar to Strings, BigInts also share the nursery with other nursery
149 // allocatable things.
150 return zone()->runtimeFromAnyThread()->gc.addressOfBigIntNurseryCurrentEnd();
151 }
152
addressOfNurseryAllocCount()153 uint32_t* CompileZone::addressOfNurseryAllocCount() {
154 return zone()->runtimeFromAnyThread()->gc.addressOfNurseryAllocCount();
155 }
156
addressOfNurseryAllocatedSites()157 void* CompileZone::addressOfNurseryAllocatedSites() {
158 JSRuntime* rt = zone()->runtimeFromAnyThread();
159 return rt->gc.nursery().addressOfNurseryAllocatedSites();
160 }
161
canNurseryAllocateStrings()162 bool CompileZone::canNurseryAllocateStrings() {
163 return zone()->runtimeFromAnyThread()->gc.nursery().canAllocateStrings() &&
164 zone()->allocNurseryStrings;
165 }
166
canNurseryAllocateBigInts()167 bool CompileZone::canNurseryAllocateBigInts() {
168 return zone()->runtimeFromAnyThread()->gc.nursery().canAllocateBigInts() &&
169 zone()->allocNurseryBigInts;
170 }
171
nurseryCellHeader(JS::TraceKind traceKind,gc::CatchAllAllocSite siteKind)172 uintptr_t CompileZone::nurseryCellHeader(JS::TraceKind traceKind,
173 gc::CatchAllAllocSite siteKind) {
174 gc::AllocSite* site = siteKind == gc::CatchAllAllocSite::Optimized
175 ? zone()->optimizedAllocSite()
176 : zone()->unknownAllocSite();
177 return gc::NurseryCellHeader::MakeValue(site, traceKind);
178 }
179
realm()180 JS::Realm* CompileRealm::realm() { return reinterpret_cast<JS::Realm*>(this); }
181
182 /* static */
get(JS::Realm * realm)183 CompileRealm* CompileRealm::get(JS::Realm* realm) {
184 return reinterpret_cast<CompileRealm*>(realm);
185 }
186
zone()187 CompileZone* CompileRealm::zone() { return CompileZone::get(realm()->zone()); }
188
runtime()189 CompileRuntime* CompileRealm::runtime() {
190 return CompileRuntime::get(realm()->runtimeFromAnyThread());
191 }
192
193 const mozilla::non_crypto::XorShift128PlusRNG*
addressOfRandomNumberGenerator()194 CompileRealm::addressOfRandomNumberGenerator() {
195 return realm()->addressOfRandomNumberGenerator();
196 }
197
jitRealm()198 const JitRealm* CompileRealm::jitRealm() { return realm()->jitRealm(); }
199
maybeGlobal()200 const GlobalObject* CompileRealm::maybeGlobal() {
201 // This uses unsafeUnbarrieredMaybeGlobal() so as not to trigger the read
202 // barrier on the global from off thread. This is safe because we
203 // abort Ion compilation when we GC.
204 return realm()->unsafeUnbarrieredMaybeGlobal();
205 }
206
addressOfGlobalWriteBarriered()207 const uint32_t* CompileRealm::addressOfGlobalWriteBarriered() {
208 return &realm()->globalWriteBarriered;
209 }
210
hasAllocationMetadataBuilder()211 bool CompileRealm::hasAllocationMetadataBuilder() {
212 return realm()->hasAllocationMetadataBuilder();
213 }
214
JitCompileOptions()215 JitCompileOptions::JitCompileOptions()
216 : profilerSlowAssertionsEnabled_(false),
217 offThreadCompilationAvailable_(false) {}
218
JitCompileOptions(JSContext * cx)219 JitCompileOptions::JitCompileOptions(JSContext* cx) {
220 profilerSlowAssertionsEnabled_ =
221 cx->runtime()->geckoProfiler().enabled() &&
222 cx->runtime()->geckoProfiler().slowAssertionsEnabled();
223 offThreadCompilationAvailable_ = OffThreadCompilationAvailable(cx);
224 #ifdef DEBUG
225 ionBailAfterEnabled_ = cx->runtime()->jitRuntime()->ionBailAfterEnabled();
226 #endif
227 }
228