Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/vm/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 4 kB image not shown  

Quelle  InvalidatingFuse.cpp

  Sprache: C
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "vm/InvalidatingFuse.h"

#include "gc/PublicIterators.h"
#include "jit/Invalidation.h"
#include "jit/JitSpewer.h"
#include "vm/JSContext.h"
#include "vm/JSScript.h"
#include "vm/Logging.h"

#include "gc/StableCellHasher-inl.h"
#include "vm/JSScript-inl.h"

js::FuseDependentIonScriptSet::FuseDependentIonScriptSet(JSContext* cx,
                                                         InvalidatingFuse* fuse)
    : associatedFuse(fuse), ionScripts(cx->runtime()) {}

bool js::InvalidatingRuntimeFuse::addFuseDependency(
    JSContext* cx, const jit::IonScriptKey& ionScript) {
  MOZ_ASSERT(ionScript.script()->zone() == cx->zone());

  auto* scriptSet =
      cx->zone()->fuseDependencies.getOrCreateDependentScriptSet(cx, this);
  if (!scriptSet) {
    return false;
  }

  return scriptSet->addScriptForFuse(this, ionScript);
}

// This method will pop the fuse and iterates over its dependencies
// iff this fuse is still intact.
// This avoids a costly iteration over dependencies in subsequent calls.
void js::InvalidatingRuntimeFuse::popFuse(JSContext* cx) {
  if (!intact()) {
    return;
  }

  // Pop the fuse in the base class
  GuardFuse::popFuse(cx);
  JS_LOG(fuseInvalidation, Verbose, "Invalidating fuse popping: %s", name());
  // do invalidation.
  for (AllZonesIter z(cx->runtime()); !z.done(); z.next()) {
    // There's one dependent script set per fuse; just iterate over them all to
    // find the one we need (see comment on JS::Zone::fuseDependencies for
    // reasoning).
    for (auto& fd : z.get()->fuseDependencies) {
      fd.invalidateForFuse(cx, this);
    }
  }
}

void js::FuseDependentIonScriptSet::invalidateForFuse(JSContext* cx,
                                                      InvalidatingFuse* fuse) {
  if (associatedFuse != fuse) {
    return;
  }
  ionScripts.get().invalidateAndClear(cx, "fuse");
}

void js::jit::DependentIonScriptSet::invalidateAndClear(JSContext* cx,
                                                        const char* reason) {
  for (const auto& ionScriptKey : ionScripts_) {
    IonScript* ionScript = ionScriptKey.maybeIonScriptToInvalidate();
    if (ionScript) {
      JSScript* script = ionScriptKey.script();
      JitSpew(jit::JitSpew_IonInvalidate, "Invalidating ion script %p for %s",
              ionScript, reason);
      JS_LOG(fuseInvalidation, Debug,
             "Invalidating ion script %s:%d for reason %s", script->filename(),
             script->lineno(), reason);
    }
  }
  js::jit::Invalidate(cx, ionScripts_);
  ionScripts_.clearAndFree();
}

bool js::FuseDependentIonScriptSet::addScriptForFuse(
    InvalidatingFuse* fuse, const jit::IonScriptKey& ionScript) {
  MOZ_ASSERT(fuse == associatedFuse);
  return ionScripts.get().addToSet(ionScript);
}

js::FuseDependentIonScriptSet*
js::DependentIonScriptGroup::getOrCreateDependentScriptSet(
    JSContext* cx, js::InvalidatingFuse* fuse) {
  for (auto& dss : dependencies) {
    if (dss.associatedFuse == fuse) {
      return &dss;
    }
  }

  if (!dependencies.emplaceBack(cx, fuse)) {
    return nullptr;
  }

  auto& dss = dependencies.back();
  MOZ_ASSERT(dss.associatedFuse == fuse);
  return &dss;
}

bool js::jit::DependentIonScriptSet::addToSet(const IonScriptKey& ionScript) {
  MOZ_ASSERT(lengthAfterLastCompaction_ <= ionScripts_.length());

  // If `ionScript` is already in the vector, it must be the last entry.
  if (!ionScripts_.empty() && ionScripts_.back() == ionScript) {
    return true;
  }

  // Assert `ionScript` is not in the vector. Limit this to the last 8 entries
  // to not slow down debug builds too much.
#ifdef DEBUG
  size_t numToCheck = std::min<size_t>(ionScripts_.length(), 8);
  for (size_t i = 0; i < numToCheck; i++) {
    MOZ_ASSERT(ionScripts_[ionScripts_.length() - 1 - i] != ionScript);
  }
#endif

  // Compact the vector if its size doubled since the last compaction. This
  // isn't required for correctness but it avoids keeping a lot of stale
  // entries around between GCs.
  if (ionScripts_.length() / 2 > lengthAfterLastCompaction_) {
    ionScripts_.eraseIf([](const IonScriptKey& ionScript) {
      return ionScript.maybeIonScriptToInvalidate() == nullptr;
    });
    lengthAfterLastCompaction_ = ionScripts_.length();
  }

  return ionScripts_.append(ionScript);
}

Messung V0.5 in Prozent
C=89 H=95 G=91

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.