Bug 1452406 - Support calling RecompileInfo::shouldSweep under CodeGenerator::link instead of asserting. r=tcampbell

This commit is contained in:
Jan de Mooij 2018-04-09 19:36:41 +02:00
Родитель 78177eb809
Коммит 2fa8f7862f
6 изменённых файлов: 37 добавлений и 27 удалений

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

@ -10237,14 +10237,11 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints)
// will trickle to jit::Compile() and return Method_Skipped. // will trickle to jit::Compile() and return Method_Skipped.
uint32_t warmUpCount = script->getWarmUpCount(); uint32_t warmUpCount = script->getWarmUpCount();
JitRuntime* jrt = cx->runtime()->jitRuntime(); IonCompilationId compilationId = cx->runtime()->jitRuntime()->nextCompilationId();
IonCompilationId compilationId = jrt->nextCompilationId(); cx->zone()->types.currentCompilationIdRef().emplace(compilationId);
#ifdef DEBUG auto resetCurrentId = mozilla::MakeScopeExit([cx] {
jrt->currentCompilationId().emplace(compilationId); cx->zone()->types.currentCompilationIdRef().reset();
auto resetCurrentId = mozilla::MakeScopeExit([jrt] {
jrt->currentCompilationId().reset();
}); });
#endif
// Record constraints. If an error occured, returns false and potentially // Record constraints. If an error occured, returns false and potentially
// prevent future compilations. Otherwise, if an invalidation occured, then // prevent future compilations. Otherwise, if an invalidation occured, then

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

@ -2870,7 +2870,7 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
if (cancelOffThread) if (cancelOffThread)
CancelOffThreadIonCompile(info.script()); CancelOffThreadIonCompile(info.script());
IonScript* ionScript = info.maybeIonScriptToInvalidate(); IonScript* ionScript = info.maybeIonScriptToInvalidate(types);
if (!ionScript) if (!ionScript)
continue; continue;
@ -2897,7 +2897,7 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
// IonScript will be immediately destroyed. Otherwise, it will be held live // IonScript will be immediately destroyed. Otherwise, it will be held live
// until its last invalidated frame is destroyed. // until its last invalidated frame is destroyed.
for (const RecompileInfo& info : invalid) { for (const RecompileInfo& info : invalid) {
IonScript* ionScript = info.maybeIonScriptToInvalidate(); IonScript* ionScript = info.maybeIonScriptToInvalidate(types);
if (!ionScript) if (!ionScript)
continue; continue;
@ -2919,7 +2919,7 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
// Finally, null out script->ion for IonScripts that are still on the stack. // Finally, null out script->ion for IonScripts that are still on the stack.
for (const RecompileInfo& info : invalid) { for (const RecompileInfo& info : invalid) {
if (info.maybeIonScriptToInvalidate()) if (info.maybeIonScriptToInvalidate(types))
ClearIonScriptAfterInvalidation(cx, info.script(), resetUses); ClearIonScriptAfterInvalidation(cx, info.script(), resetUses);
} }
} }

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

@ -65,9 +65,6 @@ class JitRuntime
ActiveThreadData<ExecutableAllocator> execAlloc_; ActiveThreadData<ExecutableAllocator> execAlloc_;
ActiveThreadData<uint64_t> nextCompilationId_; ActiveThreadData<uint64_t> nextCompilationId_;
#ifdef DEBUG
ActiveThreadData<mozilla::Maybe<IonCompilationId>> currentCompilationId_;
#endif
// Shared exception-handler tail. // Shared exception-handler tail.
ExclusiveAccessLockWriteOnceData<uint32_t> exceptionTailOffset_; ExclusiveAccessLockWriteOnceData<uint32_t> exceptionTailOffset_;
@ -190,11 +187,6 @@ class JitRuntime
IonCompilationId nextCompilationId() { IonCompilationId nextCompilationId() {
return IonCompilationId(nextCompilationId_++); return IonCompilationId(nextCompilationId_++);
} }
#ifdef DEBUG
mozilla::Maybe<IonCompilationId>& currentCompilationId() {
return currentCompilationId_.ref();
}
#endif
TrampolinePtr getVMWrapper(const VMFunction& f) const; TrampolinePtr getVMWrapper(const VMFunction& f) const;
JitCode* debugTrapHandler(JSContext* cx); JitCode* debugTrapHandler(JSContext* cx);

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

@ -36,11 +36,13 @@ namespace js {
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
jit::IonScript* jit::IonScript*
RecompileInfo::maybeIonScriptToInvalidate() const RecompileInfo::maybeIonScriptToInvalidate(const TypeZone& zone) const
{ {
MOZ_ASSERT(script_->zone() == zone.zone());
// Make sure this is not called under CodeGenerator::link (before the // Make sure this is not called under CodeGenerator::link (before the
// IonScript is created). // IonScript is created).
MOZ_ASSERT(!TlsContext.get()->runtime()->jitRuntime()->currentCompilationId().isSome()); MOZ_ASSERT_IF(zone.currentCompilationId(), zone.currentCompilationId().ref() != id_);
if (!script_->hasIonScript() || script_->ionScript()->compilationId() != id_) if (!script_->hasIonScript() || script_->ionScript()->compilationId() != id_)
return nullptr; return nullptr;
@ -49,11 +51,19 @@ RecompileInfo::maybeIonScriptToInvalidate() const
} }
inline bool inline bool
RecompileInfo::shouldSweep() RecompileInfo::shouldSweep(const TypeZone& zone)
{ {
if (IsAboutToBeFinalizedUnbarriered(&script_)) if (IsAboutToBeFinalizedUnbarriered(&script_))
return true; return true;
return maybeIonScriptToInvalidate() == nullptr;
MOZ_ASSERT(script_->zone() == zone.zone());
// Don't sweep if we're called under CodeGenerator::link, before the
// IonScript is created.
if (zone.currentCompilationId() && zone.currentCompilationId().ref() == id_)
return false;
return maybeIonScriptToInvalidate(zone) == nullptr;
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

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

@ -1213,7 +1213,7 @@ class TypeCompilerConstraint : public TypeConstraint
} }
bool sweep(TypeZone& zone, TypeConstraint** res) override { bool sweep(TypeZone& zone, TypeConstraint** res) override {
if (data.shouldSweep() || compilation.shouldSweep()) if (data.shouldSweep() || compilation.shouldSweep(zone))
return false; return false;
*res = zone.typeLifoAlloc().new_<TypeCompilerConstraint<T> >(compilation, data); *res = zone.typeLifoAlloc().new_<TypeCompilerConstraint<T> >(compilation, data);
return true; return true;
@ -1422,7 +1422,7 @@ bool
js::FinishCompilation(JSContext* cx, HandleScript script, CompilerConstraintList* constraints, js::FinishCompilation(JSContext* cx, HandleScript script, CompilerConstraintList* constraints,
IonCompilationId compilationId, bool* isValidOut) IonCompilationId compilationId, bool* isValidOut)
{ {
MOZ_ASSERT(*cx->runtime()->jitRuntime()->currentCompilationId() == compilationId); MOZ_ASSERT(*cx->zone()->types.currentCompilationId() == compilationId);
if (constraints->failed()) if (constraints->failed())
return false; return false;
@ -4415,7 +4415,7 @@ JSScript::maybeSweepTypes(AutoClearTypeInferenceStateOnOOM* oom)
RecompileInfoVector& inlinedCompilations = types_->inlinedCompilations(); RecompileInfoVector& inlinedCompilations = types_->inlinedCompilations();
size_t dest = 0; size_t dest = 0;
for (size_t i = 0; i < inlinedCompilations.length(); i++) { for (size_t i = 0; i < inlinedCompilations.length(); i++) {
if (inlinedCompilations[i].shouldSweep()) if (inlinedCompilations[i].shouldSweep(types))
continue; continue;
inlinedCompilations[dest] = inlinedCompilations[i]; inlinedCompilations[dest] = inlinedCompilations[i];
dest++; dest++;
@ -4485,6 +4485,7 @@ Zone::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
TypeZone::TypeZone(Zone* zone) TypeZone::TypeZone(Zone* zone)
: zone_(zone), : zone_(zone),
typeLifoAlloc_(zone->group(), (size_t) TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), typeLifoAlloc_(zone->group(), (size_t) TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
currentCompilationId_(zone->group()),
generation(zone->group(), 0), generation(zone->group(), 0),
sweepTypeLifoAlloc(zone->group(), (size_t) TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), sweepTypeLifoAlloc(zone->group(), (size_t) TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
sweepReleaseTypes(zone->group(), false), sweepReleaseTypes(zone->group(), false),

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

@ -1139,9 +1139,9 @@ class RecompileInfo
return script_; return script_;
} }
inline jit::IonScript* maybeIonScriptToInvalidate() const; inline jit::IonScript* maybeIonScriptToInvalidate(const TypeZone& zone) const;
inline bool shouldSweep(); inline bool shouldSweep(const TypeZone& zone);
bool operator==(const RecompileInfo& other) const { bool operator==(const RecompileInfo& other) const {
return script_== other.script_ && id_ == other.id_; return script_== other.script_ && id_ == other.id_;
@ -1340,6 +1340,9 @@ class TypeZone
static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 8 * 1024; static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 8 * 1024;
ZoneGroupData<LifoAlloc> typeLifoAlloc_; ZoneGroupData<LifoAlloc> typeLifoAlloc_;
// Under CodeGenerator::link, the id of the current compilation.
ZoneGroupData<mozilla::Maybe<IonCompilationId>> currentCompilationId_;
TypeZone(const TypeZone&) = delete; TypeZone(const TypeZone&) = delete;
void operator=(const TypeZone&) = delete; void operator=(const TypeZone&) = delete;
@ -1388,6 +1391,13 @@ class TypeZone
MOZ_RELEASE_ASSERT(sweepingTypes != sweeping); MOZ_RELEASE_ASSERT(sweepingTypes != sweeping);
sweepingTypes = sweeping; sweepingTypes = sweeping;
} }
mozilla::Maybe<IonCompilationId> currentCompilationId() const {
return currentCompilationId_.ref();
}
mozilla::Maybe<IonCompilationId>& currentCompilationIdRef() {
return currentCompilationId_.ref();
}
}; };
enum SpewChannel { enum SpewChannel {