tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */