JSScript-inl.h (7917B)
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 #ifndef vm_JSScript_inl_h 8 #define vm_JSScript_inl_h 9 10 #include "vm/JSScript.h" 11 12 #include <utility> 13 14 #include "jit/IonScript.h" 15 #include "jit/JitScript.h" 16 #include "vm/RegExpObject.h" 17 #include "wasm/AsmJS.h" 18 19 namespace js { 20 21 ScriptCounts::ScriptCounts() : ionCounts_(nullptr) {} 22 23 ScriptCounts::ScriptCounts(PCCountsVector&& jumpTargets) 24 : pcCounts_(std::move(jumpTargets)), ionCounts_(nullptr) {} 25 26 ScriptCounts::ScriptCounts(ScriptCounts&& src) 27 : pcCounts_(std::move(src.pcCounts_)), 28 throwCounts_(std::move(src.throwCounts_)), 29 ionCounts_(std::move(src.ionCounts_)) { 30 src.ionCounts_ = nullptr; 31 } 32 33 ScriptCounts& ScriptCounts::operator=(ScriptCounts&& src) { 34 pcCounts_ = std::move(src.pcCounts_); 35 throwCounts_ = std::move(src.throwCounts_); 36 ionCounts_ = std::move(src.ionCounts_); 37 src.ionCounts_ = nullptr; 38 return *this; 39 } 40 41 ScriptCounts::~ScriptCounts() { js_delete(ionCounts_); } 42 43 ScriptAndCounts::ScriptAndCounts(JSScript* script) : script(script) { 44 script->releaseScriptCounts(&scriptCounts); 45 } 46 47 ScriptAndCounts::ScriptAndCounts(ScriptAndCounts&& sac) 48 : script(std::move(sac.script)), 49 scriptCounts(std::move(sac.scriptCounts)) {} 50 51 void SetFrameArgumentsObject(JSContext* cx, AbstractFramePtr frame, 52 JSObject* argsobj); 53 54 inline void ScriptWarmUpData::initEnclosingScript(BaseScript* enclosingScript) { 55 MOZ_ASSERT(data_ == ResetState()); 56 setTaggedPtr<EnclosingScriptTag>(enclosingScript); 57 static_assert(std::is_base_of_v<gc::TenuredCell, BaseScript>, 58 "BaseScript must be TenuredCell to avoid post-barriers"); 59 } 60 inline void ScriptWarmUpData::clearEnclosingScript() { 61 gc::PreWriteBarrier(toEnclosingScript()); 62 data_ = ResetState(); 63 } 64 65 inline void ScriptWarmUpData::initEnclosingScope(Scope* enclosingScope) { 66 MOZ_ASSERT(data_ == ResetState()); 67 setTaggedPtr<EnclosingScopeTag>(enclosingScope); 68 static_assert(std::is_base_of_v<gc::TenuredCell, Scope>, 69 "Scope must be TenuredCell to avoid post-barriers"); 70 } 71 inline void ScriptWarmUpData::clearEnclosingScope() { 72 gc::PreWriteBarrier(toEnclosingScope()); 73 data_ = ResetState(); 74 } 75 76 inline JSPrincipals* BaseScript::principals() const { 77 return realm()->principals(); 78 } 79 80 inline JSScript* BaseScript::asJSScript() { 81 MOZ_ASSERT(hasBytecode()); 82 return static_cast<JSScript*>(this); 83 } 84 85 } // namespace js 86 87 inline JSFunction* JSScript::getFunction(js::GCThingIndex index) const { 88 JSObject* obj = getObject(index); 89 MOZ_RELEASE_ASSERT(obj->is<JSFunction>(), "Script object is not JSFunction"); 90 JSFunction* fun = &obj->as<JSFunction>(); 91 MOZ_ASSERT_IF(fun->isNativeFun(), IsAsmJSModuleNative(fun->native())); 92 return fun; 93 } 94 95 inline JSFunction* JSScript::getFunction(jsbytecode* pc) const { 96 return getFunction(GET_GCTHING_INDEX(pc)); 97 } 98 99 inline js::RegExpObject* JSScript::getRegExp(js::GCThingIndex index) const { 100 JSObject* obj = getObject(index); 101 MOZ_RELEASE_ASSERT(obj->is<js::RegExpObject>(), 102 "Script object is not RegExpObject"); 103 return &obj->as<js::RegExpObject>(); 104 } 105 106 inline js::RegExpObject* JSScript::getRegExp(jsbytecode* pc) const { 107 JSObject* obj = getObject(pc); 108 MOZ_RELEASE_ASSERT(obj->is<js::RegExpObject>(), 109 "Script object is not RegExpObject"); 110 return &obj->as<js::RegExpObject>(); 111 } 112 113 inline js::GlobalObject& JSScript::global() const { 114 /* 115 * A JSScript always marks its realm's global so we can assert it's non-null 116 * here. We don't need a read barrier here for the same reason 117 * JSObject::nonCCWGlobal doesn't need one. 118 */ 119 return *realm()->unsafeUnbarrieredMaybeGlobal(); 120 } 121 122 inline bool JSScript::hasGlobal(const js::GlobalObject* global) const { 123 return global == realm()->unsafeUnbarrieredMaybeGlobal(); 124 } 125 126 inline js::LexicalScope* JSScript::maybeNamedLambdaScope() const { 127 // Dynamically created Functions via the 'new Function' are considered 128 // named lambdas but they do not have the named lambda scope of 129 // textually-created named lambdas. 130 js::Scope* scope = outermostScope(); 131 if (scope->kind() == js::ScopeKind::NamedLambda || 132 scope->kind() == js::ScopeKind::StrictNamedLambda) { 133 MOZ_ASSERT_IF(!strict(), scope->kind() == js::ScopeKind::NamedLambda); 134 MOZ_ASSERT_IF(strict(), scope->kind() == js::ScopeKind::StrictNamedLambda); 135 return &scope->as<js::LexicalScope>(); 136 } 137 return nullptr; 138 } 139 140 inline js::Shape* JSScript::initialEnvironmentShape() const { 141 js::Scope* scope = bodyScope(); 142 if (scope->is<js::FunctionScope>()) { 143 if (js::Shape* envShape = scope->environmentShape()) { 144 return envShape; 145 } 146 if (js::Scope* namedLambdaScope = maybeNamedLambdaScope()) { 147 return namedLambdaScope->environmentShape(); 148 } 149 } else if (scope->is<js::EvalScope>()) { 150 return scope->environmentShape(); 151 } 152 return nullptr; 153 } 154 155 inline bool JSScript::isDebuggee() const { 156 return realm()->debuggerObservesAllExecution() || hasDebugScript(); 157 } 158 159 inline bool js::BaseScript::hasBaselineScript() const { 160 return hasJitScript() && jitScript()->hasBaselineScript(); 161 } 162 163 inline bool JSScript::isBaselineCompilingOffThread() const { 164 return hasJitScript() && jitScript()->isBaselineCompiling(); 165 } 166 167 inline bool js::BaseScript::hasIonScript() const { 168 return hasJitScript() && jitScript()->hasIonScript(); 169 } 170 171 inline bool JSScript::isIonCompilingOffThread() const { 172 return hasJitScript() && jitScript()->isIonCompilingOffThread(); 173 } 174 175 inline bool JSScript::canBaselineCompile() const { 176 bool disabled = baselineDisabled(); 177 #ifdef DEBUG 178 if (hasJitScript()) { 179 bool jitScriptDisabled = 180 jitScript()->baselineScript_ == js::jit::BaselineDisabledScriptPtr; 181 MOZ_ASSERT(disabled == jitScriptDisabled); 182 } 183 #endif 184 return !disabled; 185 } 186 187 inline bool JSScript::canIonCompile() const { 188 bool disabled = ionDisabled(); 189 #ifdef DEBUG 190 if (hasJitScript()) { 191 bool jitScriptDisabled = 192 jitScript()->ionScript_ == js::jit::IonDisabledScriptPtr; 193 MOZ_ASSERT(disabled == jitScriptDisabled); 194 } 195 #endif 196 return !disabled; 197 } 198 199 inline void JSScript::disableBaselineCompile() { 200 MOZ_ASSERT(!hasBaselineScript()); 201 setFlag(MutableFlags::BaselineDisabled); 202 if (hasJitScript()) { 203 jitScript()->setBaselineScriptImpl(this, 204 js::jit::BaselineDisabledScriptPtr); 205 } 206 } 207 208 inline void JSScript::disableIon() { 209 setFlag(MutableFlags::IonDisabled); 210 if (hasJitScript()) { 211 jitScript()->setIonScriptImpl(this, js::jit::IonDisabledScriptPtr); 212 } 213 } 214 215 inline js::jit::BaselineScript* JSScript::baselineScript() const { 216 return jitScript()->baselineScript(); 217 } 218 219 inline js::jit::IonScript* JSScript::ionScript() const { 220 return jitScript()->ionScript(); 221 } 222 223 inline uint32_t JSScript::getWarmUpCount() const { 224 if (warmUpData_.isWarmUpCount()) { 225 return warmUpData_.toWarmUpCount(); 226 } 227 return warmUpData_.toJitScript()->warmUpCount(); 228 } 229 230 inline void JSScript::updateLastICStubCounter() { 231 if (!hasJitScript()) { 232 return; 233 } 234 jitScript()->updateLastICStubCounter(); 235 } 236 237 inline uint32_t JSScript::warmUpCountAtLastICStub() const { 238 MOZ_ASSERT(hasJitScript()); 239 return jitScript()->warmUpCountAtLastICStub(); 240 } 241 242 inline void JSScript::incWarmUpCounter() { 243 if (warmUpData_.isWarmUpCount()) { 244 warmUpData_.incWarmUpCount(); 245 } else { 246 warmUpData_.toJitScript()->incWarmUpCount(); 247 } 248 } 249 250 inline void JSScript::resetWarmUpCounterForGC() { 251 incWarmUpResetCounter(); 252 if (warmUpData_.isWarmUpCount()) { 253 warmUpData_.resetWarmUpCount(0); 254 } else { 255 warmUpData_.toJitScript()->resetWarmUpCount(0); 256 } 257 } 258 259 #endif /* vm_JSScript_inl_h */