зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1736604 - Part 1: Replace sweeping with tracing weak edges in WeakRef implementation r=sfink
Differential Revision: https://phabricator.services.mozilla.com/D128901
This commit is contained in:
Родитель
48823d0e19
Коммит
3649131338
|
@ -298,23 +298,27 @@ void GCRuntime::traceKeptObjects(JSTracer* trc) {
|
|||
|
||||
} // namespace gc
|
||||
|
||||
void WeakRefMap::sweep(gc::StoreBuffer* sbToLock) {
|
||||
static WeakRefObject* UnwrapWeakRef(JSObject* obj) {
|
||||
MOZ_ASSERT(!JS_IsDeadWrapper(obj));
|
||||
obj = UncheckedUnwrapWithoutExpose(obj);
|
||||
return &obj->as<WeakRefObject>();
|
||||
}
|
||||
|
||||
void WeakRefMap::traceWeak(JSTracer* trc, gc::StoreBuffer* sbToLock) {
|
||||
mozilla::Maybe<typename Base::Enum> e;
|
||||
for (e.emplace(*this); !e->empty(); e->popFront()) {
|
||||
// If target is dying, clear the target field of all weakRefs, and remove
|
||||
// the entry from the map.
|
||||
if (JS::GCPolicy<HeapPtrObject>::needsSweep(&e->front().mutableKey())) {
|
||||
auto result =
|
||||
TraceWeakEdge(trc, &e->front().mutableKey(), "WeakRef target");
|
||||
if (result.isDead()) {
|
||||
for (JSObject* obj : e->front().value()) {
|
||||
MOZ_ASSERT(!JS_IsDeadWrapper(obj));
|
||||
obj = UncheckedUnwrapWithoutExpose(obj);
|
||||
|
||||
WeakRefObject* weakRef = &obj->as<WeakRefObject>();
|
||||
weakRef->clearTarget();
|
||||
UnwrapWeakRef(obj)->clearTarget();
|
||||
}
|
||||
e->removeFront();
|
||||
} else {
|
||||
// Update the target field after compacting.
|
||||
e->front().value().sweep(e->front().mutableKey());
|
||||
e->front().value().traceWeak(trc, result.finalTarget());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,20 +330,15 @@ void WeakRefMap::sweep(gc::StoreBuffer* sbToLock) {
|
|||
|
||||
// Like GCVector::sweep, but this method will also update the target in every
|
||||
// weakRef in this GCVector.
|
||||
void WeakRefHeapPtrVector::sweep(HeapPtrObject& target) {
|
||||
void WeakRefHeapPtrVector::traceWeak(JSTracer* trc, JSObject* target) {
|
||||
HeapPtrObject* src = begin();
|
||||
HeapPtrObject* dst = begin();
|
||||
while (src != end()) {
|
||||
bool needsSweep = JS::GCPolicy<HeapPtrObject>::needsSweep(src);
|
||||
JSObject* obj = UncheckedUnwrapWithoutExpose(*src);
|
||||
MOZ_ASSERT(!JS_IsDeadWrapper(obj));
|
||||
|
||||
WeakRefObject* weakRef = &obj->as<WeakRefObject>();
|
||||
|
||||
if (needsSweep) {
|
||||
weakRef->clearTarget();
|
||||
auto result = TraceWeakEdge(trc, src, "WeakRef");
|
||||
if (result.isDead()) {
|
||||
UnwrapWeakRef(result.initialTarget())->clearTarget();
|
||||
} else {
|
||||
weakRef->setTargetUnbarriered(target.get());
|
||||
UnwrapWeakRef(result.finalTarget())->setTargetUnbarriered(target);
|
||||
|
||||
if (src != dst) {
|
||||
*dst = std::move(*src);
|
||||
|
|
|
@ -457,7 +457,7 @@ void Zone::prepareForCompacting() {
|
|||
void GCRuntime::sweepZoneAfterCompacting(MovingTracer* trc, Zone* zone) {
|
||||
MOZ_ASSERT(zone->isCollecting());
|
||||
traceWeakFinalizationRegistryEdges(trc, zone);
|
||||
zone->weakRefMap().sweep(&storeBuffer());
|
||||
zone->weakRefMap().traceWeak(trc, &storeBuffer());
|
||||
|
||||
zone->traceWeakMaps(trc);
|
||||
|
||||
|
|
|
@ -1276,7 +1276,7 @@ bool UniqueIdGCPolicy::traceWeak(JSTracer* trc, Cell** keyp, uint64_t* valuep) {
|
|||
void GCRuntime::sweepWeakRefs() {
|
||||
for (SweepGroupZonesIter zone(this); !zone.done(); zone.next()) {
|
||||
AutoSetThreadIsSweeping threadIsSweeping(zone);
|
||||
zone->weakRefMap().sweep(&storeBuffer());
|
||||
zone->weakRefMap().traceWeak(&sweepingTracer, &storeBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ class WeakRefHeapPtrVector
|
|||
using GCVector::GCVector;
|
||||
|
||||
// call in compacting, to update the target in each WeakRefObject.
|
||||
void sweep(js::HeapPtrObject& target);
|
||||
void traceWeak(JSTracer* trc, JSObject* target);
|
||||
};
|
||||
|
||||
// WeakRefMap is a per-zone GCHashMap, which maps from the target of the JS
|
||||
|
@ -128,7 +128,7 @@ class WeakRefMap
|
|||
using GCHashMap::GCHashMap;
|
||||
using Base = GCHashMap<HeapPtrObject, WeakRefHeapPtrVector,
|
||||
MovableCellHasher<HeapPtrObject>, ZoneAllocPolicy>;
|
||||
void sweep(gc::StoreBuffer* sbToLock);
|
||||
void traceWeak(JSTracer* trc, gc::StoreBuffer* sbToLock);
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
|
Загрузка…
Ссылка в новой задаче