Bug 807535 - Avoid toggling Ion write barrier too often. r=sstangl, a=bajaj

This commit is contained in:
Bill McCloskey 2012-11-01 08:08:21 -07:00
Родитель 0bd68fc015
Коммит 2171886248
3 изменённых файлов: 25 добавлений и 11 удалений

Просмотреть файл

@ -48,6 +48,7 @@ JSCompartment::JSCompartment(JSRuntime *rt)
gcStoreBuffer(&gcNursery),
#endif
needsBarrier_(false),
ionUsingBarriers_(false),
gcScheduled(false),
gcState(NoGC),
gcPreserveCode(false),
@ -131,7 +132,7 @@ JSCompartment::init(JSContext *cx)
}
void
JSCompartment::setNeedsBarrier(bool needs)
JSCompartment::setNeedsBarrier(bool needs, ShouldUpdateIon updateIon)
{
#ifdef JS_METHODJIT
/* ClearAllFrames calls compileBarriers() and needs the old value. */
@ -141,8 +142,10 @@ JSCompartment::setNeedsBarrier(bool needs)
#endif
#ifdef JS_ION
if (needsBarrier_ != needs)
if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
ion::ToggleBarriers(this, needs);
ionUsingBarriers_ = needs;
}
#endif
needsBarrier_ = needs;

Просмотреть файл

@ -155,6 +155,7 @@ struct JSCompartment
private:
bool needsBarrier_;
bool ionUsingBarriers_;
public:
bool needsBarrier() const {
@ -169,7 +170,12 @@ struct JSCompartment
return compileBarriers(needsBarrier());
}
void setNeedsBarrier(bool needs);
enum ShouldUpdateIon {
DontUpdateIon,
UpdateIon
};
void setNeedsBarrier(bool needs, ShouldUpdateIon updateIon);
static size_t OffsetOfNeedsBarrier() {
return offsetof(JSCompartment, needsBarrier_);

Просмотреть файл

@ -4162,7 +4162,7 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason)
AutoCopyFreeListToArenas copy(rt);
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
if (c->isGCMarking()) {
c->setNeedsBarrier(false);
c->setNeedsBarrier(false, JSCompartment::DontUpdateIon);
c->setGCState(JSCompartment::NoGC);
wasMarking = true;
}
@ -4220,10 +4220,15 @@ AutoGCSlice::AutoGCSlice(JSRuntime *rt)
rt->stackSpace.markActiveCompartments();
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
/* Clear this early so we don't do any write barriers during GC. */
/*
* Clear needsBarrier early so we don't do any write barriers during
* GC. We don't need to update the Ion barriers (which is expensive)
* because Ion code doesn't run during GC. If need be, we'll update the
* Ion barriers in ~AutoGCSlice.
*/
if (c->isGCMarking()) {
JS_ASSERT(c->needsBarrier());
c->setNeedsBarrier(false);
c->setNeedsBarrier(false, JSCompartment::DontUpdateIon);
} else {
JS_ASSERT(!c->needsBarrier());
}
@ -4234,11 +4239,11 @@ AutoGCSlice::~AutoGCSlice()
{
for (GCCompartmentsIter c(runtime); !c.done(); c.next()) {
if (c->isGCMarking()) {
c->setNeedsBarrier(true);
c->setNeedsBarrier(true, JSCompartment::UpdateIon);
c->arenas.prepareForIncrementalGC(runtime);
} else {
JS_ASSERT(c->isGCSweeping());
c->setNeedsBarrier(false);
c->setNeedsBarrier(false, JSCompartment::UpdateIon);
}
}
}
@ -4395,7 +4400,7 @@ IncrementalCollectSlice(JSRuntime *rt,
default:
JS_ASSERT(false);
}
}
}
class IncrementalSafety
@ -5351,7 +5356,7 @@ StartVerifyPreBarriers(JSRuntime *rt)
rt->gcMarker.start(rt);
for (CompartmentsIter c(rt); !c.done(); c.next()) {
PurgeJITCaches(c);
c->setNeedsBarrier(true);
c->setNeedsBarrier(true, JSCompartment::UpdateIon);
c->arenas.purge();
}
@ -5434,7 +5439,7 @@ EndVerifyPreBarriers(JSRuntime *rt)
compartmentCreated = true;
PurgeJITCaches(c);
c->setNeedsBarrier(false);
c->setNeedsBarrier(false, JSCompartment::UpdateIon);
}
/*