Bug 650161 - Fix shell test failures caused by compacting GC r=terrence

This commit is contained in:
Jon Coppeard 2014-09-17 15:35:11 +01:00
parent 1c33bd3c21
commit af91929263
9 changed files with 35 additions and 12 deletions

View File

@ -138,7 +138,7 @@ CheckHashTablesAfterMovingGC(JSRuntime *rt);
#ifdef JSGC_COMPACTING #ifdef JSGC_COMPACTING
struct MovingTracer : JSTracer { struct MovingTracer : JSTracer {
MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapValues) {} MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapKeysValues) {}
static void Visit(JSTracer *jstrc, void **thingp, JSGCTraceKind kind); static void Visit(JSTracer *jstrc, void **thingp, JSGCTraceKind kind);
static void Sweep(JSTracer *jstrc); static void Sweep(JSTracer *jstrc);

View File

@ -538,6 +538,8 @@ struct ArenaHeader : public JS::shadow::ArenaHeader
inline ArenaHeader *getNextAllocDuringSweep() const; inline ArenaHeader *getNextAllocDuringSweep() const;
inline void setNextAllocDuringSweep(ArenaHeader *aheader); inline void setNextAllocDuringSweep(ArenaHeader *aheader);
inline void unsetAllocDuringSweep(); inline void unsetAllocDuringSweep();
void unmarkAll();
}; };
struct Arena struct Arena

View File

@ -447,6 +447,13 @@ ArenaHeader::checkSynchronizedWithFreeList() const
} }
#endif #endif
void
ArenaHeader::unmarkAll()
{
uintptr_t *word = chunk()->bitmap.arenaBits(this);
memset(word, 0, ArenaBitmapWords * sizeof(uintptr_t));
}
/* static */ void /* static */ void
Arena::staticAsserts() Arena::staticAsserts()
{ {
@ -2483,6 +2490,9 @@ GCRuntime::releaseRelocatedArenas(ArenaHeader *relocatedList)
ArenaHeader *aheader = relocatedList; ArenaHeader *aheader = relocatedList;
relocatedList = relocatedList->next; relocatedList = relocatedList->next;
// Clear the mark bits
aheader->unmarkAll();
// Mark arena as empty // Mark arena as empty
AllocKind thingKind = aheader->getAllocKind(); AllocKind thingKind = aheader->getAllocKind();
size_t thingSize = aheader->getThingSize(); size_t thingSize = aheader->getThingSize();

View File

@ -726,10 +726,8 @@ class ArenaLists
/* The background finalization must have stopped at this point. */ /* The background finalization must have stopped at this point. */
JS_ASSERT(backgroundFinalizeState[i] == BFS_DONE || JS_ASSERT(backgroundFinalizeState[i] == BFS_DONE ||
backgroundFinalizeState[i] == BFS_JUST_FINISHED); backgroundFinalizeState[i] == BFS_JUST_FINISHED);
for (ArenaHeader *aheader = arenaLists[i].head(); aheader; aheader = aheader->next) { for (ArenaHeader *aheader = arenaLists[i].head(); aheader; aheader = aheader->next)
uintptr_t *word = aheader->chunk()->bitmap.arenaBits(aheader); aheader->unmarkAll();
memset(word, 0, ArenaBitmapWords * sizeof(uintptr_t));
}
} }
} }

View File

@ -662,6 +662,12 @@ JSObject::finish(js::FreeOp *fop)
fop->free_(elements); fop->free_(elements);
} }
} }
// It's possible that unreachable shapes may be marked whose listp points
// into this object. In case this happens, null out the shape's pointer here
// so that a moving GC will not try to access the dead object.
if (shape_->listp == &shape_)
shape_->listp = nullptr;
} }
/* static */ inline bool /* static */ inline bool

View File

@ -71,8 +71,12 @@ WeakMapBase::unmarkCompartment(JSCompartment *c)
void void
WeakMapBase::markAll(JSCompartment *c, JSTracer *tracer) WeakMapBase::markAll(JSCompartment *c, JSTracer *tracer)
{ {
for (WeakMapBase *m = c->gcWeakMapList; m; m = m->next) JS_ASSERT(tracer->eagerlyTraceWeakMaps() != DoNotTraceWeakMaps);
m->markIteratively(tracer); for (WeakMapBase *m = c->gcWeakMapList; m; m = m->next) {
m->trace(tracer);
if (m->memberOf)
gc::MarkObject(tracer, &m->memberOf, "memberOf");
}
} }
bool bool

View File

@ -91,7 +91,7 @@ class WeakMapBase {
virtual void finish() = 0; virtual void finish() = 0;
// Object that this weak map is part of, if any. // Object that this weak map is part of, if any.
JSObject *memberOf; HeapPtrObject memberOf;
// Compartment that this weak map is part of. // Compartment that this weak map is part of.
JSCompartment *compartment; JSCompartment *compartment;

View File

@ -772,10 +772,13 @@ RegExpCompartment::sweep(JSRuntime *rt)
bool keep = shared->marked() && !IsStringAboutToBeFinalized(shared->source.unsafeGet()); bool keep = shared->marked() && !IsStringAboutToBeFinalized(shared->source.unsafeGet());
for (size_t i = 0; i < ArrayLength(shared->compilationArray); i++) { for (size_t i = 0; i < ArrayLength(shared->compilationArray); i++) {
RegExpShared::RegExpCompilation &compilation = shared->compilationArray[i]; RegExpShared::RegExpCompilation &compilation = shared->compilationArray[i];
if (keep && compilation.jitCode) if (compilation.jitCode &&
keep = !IsJitCodeAboutToBeFinalized(compilation.jitCode.unsafeGet()); IsJitCodeAboutToBeFinalized(compilation.jitCode.unsafeGet()))
{
keep = false;
}
} }
if (keep) { if (keep || rt->isHeapCompacting()) {
shared->clearMarked(); shared->clearMarked();
} else { } else {
js_delete(shared); js_delete(shared);

View File

@ -199,7 +199,7 @@ class RegExpShared
void trace(JSTracer *trc); void trace(JSTracer *trc);
bool marked() const { return marked_; } bool marked() const { return marked_; }
void clearMarked() { JS_ASSERT(marked_); marked_ = false; } void clearMarked() { marked_ = false; }
size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
}; };