зеркало из https://github.com/mozilla/gecko-dev.git
Bug 807535 - Avoid toggling Ion write barrier too often. r=sstangl, a=bajaj
This commit is contained in:
Родитель
0bd68fc015
Коммит
2171886248
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче