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 c60aa1033f
commit 7baed2498e
9 changed files with 35 additions and 12 deletions

View File

@ -138,7 +138,7 @@ CheckHashTablesAfterMovingGC(JSRuntime *rt);
#ifdef JSGC_COMPACTING
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 Sweep(JSTracer *jstrc);

View File

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

View File

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

View File

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

View File

@ -662,6 +662,12 @@ JSObject::finish(js::FreeOp *fop)
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

View File

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

View File

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

View File

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

View File

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