Bug 1293209 - Don't assert tables are empty if the embedding leaked JS GC things r=terrence

This commit is contained in:
Jon Coppeard 2016-08-19 10:44:01 +01:00
parent 67de9ad6e4
commit d170af87c1
4 changed files with 26 additions and 3 deletions

View File

@ -682,6 +682,12 @@ class GCRuntime
return uid;
}
#ifdef DEBUG
bool shutdownCollectedEverything() const {
return arenasEmptyAtShutdown;
}
#endif
public:
// Internal public interface
State state() const { return incrementalState; }
@ -1350,6 +1356,8 @@ class GCRuntime
size_t noGCOrAllocationCheck;
size_t noNurseryAllocationCheck;
bool arenasEmptyAtShutdown;
#endif
/* Synchronize GC heap access between main thread and GCHelperState. */

View File

@ -64,6 +64,12 @@ Zone::~Zone()
js_delete(debuggers);
js_delete(jitZone_);
#ifdef DEBUG
// Avoid assertion destroying the weak map list if the embedding leaked GC things.
if (!rt->gc.shutdownCollectedEverything())
gcWeakMapList.clear();
#endif
}
bool Zone::init(bool isSystemArg)

View File

@ -869,6 +869,7 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
inUnsafeRegion(0),
noGCOrAllocationCheck(0),
noNurseryAllocationCheck(0),
arenasEmptyAtShutdown(true),
#endif
allocTask(rt, emptyChunks_),
decommitTask(rt),
@ -3508,7 +3509,9 @@ Zone::sweepCompartments(FreeOp* fop, bool keepAtleastOne, bool destroyingRuntime
void
GCRuntime::sweepZones(FreeOp* fop, bool destroyingRuntime)
{
MOZ_ASSERT_IF(destroyingRuntime, rt->gc.numActiveZoneIters == 0);
MOZ_ASSERT_IF(destroyingRuntime, numActiveZoneIters == 0);
MOZ_ASSERT_IF(destroyingRuntime, arenasEmptyAtShutdown);
if (rt->gc.numActiveZoneIters)
return;
@ -3539,14 +3542,17 @@ GCRuntime::sweepZones(FreeOp* fop, bool destroyingRuntime)
// We are about to delete the Zone; this will leave the Zone*
// in the arena header dangling if there are any arenas
// remaining at this point.
mozilla::DebugOnly<bool> arenasEmpty = zone->arenas.checkEmptyArenaLists();
#ifdef DEBUG
if (!zone->arenas.checkEmptyArenaLists())
arenasEmptyAtShutdown = false;
#endif
if (callback)
callback(zone);
zone->sweepCompartments(fop, false, destroyingRuntime);
MOZ_ASSERT(zone->compartments.empty());
MOZ_ASSERT_IF(arenasEmpty, zone->typeDescrObjects.empty());
MOZ_ASSERT_IF(arenasEmptyAtShutdown, zone->typeDescrObjects.empty());
fop->delete_(zone);
stats.sweptZone();
continue;

View File

@ -2524,6 +2524,9 @@ js::FreeScriptData(JSRuntime* rt, AutoLockForExclusiveAccess& lock)
if (!table.initialized())
return;
// The table should be empty unless the embedding leaked GC things.
MOZ_ASSERT_IF(rt->gc.shutdownCollectedEverything(), table.empty());
for (ScriptDataTable::Enum e(table); !e.empty(); e.popFront()) {
#ifdef DEBUG
SharedScriptData* scriptData = e.front();