Improve dead compartment collection js/src/gc

This commit is contained in:
win7-7 2019-04-29 12:02:24 +03:00 • committed by Roy Tam
commit c1b4fc1442
4 changed files with 32 additions and 8 deletions

View file

@ -900,7 +900,8 @@ class GCRuntime
void requestMajorGC(JS::gcreason::Reason reason); void requestMajorGC(JS::gcreason::Reason reason);
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis); SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis);
void budgetIncrementalGC(SliceBudget& budget, AutoLockForExclusiveAccess& lock); void budgetIncrementalGC(JS::gcreason::Reason reason, SliceBudget& budget,
AutoLockForExclusiveAccess& lock);
void resetIncrementalGC(AbortReason reason, AutoLockForExclusiveAccess& lock); void resetIncrementalGC(AbortReason reason, AutoLockForExclusiveAccess& lock);
// Assert if the system state is such that we should never // Assert if the system state is such that we should never
@ -915,6 +916,7 @@ class GCRuntime
void collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::Reason reason) JS_HAZ_GC_CALL; void collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::Reason reason) JS_HAZ_GC_CALL;
MOZ_MUST_USE bool gcCycle(bool nonincrementalByAPI, SliceBudget& budget, MOZ_MUST_USE bool gcCycle(bool nonincrementalByAPI, SliceBudget& budget,
JS::gcreason::Reason reason); JS::gcreason::Reason reason);
bool shouldRepeatForDeadZone(JS::gcreason::Reason reason);
void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason, void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason,
AutoLockForExclusiveAccess& lock); AutoLockForExclusiveAccess& lock);

View file

@ -478,6 +478,7 @@ js::gc::GCRuntime::bufferGrayRoots()
for (GCZonesIter zone(rt); !zone.done(); zone.next()) for (GCZonesIter zone(rt); !zone.done(); zone.next())
MOZ_ASSERT(zone->gcGrayRoots.empty()); MOZ_ASSERT(zone->gcGrayRoots.empty());
gcstats::AutoPhase ap(stats, gcstats::PHASE_BUFFER_GRAY_ROOTS);
BufferGrayRootsTracer grayBufferer(rt); BufferGrayRootsTracer grayBufferer(rt);
if (JSTraceDataOp op = grayRootTracer.op) if (JSTraceDataOp op = grayRootTracer.op)
@ -540,4 +541,3 @@ GCRuntime::resetBufferedGrayRoots() const
for (GCZonesIter zone(rt); !zone.done(); zone.next()) for (GCZonesIter zone(rt); !zone.done(); zone.next())
zone->gcGrayRoots.clearAndFree(); zone->gcGrayRoots.clearAndFree();
} }

View file

@ -370,6 +370,21 @@ Zone::fixupAfterMovingGC()
fixupInitialShapeTable(); fixupInitialShapeTable();
} }
bool
Zone::addTypeDescrObject(JSContext* cx, HandleObject obj)
{
// Type descriptor objects are always tenured so we don't need post barriers
// on the set.
MOZ_ASSERT(!IsInsideNursery(obj));
if (!typeDescrObjects.put(obj)) {
ReportOutOfMemory(cx);
return false;
}
return true;
}
ZoneList::ZoneList() ZoneList::ZoneList()
: head(nullptr), tail(nullptr) : head(nullptr), tail(nullptr)
{} {}

View file

@ -349,11 +349,18 @@ struct Zone : public JS::shadow::Zone,
// Keep track of all TypeDescr and related objects in this compartment. // Keep track of all TypeDescr and related objects in this compartment.
// This is used by the GC to trace them all first when compacting, since the // This is used by the GC to trace them all first when compacting, since the
// TypedObject trace hook may access these objects. // TypedObject trace hook may access these objects.
using TypeDescrObjectSet = js::GCHashSet<js::HeapPtr<JSObject*>,
js::MovableCellHasher<js::HeapPtr<JSObject*>>, //
// There are no barriers here - the set contains only tenured objects so no
// post-barrier is required, and these are weak references so no pre-barrier
// is required.
using TypeDescrObjectSet = js::GCHashSet<JSObject*,
js::MovableCellHasher<JSObject*>,
js::SystemAllocPolicy>; js::SystemAllocPolicy>;
JS::WeakCache<TypeDescrObjectSet> typeDescrObjects; JS::WeakCache<TypeDescrObjectSet> typeDescrObjects;
bool addTypeDescrObject(JSContext* cx, HandleObject obj);
// Malloc counter to measure memory pressure for GC scheduling. It runs from // Malloc counter to measure memory pressure for GC scheduling. It runs from
// gcMaxMallocBytes down to zero. This counter should be used only when it's // gcMaxMallocBytes down to zero. This counter should be used only when it's