CompileWrappers.cpp (7500B)
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 18 JSRuntime* CompileRuntime::runtime() { 19 return reinterpret_cast<JSRuntime*>(this); 20 } 21 22 /* static */ 23 CompileRuntime* CompileRuntime::get(JSRuntime* rt) { 24 return reinterpret_cast<CompileRuntime*>(rt); 25 } 26 27 #ifdef JS_GC_ZEAL 28 const uint32_t* CompileRuntime::addressOfGCZealModeBits() { 29 return runtime()->gc.addressOfZealModeBits(); 30 } 31 #endif 32 33 const JitRuntime* CompileRuntime::jitRuntime() { 34 return runtime()->jitRuntime(); 35 } 36 37 const GeckoProfilerRuntime& CompileRuntime::geckoProfiler() { 38 return runtime()->geckoProfiler(); 39 } 40 41 bool CompileRuntime::hadOutOfMemory() { return runtime()->hadOutOfMemory; } 42 43 bool CompileRuntime::profilingScripts() { return runtime()->profilingScripts; } 44 45 const JSAtomState& CompileRuntime::names() { return *runtime()->commonNames; } 46 47 const PropertyName* CompileRuntime::emptyString() { 48 return runtime()->emptyString; 49 } 50 51 const StaticStrings& CompileRuntime::staticStrings() { 52 return *runtime()->staticStrings; 53 } 54 55 const WellKnownSymbols& CompileRuntime::wellKnownSymbols() { 56 return *runtime()->wellKnownSymbols; 57 } 58 59 const JSClass* CompileRuntime::maybeWindowProxyClass() { 60 return runtime()->maybeWindowProxyClass(); 61 } 62 63 const void* CompileRuntime::mainContextPtr() { 64 return runtime()->mainContextFromAnyThread(); 65 } 66 67 const void* CompileRuntime::addressOfJitActivation() { 68 return runtime()->mainContextFromAnyThread()->addressOfJitActivation(); 69 } 70 71 const void* CompileRuntime::addressOfJitStackLimit() { 72 return runtime()->mainContextFromAnyThread()->addressOfJitStackLimit(); 73 } 74 75 const void* CompileRuntime::addressOfInterruptBits() { 76 return runtime()->mainContextFromAnyThread()->addressOfInterruptBits(); 77 } 78 79 const void* CompileRuntime::addressOfRealm() { 80 return runtime()->mainContextFromAnyThread()->addressOfRealm(); 81 } 82 83 const void* CompileRuntime::addressOfZone() { 84 return runtime()->mainContextFromAnyThread()->addressOfZone(); 85 } 86 87 const void* CompileRuntime::addressOfMegamorphicCache() { 88 return &runtime()->caches().megamorphicCache; 89 } 90 91 const void* CompileRuntime::addressOfMegamorphicSetPropCache() { 92 return runtime()->caches().megamorphicSetPropCache.get(); 93 } 94 95 const void* CompileRuntime::addressOfStringToAtomCache() { 96 return &runtime()->caches().stringToAtomCache; 97 } 98 99 const void* CompileRuntime::addressOfLastBufferedWholeCell() { 100 return runtime()->gc.addressOfLastBufferedWholeCell(); 101 } 102 103 const void* CompileRuntime::addressOfRuntimeFuse( 104 RuntimeFuses::FuseIndex index) { 105 // We're merely accessing the address of the fuse here, and so we don't need 106 // the MainThreadData check here. 107 return runtime()->runtimeFuses.refNoCheck().getFuseByIndex(index)->fuseRef(); 108 } 109 110 bool CompileRuntime::runtimeFuseIntact(RuntimeFuses::FuseIndex index) { 111 // Note: This accesses the bit; this would be unsafe off-thread, however 112 // this should only be accessed by CompileInfo in its constructor on main 113 // thread and so should be safe. 114 // 115 // (This value is also checked by ref() rather than skipped like the address 116 // call above.) 117 return runtime()->runtimeFuses.ref().getFuseByIndex(index)->intact(); 118 } 119 120 const DOMCallbacks* CompileRuntime::DOMcallbacks() { 121 return runtime()->DOMcallbacks; 122 } 123 124 bool CompileRuntime::runtimeMatches(JSRuntime* rt) { return rt == runtime(); } 125 126 Zone* CompileZone::zone() { return reinterpret_cast<Zone*>(this); } 127 128 /* static */ 129 CompileZone* CompileZone::get(Zone* zone) { 130 return reinterpret_cast<CompileZone*>(zone); 131 } 132 133 CompileRuntime* CompileZone::runtime() { 134 return CompileRuntime::get(zone()->runtimeFromAnyThread()); 135 } 136 137 bool CompileZone::isAtomsZone() { return zone()->isAtomsZone(); } 138 139 #ifdef DEBUG 140 const void* CompileRuntime::addressOfIonBailAfterCounter() { 141 return runtime()->jitRuntime()->addressOfIonBailAfterCounter(); 142 } 143 #endif 144 145 const uint32_t* CompileZone::addressOfNeedsIncrementalBarrier() { 146 // Cast away relaxed atomic wrapper for JIT access to barrier state. 147 const mozilla::Atomic<uint32_t, mozilla::Relaxed>* ptr = 148 zone()->addressOfNeedsIncrementalBarrier(); 149 return reinterpret_cast<const uint32_t*>(ptr); 150 } 151 152 uint32_t* CompileZone::addressOfTenuredAllocCount() { 153 return zone()->addressOfTenuredAllocCount(); 154 } 155 156 gc::FreeSpan** CompileZone::addressOfFreeList(gc::AllocKind allocKind) { 157 return zone()->arenas.addressOfFreeList(allocKind); 158 } 159 160 bool CompileZone::allocNurseryObjects() { 161 return zone()->allocNurseryObjects(); 162 } 163 164 bool CompileZone::allocNurseryStrings() { 165 return zone()->allocNurseryStrings(); 166 } 167 168 bool CompileZone::allocNurseryBigInts() { 169 return zone()->allocNurseryBigInts(); 170 } 171 172 void* CompileZone::addressOfNurseryPosition() { 173 return zone()->runtimeFromAnyThread()->gc.addressOfNurseryPosition(); 174 } 175 176 void* CompileZone::addressOfNurseryAllocatedSites() { 177 JSRuntime* rt = zone()->runtimeFromAnyThread(); 178 return rt->gc.addressOfNurseryAllocatedSites(); 179 } 180 181 void* CompileZone::jitZone() { return zone()->jitZone(); } 182 183 bool CompileZone::canNurseryAllocateStrings() { 184 return zone()->allocNurseryStrings(); 185 } 186 187 bool CompileZone::canNurseryAllocateBigInts() { 188 return zone()->allocNurseryBigInts(); 189 } 190 191 gc::AllocSite* CompileZone::catchAllAllocSite(JS::TraceKind traceKind, 192 gc::CatchAllAllocSite siteKind) { 193 if (siteKind == gc::CatchAllAllocSite::Optimized) { 194 return zone()->optimizedAllocSite(); 195 } 196 return zone()->unknownAllocSite(traceKind); 197 } 198 199 gc::AllocSite* CompileZone::tenuringAllocSite() { 200 return zone()->tenuringAllocSite(); 201 } 202 203 JS::Realm* CompileRealm::realm() { return reinterpret_cast<JS::Realm*>(this); } 204 205 /* static */ 206 CompileRealm* CompileRealm::get(JS::Realm* realm) { 207 return reinterpret_cast<CompileRealm*>(realm); 208 } 209 210 CompileZone* CompileRealm::zone() { return CompileZone::get(realm()->zone()); } 211 212 CompileRuntime* CompileRealm::runtime() { 213 return CompileRuntime::get(realm()->runtimeFromAnyThread()); 214 } 215 216 const mozilla::non_crypto::XorShift128PlusRNG* 217 CompileRealm::addressOfRandomNumberGenerator() { 218 return realm()->addressOfRandomNumberGenerator(); 219 } 220 221 const GlobalObject* CompileRealm::maybeGlobal() { 222 // This uses unsafeUnbarrieredMaybeGlobal() so as not to trigger the read 223 // barrier on the global from off thread. This is safe because we 224 // abort Ion compilation when we GC. 225 return realm()->unsafeUnbarrieredMaybeGlobal(); 226 } 227 228 const uint32_t* CompileRealm::addressOfGlobalWriteBarriered() { 229 return &realm()->globalWriteBarriered; 230 } 231 232 bool CompileZone::hasRealmWithAllocMetadataBuilder() { 233 return zone()->hasRealmWithAllocMetadataBuilder(); 234 } 235 236 JitCompileOptions::JitCompileOptions() 237 : profilerSlowAssertionsEnabled_(false), 238 offThreadCompilationAvailable_(false) {} 239 240 JitCompileOptions::JitCompileOptions(JSContext* cx) { 241 profilerSlowAssertionsEnabled_ = 242 cx->runtime()->geckoProfiler().enabled() && 243 cx->runtime()->geckoProfiler().slowAssertionsEnabled(); 244 offThreadCompilationAvailable_ = OffThreadCompilationAvailable(cx); 245 #ifdef DEBUG 246 ionBailAfterEnabled_ = cx->runtime()->jitRuntime()->ionBailAfterEnabled(); 247 #endif 248 }