diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 9b8c67c9f1ff..407bc68ebdd3 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -486,7 +486,7 @@ class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoAssertOnGC * JSTRACE_SHAPE. |thing| should be non-null. */ extern JS_FRIEND_API(bool) -UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind); +UnmarkGrayGCThingRecursively(GCCellPtr thing); } /* namespace JS */ @@ -509,7 +509,7 @@ ExposeGCThingToActiveJS(JS::GCCellPtr thing) if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) JS::IncrementalReferenceBarrier(thing); else if (JS::GCThingIsMarkedGray(thing.asCell())) - JS::UnmarkGrayGCThingRecursively(thing.asCell(), thing.kind()); + JS::UnmarkGrayGCThingRecursively(thing); } static MOZ_ALWAYS_INLINE void diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index d1ef3181b4b2..1c8cc74564c4 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -196,6 +196,7 @@ class TenuredCell : public Cell // Access to the arena header. inline ArenaHeader *arenaHeader() const; inline AllocKind getAllocKind() const; + inline JSGCTraceKind getTraceKind() const; inline JS::Zone *zone() const; inline JS::Zone *zoneFromAnyThread() const; inline bool isInsideZone(JS::Zone *zone) const; @@ -1312,6 +1313,12 @@ TenuredCell::getAllocKind() const return arenaHeader()->getAllocKind(); } +JSGCTraceKind +TenuredCell::getTraceKind() const +{ + return MapAllocToTraceKind(getAllocKind()); +} + JS::Zone * TenuredCell::zone() const { @@ -1346,8 +1353,9 @@ TenuredCell::readBarrier(TenuredCell *thing) MapAllocToTraceKind(thing->getAllocKind())); MOZ_ASSERT(tmp == thing); } + JS::GCCellPtr cellptr(thing, thing->getTraceKind()); if (JS::GCThingIsMarkedGray(thing)) - JS::UnmarkGrayGCThingRecursively(thing, MapAllocToTraceKind(thing->getAllocKind())); + JS::UnmarkGrayGCThingRecursively(cellptr); } /* static */ MOZ_ALWAYS_INLINE void diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 3ee8c8e830af..9e6f07e05394 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -2110,10 +2110,12 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind) tracer->unmarkedAny |= childTracer.unmarkedAny; } -JS_FRIEND_API(bool) -JS::UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind) +static bool +UnmarkGrayCellRecursively(gc::Cell *cell, JSGCTraceKind kind) { - JSRuntime *rt = static_cast(thing)->runtimeFromMainThread(); + MOZ_ASSERT(cell); + + JSRuntime *rt = cell->runtimeFromMainThread(); // When the ReadBarriered type is used in a HashTable, it is difficult or // impossible to suppress the implicit cast operator while iterating for GC. @@ -2121,16 +2123,28 @@ JS::UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind) return false; bool unmarkedArg = false; - if (!IsInsideNursery(static_cast(thing))) { - if (!JS::GCThingIsMarkedGray(thing)) + if (cell->isTenured()) { + if (!cell->asTenured().isMarked(GRAY)) return false; - TenuredCell::fromPointer(thing)->unmark(js::gc::GRAY); + cell->asTenured().unmark(GRAY); unmarkedArg = true; } UnmarkGrayTracer trc(rt); - JS_TraceChildren(&trc, thing, kind); + JS_TraceChildren(&trc, cell, kind); return unmarkedArg || trc.unmarkedAny; } + +bool +js::UnmarkGrayShapeRecursively(Shape *shape) +{ + return UnmarkGrayCellRecursively(shape, JSTRACE_SHAPE); +} + +JS_FRIEND_API(bool) +JS::UnmarkGrayGCThingRecursively(JS::GCCellPtr thing) +{ + return UnmarkGrayCellRecursively(thing.asCell(), thing.kind()); +} diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index dbd0088cf322..769ae0fa51b6 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -410,6 +410,9 @@ ToMarkable(Cell *cell) void TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind); +bool +UnmarkGrayShapeRecursively(Shape *shape); + } /* namespace js */ #endif /* gc_Marking_h */ diff --git a/js/src/jspropertytree.cpp b/js/src/jspropertytree.cpp index 474274fb556b..bb8187df5783 100644 --- a/js/src/jspropertytree.cpp +++ b/js/src/jspropertytree.cpp @@ -172,7 +172,7 @@ PropertyTree::getChild(ExclusiveContext *cx, Shape *parentArg, StackShape &unroo parent->removeChild(existingShape); existingShape = nullptr; } else if (existingShape->isMarked(gc::GRAY)) { - JS::UnmarkGrayGCThingRecursively(existingShape, JSTRACE_SHAPE); + UnmarkGrayShapeRecursively(existingShape); } } diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index b78856f8e86d..cace19f39319 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -277,7 +277,7 @@ private: if (delegateMightNeedMarking && aKey.isObject()) { JSObject* kdelegate = js::GetWeakmapKeyDelegate(aKey.toObject()); if (kdelegate && !xpc_IsGrayGCThing(kdelegate)) { - if (JS::UnmarkGrayGCThingRecursively(aKey.asCell(), JSTRACE_OBJECT)) { + if (JS::UnmarkGrayGCThingRecursively(aKey)) { tracer->mAnyMarked = true; } } @@ -287,7 +287,7 @@ private: (!aKey || !xpc_IsGrayGCThing(aKey.asCell())) && (!aMap || !xpc_IsGrayGCThing(aMap)) && aValue.kind() != JSTRACE_SHAPE) { - if (JS::UnmarkGrayGCThingRecursively(aValue.asCell(), aValue.kind())) { + if (JS::UnmarkGrayGCThingRecursively(aValue)) { tracer->mAnyMarked = true; } }