146 lines
6.4 KiB
Diff
146 lines
6.4 KiB
Diff
From aee1effa487849cc3c48c28c60a866211b05ebae Mon Sep 17 00:00:00 2001
|
|
From: Jon Coppeard <jcoppeard@mozilla.com>
|
|
Date: Tue, 14 Feb 2023 10:32:47 +0000
|
|
Subject: [PATCH] Part 1: Disallow GC while iterating global's debugger vector
|
|
|
|
Conflict:NA
|
|
Reference:https://hg.mozilla.org/integration/autoland/rev/760275af660b20d35ace80f4d245c4ad9c4a3869
|
|
---
|
|
js/src/debugger/Debugger.cpp | 37 +++++++++++++++++++++++-------------
|
|
js/src/debugger/Debugger.h | 10 ++++++----
|
|
js/src/gc/GC.h | 2 +-
|
|
3 files changed, 31 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp
|
|
index be22c18354..56a172c457 100644
|
|
--- a/js/src/debugger/Debugger.cpp
|
|
+++ b/js/src/debugger/Debugger.cpp
|
|
@@ -1240,8 +1240,9 @@ bool DebugAPI::slowPathOnNewGenerator(JSContext* cx, AbstractFramePtr frame,
|
|
MakeScopeExit([&] { Debugger::terminateDebuggerFrames(cx, frame); });
|
|
|
|
bool ok = true;
|
|
+ gc::AutoSuppressGC nogc(cx);
|
|
Debugger::forEachOnStackDebuggerFrame(
|
|
- frame, [&](Debugger* dbg, DebuggerFrame* frameObjPtr) {
|
|
+ frame, nogc, [&](Debugger* dbg, DebuggerFrame* frameObjPtr) {
|
|
if (!ok) {
|
|
return;
|
|
}
|
|
@@ -3265,7 +3266,10 @@ bool Debugger::updateExecutionObservabilityOfScripts(
|
|
|
|
template <typename FrameFn>
|
|
/* static */
|
|
-void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
|
|
+void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame,
|
|
+ const JS::AutoRequireNoGC& nogc,
|
|
+ FrameFn fn) {
|
|
+ // GC is disallowed because it may mutate the vector we are iterating.
|
|
for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
|
|
Debugger* dbg = entry.dbg;
|
|
if (FrameMap::Ptr frameEntry = dbg->frames.lookup(frame)) {
|
|
@@ -3276,9 +3280,10 @@ void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
|
|
|
|
template <typename FrameFn>
|
|
/* static */
|
|
-void Debugger::forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
|
|
- AbstractFramePtr frame,
|
|
- FrameFn fn) {
|
|
+void Debugger::forEachOnStackOrSuspendedDebuggerFrame(
|
|
+ JSContext* cx, AbstractFramePtr frame, const JS::AutoRequireNoGC& nogc,
|
|
+ FrameFn fn) {
|
|
+ // GC is disallowed because it may mutate the vector we are iterating.
|
|
Rooted<AbstractGeneratorObject*> genObj(
|
|
cx, frame.isGeneratorFrame() ? GetGeneratorObjectForFrame(cx, frame)
|
|
: nullptr);
|
|
@@ -3304,11 +3309,13 @@ void Debugger::forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
|
|
bool Debugger::getDebuggerFrames(AbstractFramePtr frame,
|
|
MutableHandle<DebuggerFrameVector> frames) {
|
|
bool hadOOM = false;
|
|
- forEachOnStackDebuggerFrame(frame, [&](Debugger*, DebuggerFrame* frameobj) {
|
|
- if (!hadOOM && !frames.append(frameobj)) {
|
|
- hadOOM = true;
|
|
- }
|
|
- });
|
|
+ JS::AutoAssertNoGC nogc;
|
|
+ forEachOnStackDebuggerFrame(frame, nogc,
|
|
+ [&](Debugger*, DebuggerFrame* frameobj) {
|
|
+ if (!hadOOM && !frames.append(frameobj)) {
|
|
+ hadOOM = true;
|
|
+ }
|
|
+ });
|
|
return !hadOOM;
|
|
}
|
|
|
|
@@ -6466,8 +6473,10 @@ bool Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from,
|
|
/* static */
|
|
bool DebugAPI::inFrameMaps(AbstractFramePtr frame) {
|
|
bool foundAny = false;
|
|
+ JS::AutoAssertNoGC nogc;
|
|
Debugger::forEachOnStackDebuggerFrame(
|
|
- frame, [&](Debugger*, DebuggerFrame* frameobj) { foundAny = true; });
|
|
+ frame, nogc,
|
|
+ [&](Debugger*, DebuggerFrame* frameobj) { foundAny = true; });
|
|
return foundAny;
|
|
}
|
|
|
|
@@ -6475,8 +6484,9 @@ bool DebugAPI::inFrameMaps(AbstractFramePtr frame) {
|
|
void Debugger::suspendGeneratorDebuggerFrames(JSContext* cx,
|
|
AbstractFramePtr frame) {
|
|
JSFreeOp* fop = cx->runtime()->defaultFreeOp();
|
|
+ JS::AutoAssertNoGC nogc;
|
|
forEachOnStackDebuggerFrame(
|
|
- frame, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
|
+ frame, nogc, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
|
dbg->frames.remove(frame);
|
|
|
|
#if DEBUG
|
|
@@ -6495,8 +6505,9 @@ void Debugger::suspendGeneratorDebuggerFrames(JSContext* cx,
|
|
void Debugger::terminateDebuggerFrames(JSContext* cx, AbstractFramePtr frame) {
|
|
JSFreeOp* fop = cx->runtime()->defaultFreeOp();
|
|
|
|
+ JS::AutoAssertNoGC nogc;
|
|
forEachOnStackOrSuspendedDebuggerFrame(
|
|
- cx, frame, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
|
+ cx, frame, nogc, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
|
Debugger::terminateDebuggerFrame(fop, dbg, dbgFrame, frame);
|
|
});
|
|
|
|
diff --git a/js/src/debugger/Debugger.h b/js/src/debugger/Debugger.h
|
|
index bc89e4bfb1..d9da8bbe36 100644
|
|
--- a/js/src/debugger/Debugger.h
|
|
+++ b/js/src/debugger/Debugger.h
|
|
@@ -930,11 +930,13 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
|
IsObserving observing);
|
|
|
|
template <typename FrameFn /* void (Debugger*, DebuggerFrame*) */>
|
|
- static void forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn);
|
|
+ static void forEachOnStackDebuggerFrame(AbstractFramePtr frame,
|
|
+ const JS::AutoRequireNoGC& nogc,
|
|
+ FrameFn fn);
|
|
template <typename FrameFn /* void (Debugger*, DebuggerFrame*) */>
|
|
- static void forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
|
|
- AbstractFramePtr frame,
|
|
- FrameFn fn);
|
|
+ static void forEachOnStackOrSuspendedDebuggerFrame(
|
|
+ JSContext* cx, AbstractFramePtr frame, const JS::AutoRequireNoGC& nogc,
|
|
+ FrameFn fn);
|
|
|
|
/*
|
|
* Return a vector containing all Debugger.Frame instances referring to
|
|
diff --git a/js/src/gc/GC.h b/js/src/gc/GC.h
|
|
index 9cee0190b6..c6fe40c263 100644
|
|
--- a/js/src/gc/GC.h
|
|
+++ b/js/src/gc/GC.h
|
|
@@ -179,7 +179,7 @@ static inline void MaybeVerifyBarriers(JSContext* cx, bool always = false) {}
|
|
* This works by updating the |JSContext::suppressGC| counter which is checked
|
|
* at the start of GC.
|
|
*/
|
|
-class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC {
|
|
+class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC : public JS::AutoRequireNoGC {
|
|
int32_t& suppressGC_;
|
|
|
|
public:
|
|
--
|
|
2.33.0
|
|
|