Bug 1383467 - Only cancel Ion compilations that use nursery pointers when performing a minor GC, r=jonco.

--HG--
extra : rebase_source : 9032ca56a38b2be96bc2cc5dfb6a0163a54b06c3
This commit is contained in:
Brian Hackett 2017-07-24 07:34:40 -06:00
Родитель b9e645073e
Коммит 4736d3662e
3 изменённых файлов: 30 добавлений и 15 удалений

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

@ -701,10 +701,11 @@ js::Nursery::doCollection(JS::gcreason::Reason reason,
StoreBuffer& sb = runtime()->gc.storeBuffer();
// The MIR graph only contains nursery pointers if cancelIonCompilations()
// is set on the store buffer, in which case we cancel all compilations.
// is set on the store buffer, in which case we cancel all compilations
// of such graphs.
startProfile(ProfileKey::CancelIonCompilations);
if (sb.cancelIonCompilations())
js::CancelOffThreadIonCompile(rt);
js::CancelOffThreadIonCompilesUsingNurseryPointers(rt);
endProfile(ProfileKey::CancelIonCompilations);
startProfile(ProfileKey::TraceValues);

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

@ -148,6 +148,7 @@ GetSelectorRuntime(const CompilationSelector& selector)
JSRuntime* match(ZonesInState zbs) { return zbs.runtime; }
JSRuntime* match(JSRuntime* runtime) { return runtime; }
JSRuntime* match(AllCompilations all) { return nullptr; }
JSRuntime* match(CompilationsUsingNursery cun) { return cun.runtime; }
};
return selector.match(Matcher());
@ -163,29 +164,34 @@ JitDataStructuresExist(const CompilationSelector& selector)
bool match(ZonesInState zbs) { return zbs.runtime->hasJitRuntime(); }
bool match(JSRuntime* runtime) { return runtime->hasJitRuntime(); }
bool match(AllCompilations all) { return true; }
bool match(CompilationsUsingNursery cun) { return cun.runtime->hasJitRuntime(); }
};
return selector.match(Matcher());
}
static bool
CompiledScriptMatches(const CompilationSelector& selector, JSScript* target)
IonBuilderMatches(const CompilationSelector& selector, jit::IonBuilder* builder)
{
struct ScriptMatches
struct BuilderMatches
{
JSScript* target_;
jit::IonBuilder* builder_;
bool match(JSScript* script) { return script == target_; }
bool match(JSCompartment* comp) { return comp == target_->compartment(); }
bool match(JSRuntime* runtime) { return runtime == target_->runtimeFromAnyThread(); }
bool match(JSScript* script) { return script == builder_->script(); }
bool match(JSCompartment* comp) { return comp == builder_->script()->compartment(); }
bool match(JSRuntime* runtime) { return runtime == builder_->script()->runtimeFromAnyThread(); }
bool match(AllCompilations all) { return true; }
bool match(ZonesInState zbs) {
return zbs.runtime == target_->runtimeFromAnyThread() &&
zbs.state == target_->zoneFromAnyThread()->gcState();
return zbs.runtime == builder_->script()->runtimeFromAnyThread() &&
zbs.state == builder_->script()->zoneFromAnyThread()->gcState();
}
bool match(CompilationsUsingNursery cun) {
return cun.runtime == builder_->script()->runtimeFromAnyThread() &&
!builder_->safeForMinorGC();
}
};
return selector.match(ScriptMatches{target});
return selector.match(BuilderMatches{builder});
}
void
@ -203,7 +209,7 @@ js::CancelOffThreadIonCompile(const CompilationSelector& selector, bool discardL
GlobalHelperThreadState::IonBuilderVector& worklist = HelperThreadState().ionWorklist(lock);
for (size_t i = 0; i < worklist.length(); i++) {
jit::IonBuilder* builder = worklist[i];
if (CompiledScriptMatches(selector, builder->script())) {
if (IonBuilderMatches(selector, builder)) {
FinishOffThreadIonCompile(builder, lock);
HelperThreadState().remove(worklist, &i);
}
@ -216,7 +222,7 @@ js::CancelOffThreadIonCompile(const CompilationSelector& selector, bool discardL
bool unpaused = false;
for (auto& helper : *HelperThreadState().threads) {
if (helper.ionBuilder() &&
CompiledScriptMatches(selector, helper.ionBuilder()->script()))
IonBuilderMatches(selector, helper.ionBuilder()))
{
helper.ionBuilder()->cancel();
if (helper.pause) {
@ -236,7 +242,7 @@ js::CancelOffThreadIonCompile(const CompilationSelector& selector, bool discardL
GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock);
for (size_t i = 0; i < finished.length(); i++) {
jit::IonBuilder* builder = finished[i];
if (CompiledScriptMatches(selector, builder->script())) {
if (IonBuilderMatches(selector, builder)) {
builder->script()->zone()->group()->numFinishedBuilders--;
jit::FinishOffThreadBuilder(nullptr, builder, lock);
HelperThreadState().remove(finished, &i);
@ -251,7 +257,7 @@ js::CancelOffThreadIonCompile(const CompilationSelector& selector, bool discardL
jit::IonBuilder* builder = group->ionLazyLinkList().getFirst();
while (builder) {
jit::IonBuilder* next = builder->getNext();
if (CompiledScriptMatches(selector, builder->script()))
if (IonBuilderMatches(selector, builder))
jit::FinishOffThreadBuilder(runtime, builder, lock);
builder = next;
}

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

@ -494,11 +494,13 @@ StartOffThreadIonFree(jit::IonBuilder* builder, const AutoLockHelperThreadState&
struct AllCompilations {};
struct ZonesInState { JSRuntime* runtime; JS::Zone::GCState state; };
struct CompilationsUsingNursery { JSRuntime* runtime; };
using CompilationSelector = mozilla::Variant<JSScript*,
JSCompartment*,
ZonesInState,
JSRuntime*,
CompilationsUsingNursery,
AllCompilations>;
/*
@ -531,6 +533,12 @@ CancelOffThreadIonCompile(JSRuntime* runtime)
CancelOffThreadIonCompile(CompilationSelector(runtime), true);
}
inline void
CancelOffThreadIonCompilesUsingNurseryPointers(JSRuntime* runtime)
{
CancelOffThreadIonCompile(CompilationSelector(CompilationsUsingNursery{runtime}), true);
}
inline void
CancelOffThreadIonCompile()
{