Bug 1264300 - Don't evict the nursery unnecessarily in ZoneCellIter r=sfink a=abillings
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -190,17 +190,17 @@ class ZoneCellIterImpl
{
ArenaIter arenaIter;
ArenaCellIterImpl cellIter;
public:
ZoneCellIterImpl(JS::Zone* zone, AllocKind kind) {
JSRuntime* rt = zone->runtimeFromAnyThread();
MOZ_ASSERT(zone);
- MOZ_ASSERT(rt->gc.nursery.isEmpty());
+ MOZ_ASSERT_IF(IsNurseryAllocable(kind), rt->gc.nursery.isEmpty());
// We have a single-threaded runtime, so there's no need to protect
// against other threads iterating or allocating. However, we do have
// background finalization; we may have to wait for this to finish if
// it's currently active.
if (IsBackgroundFinalized(kind) && zone->arenas.needBackgroundFinalizeWait(kind))
rt->gc.waitBackgroundSweepEnd();
@@ -251,18 +251,20 @@ class ZoneCellIter
JS::AutoAssertNoAlloc noAlloc;
public:
ZoneCellIter(JS::Zone* zone, AllocKind kind) {
// If called from outside a GC, ensure that the heap is in a state
// that allows us to iterate.
JSRuntime* rt = zone->runtimeFromMainThread();
if (!rt->isHeapBusy()) {
- // Evict the nursery before iterating so we can see all things.
- rt->gc.evictNursery();
+ // If we are iterating a nursery-allocated kind then we need to
+ // evict first so that we can see all things.
+ if (IsNurseryAllocable(kind))
+ rt->gc.evictNursery();
// Assert that no GCs can occur while a ZoneCellIter is live.
noAlloc.disallowAlloc(rt);
}
impl.emplace(zone, kind);
}