summaryrefslogtreecommitdiffstats
path: root/js/src/vm/InvalidatingFuse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/InvalidatingFuse.cpp')
-rw-r--r--js/src/vm/InvalidatingFuse.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/js/src/vm/InvalidatingFuse.cpp b/js/src/vm/InvalidatingFuse.cpp
new file mode 100644
index 0000000000..3e14d72fcc
--- /dev/null
+++ b/js/src/vm/InvalidatingFuse.cpp
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * 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 "gc/StableCellHasher-inl.h"
+#include "vm/JSScript-inl.h"
+
+js::DependentScriptSet::DependentScriptSet(JSContext* cx,
+ InvalidatingFuse* fuse)
+ : associatedFuse(fuse), weakScripts(cx->runtime()) {}
+
+bool js::InvalidatingRuntimeFuse::addFuseDependency(JSContext* cx,
+ Handle<JSScript*> script) {
+ auto* zone = script->zone();
+ DependentScriptSet* dss = zone->getOrCreateDependentScriptSet(cx, this);
+ if (!dss) {
+ return false;
+ }
+
+ return dss->addScriptForFuse(this, script);
+}
+
+void js::InvalidatingRuntimeFuse::popFuse(JSContext* cx) {
+ // Pop the fuse in the base class
+ GuardFuse::popFuse(cx);
+ // 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::DependentScriptSet::invalidateForFuse(JSContext* cx,
+ InvalidatingFuse* fuse) {
+ if (associatedFuse != fuse) {
+ return;
+ }
+
+ for (auto r = weakScripts.all(); !r.empty(); r.popFront()) {
+ JSScript* script = r.front().get();
+ // A script may have lost its ion script for other reasons
+ // by the time this is invoked, so need to ensure it's still there
+ // before calling invaidate.
+ if (script->hasIonScript()) {
+ JitSpew(jit::JitSpew_IonInvalidate, "Invalidating ion script %p",
+ script->ionScript());
+ js::jit::Invalidate(cx, script);
+ }
+ }
+
+ // Scripts are invalidated, flush them.
+ weakScripts.clear();
+}
+
+bool js::DependentScriptSet::addScriptForFuse(InvalidatingFuse* fuse,
+ Handle<JSScript*> script) {
+ MOZ_ASSERT(fuse == associatedFuse);
+
+ WeakScriptSet::AddPtr p = weakScripts.lookupForAdd(script);
+ if (!p) {
+ if (!weakScripts.add(p, script)) {
+ return false;
+ }
+ }
+
+ // Script is already in the set, no need to re-add.
+ return true;
+}