Bug 1287399 - Allow the pre-barrier verifier to work in the presence of OMT parsing; r=jonco

--HG--
extra : rebase_source : 4983f6ef29dd4479d215169be85b481328e48784
This commit is contained in:
Terrence Cole 2016-07-19 10:49:39 -07:00
parent e65989db46
commit b8be00dd83
3 changed files with 38 additions and 0 deletions

View File

@ -1304,6 +1304,9 @@ TenuredCell::readBarrier(TenuredCell* thing)
UnmarkGrayCellRecursively(thing, thing->getTraceKind());
}
void
AssertSafeToSkipBarrier(TenuredCell* thing);
/* static */ MOZ_ALWAYS_INLINE void
TenuredCell::writeBarrierPre(TenuredCell* thing)
{
@ -1312,6 +1315,22 @@ TenuredCell::writeBarrierPre(TenuredCell* thing)
if (!thing || thing->shadowRuntimeFromAnyThread()->isHeapCollecting())
return;
#ifdef JS_GC_ZEAL
// When verifying pre barriers we need to switch on all barriers, even
// those on the Atoms Zone. Normally, we never enter a parse task when
// collecting in the atoms zone, so will filter out atoms below.
// Unfortuantely, If we try that when verifying pre-barriers, we'd never be
// able to handle OMT parse tasks at all as we switch on the verifier any
// time we're not doing GC. This would cause us to deadlock, as OMT parsing
// is meant to resume after GC work completes. Instead we filter out any
// OMT barriers that reach us and assert that they would normally not be
// possible.
if (!CurrentThreadCanAccessRuntime(thing->runtimeFromAnyThread())) {
AssertSafeToSkipBarrier(thing);
return;
}
#endif
JS::shadow::Zone* shadowZone = thing->shadowZoneFromAnyThread();
if (shadowZone->needsIncrementalBarrier()) {
MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone));

View File

@ -286,6 +286,13 @@ CheckEdgeTracer::onChild(const JS::GCCellPtr& thing)
}
}
void
js::gc::AssertSafeToSkipBarrier(TenuredCell* thing)
{
Zone* zone = thing->zoneFromAnyThread();
MOZ_ASSERT(!zone->needsIncrementalBarrier() || zone->isAtomsZone());
}
static void
AssertMarkedOrAllocated(const EdgeValue& edge)
{

View File

@ -0,0 +1,12 @@
if (typeof gczeal != "function" || helperThreadCount() === 0)
quit(0);
var lfGlobal = newGlobal();
gczeal(4);
for (lfLocal in this) {}
lfGlobal.offThreadCompileScript(`
var desc = {
value: 'bar',
value: false,
};
`);