Bug 1654523 - Insist that iteration callbacks don't GC r=sfink,mccr8

Differential Revision: https://phabricator.services.mozilla.com/D84500
This commit is contained in:
Jon Coppeard 2020-07-23 02:31:57 +00:00
Родитель a4921d9a4c
Коммит f47569e9d9
16 изменённых файлов: 105 добавлений и 75 удалений

Просмотреть файл

@ -357,7 +357,8 @@ ContentPrincipal::SetDomain(nsIURI* aDomain) {
// Set the changed-document-domain flag on compartments containing realms
// using this principal.
auto cb = [](JSContext*, void*, JS::Handle<JS::Realm*> aRealm) {
auto cb = [](JSContext*, void*, JS::Realm* aRealm,
const JS::AutoRequireNoGC& nogc) {
JS::Compartment* comp = JS::GetCompartmentForRealm(aRealm);
xpc::SetCompartmentChangedDocumentDomain(comp);
};

Просмотреть файл

@ -997,8 +997,8 @@ class WorkerJSContextStats final : public JS::RuntimeStats {
const nsCString& Path() const { return mRtPath; }
virtual void initExtraZoneStats(JS::Zone* aZone,
JS::ZoneStats* aZoneStats) override {
virtual void initExtraZoneStats(JS::Zone* aZone, JS::ZoneStats* aZoneStats,
const JS::AutoRequireNoGC& nogc) override {
MOZ_ASSERT(!aZoneStats->extra);
// ReportJSRuntimeExplicitTreeStats expects that
@ -1012,8 +1012,9 @@ class WorkerJSContextStats final : public JS::RuntimeStats {
aZoneStats->extra = extras;
}
virtual void initExtraRealmStats(JS::Handle<JS::Realm*> aRealm,
JS::RealmStats* aRealmStats) override {
virtual void initExtraRealmStats(JS::Realm* aRealm,
JS::RealmStats* aRealmStats,
const JS::AutoRequireNoGC& nogc) override {
MOZ_ASSERT(!aRealmStats->extra);
// ReportJSRuntimeExplicitTreeStats expects that

Просмотреть файл

@ -19,6 +19,7 @@
#include "jspubtd.h"
#include "js/AllocPolicy.h"
#include "js/GCAPI.h"
#include "js/HashTable.h"
#include "js/TracingAPI.h"
#include "js/Utility.h"
@ -846,9 +847,10 @@ struct RuntimeStats {
mozilla::MallocSizeOf mallocSizeOf_;
virtual void initExtraRealmStats(JS::Handle<JS::Realm*> realm,
RealmStats* rstats) = 0;
virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0;
virtual void initExtraRealmStats(JS::Realm* realm, RealmStats* rstats,
const JS::AutoRequireNoGC& nogc) = 0;
virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats,
const JS::AutoRequireNoGC& nogc) = 0;
#undef FOR_EACH_SIZE
};

Просмотреть файл

@ -8,6 +8,7 @@
#define js_Realm_h
#include "jspubtd.h"
#include "js/GCAPI.h"
#include "js/GCPolicyAPI.h"
#include "js/TypeDecls.h" // forward-declaration of JS::Realm
@ -84,8 +85,9 @@ typedef void (*DestroyRealmCallback)(JSFreeOp* fop, Realm* realm);
extern JS_PUBLIC_API void SetDestroyRealmCallback(
JSContext* cx, DestroyRealmCallback callback);
typedef void (*RealmNameCallback)(JSContext* cx, Handle<Realm*> realm,
char* buf, size_t bufsize);
using RealmNameCallback = void (*)(JSContext* cx, Realm* realm, char* buf,
size_t bufsize,
const JS::AutoRequireNoGC& nogc);
// Set the callback SpiderMonkey calls to get the name of a realm, for
// diagnostic output.
@ -94,7 +96,7 @@ extern JS_PUBLIC_API void SetRealmNameCallback(JSContext* cx,
// Get the global object for the given realm. This only returns nullptr during
// GC, between collecting the global object and destroying the Realm.
extern JS_PUBLIC_API JSObject* GetRealmGlobalOrNull(Handle<Realm*> realm);
extern JS_PUBLIC_API JSObject* GetRealmGlobalOrNull(Realm* realm);
// Initialize standard JS class constructors, prototypes, and any top-level
// functions and constants associated with the standard classes (e.g. isNaN

Просмотреть файл

@ -71,11 +71,15 @@ extern unsigned NotifyGCPreSwap(JSObject* a, JSObject* b);
extern void NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned preResult);
using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::Chunk*);
using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*);
using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::Chunk*,
const JS::AutoRequireNoGC&);
using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*,
const JS::AutoRequireNoGC&);
using IterateArenaCallback = void (*)(JSRuntime*, void*, gc::Arena*,
JS::TraceKind, size_t);
using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t);
JS::TraceKind, size_t,
const JS::AutoRequireNoGC&);
using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t,
const JS::AutoRequireNoGC&);
/*
* This function calls |zoneCallback| on every zone, |realmCallback| on

Просмотреть файл

@ -21,12 +21,12 @@ using namespace js::gc;
static void IterateRealmsArenasCellsUnbarriered(
JSContext* cx, Zone* zone, void* data,
JS::IterateRealmCallback realmCallback, IterateArenaCallback arenaCallback,
IterateCellCallback cellCallback) {
IterateCellCallback cellCallback, const JS::AutoRequireNoGC& nogc) {
{
Rooted<Realm*> realm(cx);
for (RealmsInZoneIter r(zone); !r.done(); r.next()) {
realm = r;
(*realmCallback)(cx, data, realm);
(*realmCallback)(cx, data, realm, nogc);
}
}
@ -36,10 +36,10 @@ static void IterateRealmsArenasCellsUnbarriered(
for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) {
Arena* arena = aiter.get();
(*arenaCallback)(cx->runtime(), data, arena, traceKind, thingSize);
(*arenaCallback)(cx->runtime(), data, arena, traceKind, thingSize, nogc);
for (ArenaCellIter cell(arena); !cell.done(); cell.next()) {
(*cellCallback)(cx->runtime(), data, JS::GCCellPtr(cell, traceKind),
thingSize);
thingSize, nogc);
}
}
}
@ -51,11 +51,12 @@ void js::IterateHeapUnbarriered(JSContext* cx, void* data,
IterateArenaCallback arenaCallback,
IterateCellCallback cellCallback) {
AutoPrepareForTracing prep(cx);
JS::AutoSuppressGCAnalysis nogc(cx);
for (ZonesIter zone(cx->runtime(), WithAtoms); !zone.done(); zone.next()) {
(*zoneCallback)(cx->runtime(), data, zone);
(*zoneCallback)(cx->runtime(), data, zone, nogc);
IterateRealmsArenasCellsUnbarriered(cx, zone, data, realmCallback,
arenaCallback, cellCallback);
arenaCallback, cellCallback, nogc);
}
}
@ -65,20 +66,22 @@ void js::IterateHeapUnbarrieredForZone(JSContext* cx, Zone* zone, void* data,
IterateArenaCallback arenaCallback,
IterateCellCallback cellCallback) {
AutoPrepareForTracing prep(cx);
JS::AutoSuppressGCAnalysis nogc(cx);
(*zoneCallback)(cx->runtime(), data, zone);
(*zoneCallback)(cx->runtime(), data, zone, nogc);
IterateRealmsArenasCellsUnbarriered(cx, zone, data, realmCallback,
arenaCallback, cellCallback);
arenaCallback, cellCallback, nogc);
}
void js::IterateChunks(JSContext* cx, void* data,
IterateChunkCallback chunkCallback) {
AutoPrepareForTracing prep(cx);
AutoLockGC lock(cx->runtime());
JS::AutoSuppressGCAnalysis nogc(cx);
for (auto chunk = cx->runtime()->gc.allNonEmptyChunks(lock); !chunk.done();
chunk.next()) {
chunkCallback(cx->runtime(), data, chunk);
chunkCallback(cx->runtime(), data, chunk, nogc);
}
}
@ -176,15 +179,18 @@ void js::IterateLazyScripts(JSContext* cx, Realm* realm, void* data,
IterateScriptsImpl</*HasBytecode = */ false>(cx, realm, data, scriptCallback);
}
void js::IterateGrayObjects(Zone* zone, GCThingCallback cellCallback,
void js::IterateGrayObjects(Zone* zone, IterateGCThingCallback cellCallback,
void* data) {
MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
AutoPrepareForTracing prep(TlsContext.get());
JSContext* cx = TlsContext.get();
AutoPrepareForTracing prep(cx);
JS::AutoSuppressGCAnalysis nogc(cx);
for (auto kind : ObjectAllocKinds()) {
for (GrayObjectIter obj(zone, kind); !obj.done(); obj.next()) {
if (obj->asTenured().isMarkedGray()) {
cellCallback(data, JS::GCCellPtr(obj.get()));
cellCallback(data, JS::GCCellPtr(obj.get()), nogc);
}
}
}
@ -219,11 +225,12 @@ JS_PUBLIC_API void JS_IterateCompartmentsInZone(
JS_PUBLIC_API void JS::IterateRealms(JSContext* cx, void* data,
JS::IterateRealmCallback realmCallback) {
AutoTraceSession session(cx->runtime());
JS::AutoSuppressGCAnalysis nogc(cx);
Rooted<Realm*> realm(cx);
for (RealmsIter r(cx->runtime()); !r.done(); r.next()) {
realm = r;
(*realmCallback)(cx, data, realm);
(*realmCallback)(cx, data, realm, nogc);
}
}
@ -233,6 +240,7 @@ JS_PUBLIC_API void JS::IterateRealmsWithPrincipals(
MOZ_ASSERT(principals);
AutoTraceSession session(cx->runtime());
JS::AutoSuppressGCAnalysis nogc(cx);
Rooted<Realm*> realm(cx);
for (RealmsIter r(cx->runtime()); !r.done(); r.next()) {
@ -240,7 +248,7 @@ JS_PUBLIC_API void JS::IterateRealmsWithPrincipals(
continue;
}
realm = r;
(*realmCallback)(cx, data, realm);
(*realmCallback)(cx, data, realm, nogc);
}
}
@ -248,10 +256,11 @@ JS_PUBLIC_API void JS::IterateRealmsInCompartment(
JSContext* cx, JS::Compartment* compartment, void* data,
JS::IterateRealmCallback realmCallback) {
AutoTraceSession session(cx->runtime());
JS::AutoSuppressGCAnalysis nogc(cx);
Rooted<Realm*> realm(cx);
for (RealmsInCompartmentIter r(compartment); !r.done(); r.next()) {
realm = r;
(*realmCallback)(cx, data, realm);
(*realmCallback)(cx, data, realm, nogc);
}
}

Просмотреть файл

@ -452,8 +452,8 @@ extern JS_PUBLIC_API JS::Realm* EnterRealm(JSContext* cx, JSObject* target);
extern JS_PUBLIC_API void LeaveRealm(JSContext* cx, JS::Realm* oldRealm);
using IterateRealmCallback = void (*)(JSContext* cx, void* data,
Handle<Realm*> realm);
using IterateRealmCallback = void (*)(JSContext* cx, void* data, Realm* realm,
const AutoRequireNoGC& nogc);
/**
* This function calls |realmCallback| on every realm. Beware that there is no

Просмотреть файл

@ -548,14 +548,15 @@ JS_FRIEND_API bool js::IsCompartmentZoneSweepingOrCompacting(
}
JS_FRIEND_API void js::VisitGrayWrapperTargets(Zone* zone,
GCThingCallback callback,
IterateGCThingCallback callback,
void* closure) {
JS::AutoSuppressGCAnalysis nogc;
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
for (Compartment::ObjectWrapperEnum e(comp); !e.empty(); e.popFront()) {
JSObject* target = e.front().key();
if (target->isMarkedGray()) {
JS::AutoSuppressGCAnalysis nogc;
callback(closure, JS::GCCellPtr(target));
callback(closure, JS::GCCellPtr(target), nogc);
}
}
}
@ -1156,16 +1157,17 @@ static char MarkDescriptor(gc::Cell* thing) {
return 'W';
}
static void DumpHeapVisitZone(JSRuntime* rt, void* data, Zone* zone) {
static void DumpHeapVisitZone(JSRuntime* rt, void* data, Zone* zone,
const JS::AutoRequireNoGC& nogc) {
DumpHeapTracer* dtrc = static_cast<DumpHeapTracer*>(data);
fprintf(dtrc->output, "# zone %p\n", (void*)zone);
}
static void DumpHeapVisitRealm(JSContext* cx, void* data,
Handle<Realm*> realm) {
static void DumpHeapVisitRealm(JSContext* cx, void* data, Realm* realm,
const JS::AutoRequireNoGC& nogc) {
char name[1024];
if (auto nameCallback = cx->runtime()->realmNameCallback) {
nameCallback(cx, realm, name, sizeof(name));
nameCallback(cx, realm, name, sizeof(name), nogc);
} else {
strcpy(name, "<unknown>");
}
@ -1176,14 +1178,16 @@ static void DumpHeapVisitRealm(JSContext* cx, void* data,
}
static void DumpHeapVisitArena(JSRuntime* rt, void* data, gc::Arena* arena,
JS::TraceKind traceKind, size_t thingSize) {
JS::TraceKind traceKind, size_t thingSize,
const JS::AutoRequireNoGC& nogc) {
DumpHeapTracer* dtrc = static_cast<DumpHeapTracer*>(data);
fprintf(dtrc->output, "# arena allockind=%u size=%u\n",
unsigned(arena->getAllocKind()), unsigned(thingSize));
}
static void DumpHeapVisitCell(JSRuntime* rt, void* data, JS::GCCellPtr cellptr,
size_t thingSize) {
size_t thingSize,
const JS::AutoRequireNoGC& nogc) {
DumpHeapTracer* dtrc = static_cast<DumpHeapTracer*>(data);
char cellDesc[1024 * 32];
JS_GetTraceThingInfo(cellDesc, sizeof(cellDesc), dtrc, cellptr.asCell(),

Просмотреть файл

@ -473,18 +473,17 @@ extern JS_FRIEND_API bool ZoneGlobalsAreAllGray(JS::Zone* zone);
extern JS_FRIEND_API bool IsCompartmentZoneSweepingOrCompacting(
JS::Compartment* comp);
using GCThingCallback = void (*)(void*, JS::GCCellPtr);
using IterateGCThingCallback = void (*)(void*, JS::GCCellPtr,
const JS::AutoRequireNoGC&);
extern JS_FRIEND_API void VisitGrayWrapperTargets(JS::Zone* zone,
GCThingCallback callback,
void* closure);
extern JS_FRIEND_API void VisitGrayWrapperTargets(
JS::Zone* zone, IterateGCThingCallback callback, void* closure);
/**
* Invoke cellCallback on every gray JSObject in the given zone.
*/
extern JS_FRIEND_API void IterateGrayObjects(JS::Zone* zone,
GCThingCallback cellCallback,
void* data);
extern JS_FRIEND_API void IterateGrayObjects(
JS::Zone* zone, IterateGCThingCallback cellCallback, void* data);
#if defined(JS_GC_ZEAL) || defined(DEBUG)
// Trace the heap and check there are no black to gray edges. These are

Просмотреть файл

@ -469,8 +469,7 @@ void LCovRealm::writeRealmName(JS::Realm* realm) {
{
// Hazard analysis cannot tell that the callback does not GC.
JS::AutoSuppressGCAnalysis nogc;
Rooted<Realm*> rootedRealm(cx, realm);
(*cx->runtime()->realmNameCallback)(cx, rootedRealm, name, sizeof(name));
(*cx->runtime()->realmNameCallback)(cx, realm, name, sizeof(name), nogc);
}
for (char* s = name; s < name + sizeof(name) && *s; s++) {
if (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z') ||

Просмотреть файл

@ -184,7 +184,8 @@ struct StatsClosure {
};
static void DecommittedArenasChunkCallback(JSRuntime* rt, void* data,
gc::Chunk* chunk) {
gc::Chunk* chunk,
const JS::AutoRequireNoGC& nogc) {
// This case is common and fast to check. Do it first.
if (chunk->decommittedArenas.isAllClear()) {
return;
@ -200,7 +201,8 @@ static void DecommittedArenasChunkCallback(JSRuntime* rt, void* data,
*static_cast<size_t*>(data) += n;
}
static void StatsZoneCallback(JSRuntime* rt, void* data, Zone* zone) {
static void StatsZoneCallback(JSRuntime* rt, void* data, Zone* zone,
const JS::AutoRequireNoGC& nogc) {
// Append a new RealmStats to the vector.
RuntimeStats* rtStats = static_cast<StatsClosure*>(data)->rtStats;
@ -208,7 +210,7 @@ static void StatsZoneCallback(JSRuntime* rt, void* data, Zone* zone) {
MOZ_ALWAYS_TRUE(rtStats->zoneStatsVector.growBy(1));
ZoneStats& zStats = rtStats->zoneStatsVector.back();
zStats.initStrings();
rtStats->initExtraZoneStats(zone, &zStats);
rtStats->initExtraZoneStats(zone, &zStats, nogc);
rtStats->currZoneStats = &zStats;
zone->addSizeOfIncludingThis(
@ -220,8 +222,8 @@ static void StatsZoneCallback(JSRuntime* rt, void* data, Zone* zone) {
&zStats.scriptCountsMap);
}
static void StatsRealmCallback(JSContext* cx, void* data,
Handle<Realm*> realm) {
static void StatsRealmCallback(JSContext* cx, void* data, Realm* realm,
const JS::AutoRequireNoGC& nogc) {
// Append a new RealmStats to the vector.
RuntimeStats* rtStats = static_cast<StatsClosure*>(data)->rtStats;
@ -229,7 +231,7 @@ static void StatsRealmCallback(JSContext* cx, void* data,
MOZ_ALWAYS_TRUE(rtStats->realmStatsVector.growBy(1));
RealmStats& realmStats = rtStats->realmStatsVector.back();
realmStats.initClasses();
rtStats->initExtraRealmStats(realm, &realmStats);
rtStats->initExtraRealmStats(realm, &realmStats, nogc);
realm->setRealmStats(&realmStats);
@ -245,7 +247,8 @@ static void StatsRealmCallback(JSContext* cx, void* data,
}
static void StatsArenaCallback(JSRuntime* rt, void* data, gc::Arena* arena,
JS::TraceKind traceKind, size_t thingSize) {
JS::TraceKind traceKind, size_t thingSize,
const JS::AutoRequireNoGC& nogc) {
RuntimeStats* rtStats = static_cast<StatsClosure*>(data)->rtStats;
// The admin space includes (a) the header fields and (b) the padding
@ -325,7 +328,8 @@ static void CollectScriptSourceStats(StatsClosure* closure, ScriptSource* ss) {
// profile speed for complex pages such as gmail.com.
template <Granularity granularity>
static void StatsCellCallback(JSRuntime* rt, void* data, JS::GCCellPtr cellptr,
size_t thingSize) {
size_t thingSize,
const JS::AutoRequireNoGC& nogc) {
StatsClosure* closure = static_cast<StatsClosure*>(data);
RuntimeStats* rtStats = closure->rtStats;
ZoneStats* zStats = rtStats->currZoneStats;
@ -794,11 +798,11 @@ class SimpleJSRuntimeStats : public JS::RuntimeStats {
explicit SimpleJSRuntimeStats(MallocSizeOf mallocSizeOf)
: JS::RuntimeStats(mallocSizeOf) {}
virtual void initExtraZoneStats(JS::Zone* zone,
JS::ZoneStats* zStats) override {}
virtual void initExtraZoneStats(JS::Zone* zone, JS::ZoneStats* zStats,
const JS::AutoRequireNoGC& nogc) override {}
virtual void initExtraRealmStats(Handle<Realm*> realm,
JS::RealmStats* realmStats) override {}
virtual void initExtraRealmStats(Realm* realm, JS::RealmStats* realmStats,
const JS::AutoRequireNoGC& nogc) override {}
};
JS_PUBLIC_API bool AddSizeOfTab(JSContext* cx, HandleObject obj,

Просмотреть файл

@ -872,7 +872,7 @@ JS_PUBLIC_API void JS::SetRealmNameCallback(JSContext* cx,
cx->runtime()->realmNameCallback = callback;
}
JS_PUBLIC_API JSObject* JS::GetRealmGlobalOrNull(Handle<JS::Realm*> realm) {
JS_PUBLIC_API JSObject* JS::GetRealmGlobalOrNull(JS::Realm* realm) {
return realm->maybeGlobal();
}

Просмотреть файл

@ -2044,7 +2044,8 @@ class JSMainRuntimeRealmsReporter final : public nsIMemoryReporter {
js::Vector<nsCString, 0, js::SystemAllocPolicy> paths;
};
static void RealmCallback(JSContext* cx, void* vdata, Handle<Realm*> realm) {
static void RealmCallback(JSContext* cx, void* vdata, Realm* realm,
const JS::AutoRequireNoGC& nogc) {
// silently ignore OOM errors
Data* data = static_cast<Data*>(vdata);
nsCString path;
@ -2147,8 +2148,8 @@ class XPCJSRuntimeStats : public JS::RuntimeStats {
}
}
virtual void initExtraZoneStats(JS::Zone* zone,
JS::ZoneStats* zStats) override {
virtual void initExtraZoneStats(JS::Zone* zone, JS::ZoneStats* zStats,
const JS::AutoRequireNoGC& nogc) override {
xpc::ZoneStatsExtras* extras = new xpc::ZoneStatsExtras;
extras->pathPrefix.AssignLiteral("explicit/js-non-window/zones/");
@ -2174,8 +2175,8 @@ class XPCJSRuntimeStats : public JS::RuntimeStats {
zStats->extra = extras;
}
virtual void initExtraRealmStats(Handle<Realm*> realm,
JS::RealmStats* realmStats) override {
virtual void initExtraRealmStats(Realm* realm, JS::RealmStats* realmStats,
const JS::AutoRequireNoGC& nogc) override {
xpc::RealmStatsExtras* extras = new xpc::RealmStatsExtras;
nsCString rName;
GetRealmName(realm, rName, &mAnonymizeID, /* replaceSlashes = */ true);
@ -2661,8 +2662,9 @@ static void SetUseCounterCallback(JSObject* obj, JSUseCounter counter) {
}
}
static void GetRealmNameCallback(JSContext* cx, Handle<Realm*> realm, char* buf,
size_t bufsize) {
static void GetRealmNameCallback(JSContext* cx, Realm* realm, char* buf,
size_t bufsize,
const JS::AutoRequireNoGC& nogc) {
nsCString name;
// This is called via the JSAPI and isn't involved in memory reporting, so
// we don't need to anonymize realm names.

Просмотреть файл

@ -478,7 +478,8 @@ void XPCWrappedNativeScope::AddSizeOfIncludingThis(
scopeSizeInfo->mScopeAndMapSize +=
mWrappedNativeProtoMap->SizeOfIncludingThis(scopeSizeInfo->mMallocSizeOf);
auto realmCb = [](JSContext*, void* aData, JS::Handle<JS::Realm*> aRealm) {
auto realmCb = [](JSContext*, void* aData, JS::Realm* aRealm,
const JS::AutoRequireNoGC& nogc) {
auto* scopeSizeInfo = static_cast<ScopeSizeInfo*>(aData);
JSObject* global = GetRealmGlobalOrNull(aRealm);
if (global && dom::HasProtoAndIfaceCache(global)) {

Просмотреть файл

@ -436,7 +436,8 @@ bool TraversalTracer::onChild(const JS::GCCellPtr& aThing) {
return true;
}
static void NoteJSChildGrayWrapperShim(void* aData, JS::GCCellPtr aThing) {
static void NoteJSChildGrayWrapperShim(void* aData, JS::GCCellPtr aThing,
const JS::AutoRequireNoGC& nogc) {
TraversalTracer* trc = static_cast<TraversalTracer*>(aData);
trc->onChild(aThing);
}
@ -926,8 +927,8 @@ void CycleCollectedJSRuntime::TraverseZone(
}
/* static */
void CycleCollectedJSRuntime::TraverseObjectShim(void* aData,
JS::GCCellPtr aThing) {
void CycleCollectedJSRuntime::TraverseObjectShim(
void* aData, JS::GCCellPtr aThing, const JS::AutoRequireNoGC& nogc) {
TraverseObjectShimClosure* closure =
static_cast<TraverseObjectShimClosure*>(aData);

Просмотреть файл

@ -198,7 +198,8 @@ class CycleCollectedJSRuntime {
void TraverseZone(JS::Zone* aZone, nsCycleCollectionTraversalCallback& aCb);
static void TraverseObjectShim(void* aData, JS::GCCellPtr aThing);
static void TraverseObjectShim(void* aData, JS::GCCellPtr aThing,
const JS::AutoRequireNoGC& nogc);
void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb);