mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 731783 - Eliminate per-compartment barrier marker (r=igor)
This commit is contained in:
parent
842ae8ae75
commit
8273a70134
@ -304,7 +304,7 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
* in MaybeGC.
|
||||
*/
|
||||
volatile uint32_t gcNumArenasFreeCommitted;
|
||||
js::FullGCMarker gcMarker;
|
||||
js::GCMarker gcMarker;
|
||||
void *gcVerifyData;
|
||||
bool gcChunkAllocationSinceLastGC;
|
||||
int64_t gcNextFullGCTime;
|
||||
|
@ -73,7 +73,6 @@ JSCompartment::JSCompartment(JSRuntime *rt)
|
||||
: rt(rt),
|
||||
principals(NULL),
|
||||
needsBarrier_(false),
|
||||
barrierMarker_(rt->gcMarker.sizeLimit()),
|
||||
gcBytes(0),
|
||||
gcTriggerBytes(0),
|
||||
gcLastBytes(0),
|
||||
@ -128,9 +127,6 @@ JSCompartment::init(JSContext *cx)
|
||||
if (!scriptFilenameTable.init())
|
||||
return false;
|
||||
|
||||
if (!barrierMarker_.init())
|
||||
return false;
|
||||
|
||||
return debuggees.init();
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,6 @@ struct JSCompartment
|
||||
js::gc::ArenaLists arenas;
|
||||
|
||||
bool needsBarrier_;
|
||||
js::BarrierGCMarker barrierMarker_;
|
||||
|
||||
bool needsBarrier() {
|
||||
return needsBarrier_;
|
||||
@ -201,7 +200,7 @@ struct JSCompartment
|
||||
|
||||
js::GCMarker *barrierTracer() {
|
||||
JS_ASSERT(needsBarrier_);
|
||||
return &barrierMarker_;
|
||||
return &rt->gcMarker;
|
||||
}
|
||||
|
||||
size_t gcBytes;
|
||||
|
@ -70,11 +70,6 @@
|
||||
* barriers. However, they must be marked in the first slice. Roots are things
|
||||
* like the C stack and the VM stack, since it would be too expensive to put
|
||||
* barriers on them.
|
||||
*
|
||||
* Write barriers are handled using the compartment's barrierMarker_
|
||||
* JSTracer. This includes a per-compartment stack of GC things that have been
|
||||
* write-barriered. This stack is processed in each GC slice. The barrierMarker_
|
||||
* is also used during write barrier verification (VerifyBarriers below).
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
@ -1450,14 +1445,14 @@ namespace js {
|
||||
namespace gc {
|
||||
|
||||
inline void
|
||||
ArenaLists::prepareForIncrementalGC(JSCompartment *comp)
|
||||
ArenaLists::prepareForIncrementalGC(JSRuntime *rt)
|
||||
{
|
||||
for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
|
||||
FreeSpan *headSpan = &freeLists[i];
|
||||
if (!headSpan->isEmpty()) {
|
||||
ArenaHeader *aheader = headSpan->arenaHeader();
|
||||
aheader->allocatedDuringIncremental = true;
|
||||
comp->barrierMarker_.delayMarkingArena(aheader);
|
||||
rt->gcMarker.delayMarkingArena(aheader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1517,7 +1512,7 @@ ArenaLists::allocateFromArena(JSCompartment *comp, AllocKind thingKind)
|
||||
aheader->setAsFullyUsed();
|
||||
if (JS_UNLIKELY(comp->needsBarrier())) {
|
||||
aheader->allocatedDuringIncremental = true;
|
||||
comp->barrierMarker_.delayMarkingArena(aheader);
|
||||
comp->rt->gcMarker.delayMarkingArena(aheader);
|
||||
}
|
||||
return freeLists[thingKind].infallibleAllocate(Arena::thingSize(thingKind));
|
||||
}
|
||||
@ -1546,7 +1541,7 @@ ArenaLists::allocateFromArena(JSCompartment *comp, AllocKind thingKind)
|
||||
|
||||
if (JS_UNLIKELY(comp->needsBarrier())) {
|
||||
aheader->allocatedDuringIncremental = true;
|
||||
comp->barrierMarker_.delayMarkingArena(aheader);
|
||||
comp->rt->gcMarker.delayMarkingArena(aheader);
|
||||
}
|
||||
aheader->next = al->head;
|
||||
if (!al->head) {
|
||||
@ -1874,8 +1869,8 @@ SliceBudget::checkOverBudget()
|
||||
return over;
|
||||
}
|
||||
|
||||
GCMarker::GCMarker(size_t sizeLimit)
|
||||
: stack(sizeLimit),
|
||||
GCMarker::GCMarker()
|
||||
: stack(size_t(-1)),
|
||||
color(BLACK),
|
||||
started(false),
|
||||
unmarkedArenaStackTop(NULL),
|
||||
@ -1885,11 +1880,9 @@ GCMarker::GCMarker(size_t sizeLimit)
|
||||
}
|
||||
|
||||
bool
|
||||
GCMarker::init(bool lazy)
|
||||
GCMarker::init()
|
||||
{
|
||||
if (!stack.init(lazy ? 0 : MARK_STACK_LENGTH))
|
||||
return false;
|
||||
return true;
|
||||
return stack.init(MARK_STACK_LENGTH);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1926,6 +1919,10 @@ GCMarker::stop()
|
||||
|
||||
JS_ASSERT(grayRoots.empty());
|
||||
grayFailed = false;
|
||||
|
||||
/* Free non-ballast stack memory. */
|
||||
stack.reset();
|
||||
grayRoots.clearAndFree();
|
||||
}
|
||||
|
||||
void
|
||||
@ -2129,8 +2126,6 @@ SetMarkStackLimit(JSRuntime *rt, size_t limit)
|
||||
{
|
||||
JS_ASSERT(!rt->gcRunning);
|
||||
rt->gcMarker.setSizeLimit(limit);
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next())
|
||||
c->barrierMarker_.setSizeLimit(limit);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
@ -3012,7 +3007,7 @@ MarkWeakReferences(GCMarker *gcmarker)
|
||||
static void
|
||||
MarkGrayAndWeak(JSRuntime *rt)
|
||||
{
|
||||
FullGCMarker *gcmarker = &rt->gcMarker;
|
||||
GCMarker *gcmarker = &rt->gcMarker;
|
||||
|
||||
JS_ASSERT(gcmarker->isDrained());
|
||||
MarkWeakReferences(gcmarker);
|
||||
@ -3074,7 +3069,7 @@ ValidateIncrementalMarking(JSContext *cx)
|
||||
return;
|
||||
|
||||
JSRuntime *rt = cx->runtime;
|
||||
FullGCMarker *gcmarker = &rt->gcMarker;
|
||||
GCMarker *gcmarker = &rt->gcMarker;
|
||||
|
||||
/* Save existing mark bits. */
|
||||
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
|
||||
@ -3375,11 +3370,9 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason)
|
||||
return;
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (!rt->gcIncrementalCompartment || rt->gcIncrementalCompartment == c) {
|
||||
if (!rt->gcIncrementalCompartment || rt->gcIncrementalCompartment == c)
|
||||
c->needsBarrier_ = false;
|
||||
c->barrierMarker_.reset();
|
||||
c->barrierMarker_.stop();
|
||||
}
|
||||
|
||||
JS_ASSERT(!c->needsBarrier_);
|
||||
}
|
||||
|
||||
@ -3429,7 +3422,7 @@ AutoGCSlice::~AutoGCSlice()
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (rt->gcIncrementalState == MARK) {
|
||||
c->needsBarrier_ = true;
|
||||
c->arenas.prepareForIncrementalGC(c);
|
||||
c->arenas.prepareForIncrementalGC(rt);
|
||||
} else {
|
||||
JS_ASSERT(rt->gcIncrementalState == NO_INCREMENTAL);
|
||||
|
||||
@ -3475,10 +3468,8 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind)
|
||||
rt->gcMarker.start(rt);
|
||||
JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker));
|
||||
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next())
|
||||
c->discardJitCode(cx);
|
||||
c->barrierMarker_.start(rt);
|
||||
}
|
||||
|
||||
BeginMarkPhase(rt);
|
||||
|
||||
@ -3495,15 +3486,8 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind)
|
||||
|
||||
bool finished = rt->gcMarker.drainMarkStack(sliceBudget);
|
||||
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next())
|
||||
finished &= c->barrierMarker_.drainMarkStack(sliceBudget);
|
||||
|
||||
if (finished) {
|
||||
JS_ASSERT(rt->gcMarker.isDrained());
|
||||
#ifdef DEBUG
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next())
|
||||
JS_ASSERT(c->barrierMarker_.isDrained());
|
||||
#endif
|
||||
if (initialState == MARK && !rt->gcLastMarkSlice)
|
||||
rt->gcLastMarkSlice = true;
|
||||
else
|
||||
@ -3518,8 +3502,6 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind)
|
||||
rt->gcMarker.stop();
|
||||
|
||||
/* JIT code was already discarded during sweeping. */
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next())
|
||||
c->barrierMarker_.stop();
|
||||
|
||||
rt->gcIncrementalCompartment = NULL;
|
||||
|
||||
@ -3938,17 +3920,9 @@ NewCompartment(JSContext *cx, JSPrincipals *principals)
|
||||
* it. Otherwise we might fail the mark the newly created
|
||||
* compartment fully.
|
||||
*/
|
||||
if (rt->gcIncrementalState == MARK) {
|
||||
if (rt->gcIncrementalState == MARK)
|
||||
rt->gcCompartmentCreated = true;
|
||||
|
||||
/*
|
||||
* Start the tracer so that it's legal to stop() it when
|
||||
* resetting the GC.
|
||||
*/
|
||||
if (!rt->gcIncrementalCompartment)
|
||||
compartment->barrierMarker_.start(rt);
|
||||
}
|
||||
|
||||
if (rt->compartments.append(compartment))
|
||||
return compartment;
|
||||
}
|
||||
@ -4261,10 +4235,10 @@ StartVerifyBarriers(JSContext *cx)
|
||||
|
||||
rt->gcVerifyData = trc;
|
||||
rt->gcIncrementalState = MARK;
|
||||
rt->gcMarker.start(rt);
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->needsBarrier_ = true;
|
||||
c->barrierMarker_.start(rt);
|
||||
c->arenas.prepareForIncrementalGC(c);
|
||||
c->arenas.prepareForIncrementalGC(rt);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -4400,10 +4374,8 @@ EndVerifyBarriers(JSContext *cx)
|
||||
}
|
||||
}
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->barrierMarker_.reset();
|
||||
c->barrierMarker_.stop();
|
||||
}
|
||||
rt->gcMarker.reset();
|
||||
rt->gcMarker.stop();
|
||||
|
||||
trc->~VerifyTracer();
|
||||
js_free(trc);
|
||||
|
@ -1175,7 +1175,7 @@ struct ArenaLists {
|
||||
}
|
||||
}
|
||||
|
||||
inline void prepareForIncrementalGC(JSCompartment *comp);
|
||||
inline void prepareForIncrementalGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Temporarily copy the free list heads to the arenas so the code can see
|
||||
@ -1766,8 +1766,8 @@ struct GCMarker : public JSTracer {
|
||||
}
|
||||
|
||||
public:
|
||||
explicit GCMarker(size_t sizeLimit);
|
||||
bool init(bool lazy);
|
||||
explicit GCMarker();
|
||||
bool init();
|
||||
|
||||
void setSizeLimit(size_t size) { stack.setSizeLimit(size); }
|
||||
size_t sizeLimit() const { return stack.sizeLimit; }
|
||||
@ -1910,22 +1910,6 @@ struct GCMarker : public JSTracer {
|
||||
Vector<GrayRoot, 0, SystemAllocPolicy> grayRoots;
|
||||
};
|
||||
|
||||
struct BarrierGCMarker : public GCMarker {
|
||||
BarrierGCMarker(size_t sizeLimit) : GCMarker(sizeLimit) {}
|
||||
|
||||
bool init() {
|
||||
return GCMarker::init(true);
|
||||
}
|
||||
};
|
||||
|
||||
struct FullGCMarker : public GCMarker {
|
||||
FullGCMarker() : GCMarker(size_t(-1)) {}
|
||||
|
||||
bool init() {
|
||||
return GCMarker::init(false);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
SetMarkStackLimit(JSRuntime *rt, size_t limit);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user