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