From 8af6d2df695601287845d8b5676e501f8a41fe33 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 23 Jun 2020 15:22:58 +0000 Subject: [PATCH] Bug 1647325 - Trace weak edges of FinalizationRegistrationsObjects when required r=sfink FinalizationRegistrationsObject only holds a vector of weak pointers to FinalizationRecordObjects, but it still needs a trace method so that those weak pointers can get updated by a moving GC. Differential Revision: https://phabricator.services.mozilla.com/D80630 --- js/src/builtin/FinalizationRegistryObject.cpp | 21 +++++++++++++++---- js/src/gc/Tracer.h | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/js/src/builtin/FinalizationRegistryObject.cpp b/js/src/builtin/FinalizationRegistryObject.cpp index 329f5d1a142f..5391fe293f5f 100644 --- a/js/src/builtin/FinalizationRegistryObject.cpp +++ b/js/src/builtin/FinalizationRegistryObject.cpp @@ -154,7 +154,7 @@ const JSClassOps FinalizationRegistrationsObject::classOps_ = { nullptr, // call nullptr, // hasInstance nullptr, // construct - nullptr, // trace + FinalizationRegistrationsObject::trace, // trace }; /* static */ @@ -177,10 +177,21 @@ FinalizationRegistrationsObject* FinalizationRegistrationsObject::create( return object; } +/* static */ +void FinalizationRegistrationsObject::trace(JSTracer* trc, JSObject* obj) { + if (!trc->traceWeakEdges()) { + return; + } + + auto* self = &obj->as(); + TraceRange(trc, self->records()->length(), self->records()->begin(), + "FinalizationRegistrationsObject records"); +} + /* static */ void FinalizationRegistrationsObject::finalize(JSFreeOp* fop, JSObject* obj) { - auto rv = &obj->as(); - fop->delete_(obj, rv->records(), MemoryUse::FinalizationRecordVector); + auto* self = &obj->as(); + fop->delete_(obj, self->records(), MemoryUse::FinalizationRecordVector); } inline WeakFinalizationRecordVector* @@ -348,7 +359,9 @@ void FinalizationRegistryObject::trace(JSTracer* trc, JSObject* obj) { registrations->trace(trc); } - // The active record set is weakly held and is not traced. + // The active record set is weakly held and is not traced. For moving GC this + // is updated in sweep(), which is called for all FinalizationRegistryObjects + // in a zone. if (FinalizationRecordVector* records = registry->recordsToBeCleanedUp()) { records->trace(trc); diff --git a/js/src/gc/Tracer.h b/js/src/gc/Tracer.h index 95f92df4145f..bfcf95245d5d 100644 --- a/js/src/gc/Tracer.h +++ b/js/src/gc/Tracer.h @@ -235,7 +235,7 @@ inline bool TraceWeakEdge(JSTracer* trc, BarrieredBase* thingp, // Trace all edges contained in the given array. template -void TraceRange(JSTracer* trc, size_t len, WriteBarriered* vec, +void TraceRange(JSTracer* trc, size_t len, BarrieredBase* vec, const char* name) { gc::TraceRangeInternal( trc, len, gc::ConvertToBase(vec[0].unsafeUnbarrieredForTracing()), name);