зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1452982 part 4 - Move jit-related fields from ZoneGroup to JitRuntime. r=jonco
This commit is contained in:
Родитель
84ec03bf15
Коммит
1b0f7474cb
|
@ -2539,7 +2539,8 @@ testingFunc_bailAfter(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
cx->zone()->group()->setIonBailAfter(args[0].toInt32());
|
||||
if (auto* jitRuntime = cx->runtime()->jitRuntime())
|
||||
jitRuntime->setIonBailAfter(args[0].toInt32());
|
||||
#endif
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
|
|
@ -19,24 +19,12 @@ ZoneGroup::ZoneGroup(JSRuntime* runtime)
|
|||
: runtime(runtime),
|
||||
helperThreadOwnerContext_(nullptr),
|
||||
zones_(this),
|
||||
helperThreadUse(HelperThreadUse::None),
|
||||
#ifdef DEBUG
|
||||
ionBailAfter_(this, 0),
|
||||
#endif
|
||||
numFinishedBuilders(0),
|
||||
ionLazyLinkListSize_(0)
|
||||
helperThreadUse(HelperThreadUse::None)
|
||||
{}
|
||||
|
||||
ZoneGroup::~ZoneGroup()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(helperThreadUse == HelperThreadUse::None);
|
||||
{
|
||||
AutoLockHelperThreadState lock;
|
||||
MOZ_ASSERT(ionLazyLinkListSize_ == 0);
|
||||
MOZ_ASSERT(ionLazyLinkList().isEmpty());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (this == runtime->gc.systemZoneGroup)
|
||||
runtime->gc.systemZoneGroup = nullptr;
|
||||
|
@ -57,38 +45,6 @@ ZoneGroup::ownedByCurrentHelperThread()
|
|||
return helperThreadOwnerContext_ == TlsContext.get();
|
||||
}
|
||||
|
||||
ZoneGroup::IonBuilderList&
|
||||
ZoneGroup::ionLazyLinkList()
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
|
||||
"Should only be mutated by the active thread.");
|
||||
return ionLazyLinkList_.ref();
|
||||
}
|
||||
|
||||
void
|
||||
ZoneGroup::ionLazyLinkListRemove(jit::IonBuilder* builder)
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
|
||||
"Should only be mutated by the active thread.");
|
||||
MOZ_ASSERT(this == builder->script()->zone()->group());
|
||||
MOZ_ASSERT(ionLazyLinkListSize_ > 0);
|
||||
|
||||
builder->removeFrom(ionLazyLinkList());
|
||||
ionLazyLinkListSize_--;
|
||||
|
||||
MOZ_ASSERT(ionLazyLinkList().isEmpty() == (ionLazyLinkListSize_ == 0));
|
||||
}
|
||||
|
||||
void
|
||||
ZoneGroup::ionLazyLinkListAdd(jit::IonBuilder* builder)
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
|
||||
"Should only be mutated by the active thread.");
|
||||
MOZ_ASSERT(this == builder->script()->zone()->group());
|
||||
ionLazyLinkList().insertFront(builder);
|
||||
ionLazyLinkListSize_++;
|
||||
}
|
||||
|
||||
void
|
||||
ZoneGroup::deleteEmptyZone(Zone* zone)
|
||||
{
|
||||
|
|
|
@ -84,44 +84,6 @@ class ZoneGroup
|
|||
|
||||
// Delete an empty zone after its contents have been merged.
|
||||
void deleteEmptyZone(Zone* zone);
|
||||
|
||||
#ifdef DEBUG
|
||||
private:
|
||||
// The number of possible bailing places encounters before forcefully bailing
|
||||
// in that place. Zero means inactive.
|
||||
ZoneGroupData<uint32_t> ionBailAfter_;
|
||||
|
||||
public:
|
||||
void* addressOfIonBailAfter() { return &ionBailAfter_; }
|
||||
|
||||
// Set after how many bailing places we should forcefully bail.
|
||||
// Zero disables this feature.
|
||||
void setIonBailAfter(uint32_t after) {
|
||||
ionBailAfter_ = after;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Number of Ion compilations which were finished off thread and are
|
||||
// waiting to be lazily linked. This is only set while holding the helper
|
||||
// thread state lock, but may be read from at other times.
|
||||
mozilla::Atomic<size_t> numFinishedBuilders;
|
||||
|
||||
private:
|
||||
/* List of Ion compilation waiting to get linked. */
|
||||
typedef mozilla::LinkedList<js::jit::IonBuilder> IonBuilderList;
|
||||
|
||||
js::HelperThreadLockData<IonBuilderList> ionLazyLinkList_;
|
||||
js::HelperThreadLockData<size_t> ionLazyLinkListSize_;
|
||||
|
||||
public:
|
||||
IonBuilderList& ionLazyLinkList();
|
||||
|
||||
size_t ionLazyLinkListSize() {
|
||||
return ionLazyLinkListSize_;
|
||||
}
|
||||
|
||||
void ionLazyLinkListRemove(js::jit::IonBuilder* builder);
|
||||
void ionLazyLinkListAdd(js::jit::IonBuilder* builder);
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
|
|
@ -167,7 +167,7 @@ CompileZone::isAtomsZone()
|
|||
const void*
|
||||
CompileZone::addressOfIonBailAfter()
|
||||
{
|
||||
return zone()->group()->addressOfIonBailAfter();
|
||||
return zone()->runtimeFromAnyThread()->jitRuntime()->addressOfIonBailAfter();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -213,12 +213,21 @@ JitRuntime::JitRuntime()
|
|||
baselineDebugModeOSRHandler_(nullptr),
|
||||
trampolineCode_(nullptr),
|
||||
functionWrappers_(nullptr),
|
||||
jitcodeGlobalTable_(nullptr)
|
||||
jitcodeGlobalTable_(nullptr),
|
||||
#ifdef DEBUG
|
||||
ionBailAfter_(0),
|
||||
#endif
|
||||
numFinishedBuilders_(0),
|
||||
ionLazyLinkListSize_(0)
|
||||
{
|
||||
}
|
||||
|
||||
JitRuntime::~JitRuntime()
|
||||
{
|
||||
MOZ_ASSERT(numFinishedBuilders_ == 0);
|
||||
MOZ_ASSERT(ionLazyLinkListSize_ == 0);
|
||||
MOZ_ASSERT(ionLazyLinkList_.ref().isEmpty());
|
||||
|
||||
js_delete(functionWrappers_.ref());
|
||||
|
||||
// By this point, the jitcode global table should be empty.
|
||||
|
@ -373,6 +382,38 @@ JitRuntime::debugTrapHandler(JSContext* cx)
|
|||
return debugTrapHandler_;
|
||||
}
|
||||
|
||||
JitRuntime::IonBuilderList&
|
||||
JitRuntime::ionLazyLinkList(JSRuntime* rt)
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt),
|
||||
"Should only be mutated by the active thread.");
|
||||
return ionLazyLinkList_.ref();
|
||||
}
|
||||
|
||||
void
|
||||
JitRuntime::ionLazyLinkListRemove(JSRuntime* rt, jit::IonBuilder* builder)
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt),
|
||||
"Should only be mutated by the active thread.");
|
||||
MOZ_ASSERT(rt == builder->script()->runtimeFromActiveCooperatingThread());
|
||||
MOZ_ASSERT(ionLazyLinkListSize_ > 0);
|
||||
|
||||
builder->removeFrom(ionLazyLinkList(rt));
|
||||
ionLazyLinkListSize_--;
|
||||
|
||||
MOZ_ASSERT(ionLazyLinkList(rt).isEmpty() == (ionLazyLinkListSize_ == 0));
|
||||
}
|
||||
|
||||
void
|
||||
JitRuntime::ionLazyLinkListAdd(JSRuntime* rt, jit::IonBuilder* builder)
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt),
|
||||
"Should only be mutated by the active thread.");
|
||||
MOZ_ASSERT(rt == builder->script()->runtimeFromActiveCooperatingThread());
|
||||
ionLazyLinkList(rt).insertFront(builder);
|
||||
ionLazyLinkListSize_++;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
JSContext::allocateOsrTempData(size_t size)
|
||||
{
|
||||
|
@ -485,7 +526,7 @@ jit::FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
|
|||
|
||||
// If the builder is still in one of the helper thread list, then remove it.
|
||||
if (builder->isInList())
|
||||
builder->script()->zone()->group()->ionLazyLinkListRemove(builder);
|
||||
runtime->jitRuntime()->ionLazyLinkListRemove(runtime, builder);
|
||||
|
||||
// Clear the recompiling flag of the old ionScript, since we continue to
|
||||
// use the old ionScript if recompiling fails.
|
||||
|
@ -546,7 +587,7 @@ jit::LinkIonScript(JSContext* cx, HandleScript calleeScript)
|
|||
calleeScript->baselineScript()->removePendingIonBuilder(cx->runtime(), calleeScript);
|
||||
|
||||
// Remove from pending.
|
||||
cx->zone()->group()->ionLazyLinkListRemove(builder);
|
||||
cx->runtime()->jitRuntime()->ionLazyLinkListRemove(cx->runtime(), builder);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1896,14 +1937,14 @@ CompileBackEnd(MIRGenerator* mir)
|
|||
|
||||
// Find a builder which the current thread can finish.
|
||||
static IonBuilder*
|
||||
GetFinishedBuilder(ZoneGroup* group, GlobalHelperThreadState::IonBuilderVector& finished)
|
||||
GetFinishedBuilder(JSRuntime* rt, GlobalHelperThreadState::IonBuilderVector& finished,
|
||||
const AutoLockHelperThreadState& locked)
|
||||
{
|
||||
for (size_t i = 0; i < finished.length(); i++) {
|
||||
IonBuilder* testBuilder = finished[i];
|
||||
if (testBuilder->script()->runtimeFromAnyThread() == group->runtime &&
|
||||
testBuilder->script()->zone()->group() == group) {
|
||||
if (testBuilder->script()->runtimeFromAnyThread() == rt) {
|
||||
HelperThreadState().remove(finished, &i);
|
||||
group->numFinishedBuilders--;
|
||||
rt->jitRuntime()->numFinishedBuildersRef(locked)--;
|
||||
return testBuilder;
|
||||
}
|
||||
}
|
||||
|
@ -1912,11 +1953,12 @@ GetFinishedBuilder(ZoneGroup* group, GlobalHelperThreadState::IonBuilderVector&
|
|||
}
|
||||
|
||||
void
|
||||
AttachFinishedCompilations(ZoneGroup* group, JSContext* maybecx)
|
||||
AttachFinishedCompilations(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT_IF(maybecx, maybecx->zone()->group() == group);
|
||||
JSRuntime* rt = cx->runtime();
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
|
||||
|
||||
if (!group->numFinishedBuilders)
|
||||
if (!rt->jitRuntime() || !rt->jitRuntime()->numFinishedBuilders())
|
||||
return;
|
||||
|
||||
AutoLockHelperThreadState lock;
|
||||
|
@ -1926,32 +1968,28 @@ AttachFinishedCompilations(ZoneGroup* group, JSContext* maybecx)
|
|||
// finished, failed or have been cancelled.
|
||||
while (true) {
|
||||
// Find a finished builder for the zone group.
|
||||
IonBuilder* builder = GetFinishedBuilder(group, finished);
|
||||
IonBuilder* builder = GetFinishedBuilder(rt, finished, lock);
|
||||
if (!builder)
|
||||
break;
|
||||
|
||||
JSScript* script = builder->script();
|
||||
MOZ_ASSERT(script->hasBaselineScript());
|
||||
script->baselineScript()->setPendingIonBuilder(group->runtime, script, builder);
|
||||
group->ionLazyLinkListAdd(builder);
|
||||
script->baselineScript()->setPendingIonBuilder(rt, script, builder);
|
||||
rt->jitRuntime()->ionLazyLinkListAdd(rt, builder);
|
||||
|
||||
// Don't keep more than 100 lazy link builders in a zone group.
|
||||
// Link the oldest ones immediately. Only do this if we have a valid
|
||||
// context to use (otherwise this method might have been called in the
|
||||
// middle of a compartment change on the current thread's context).
|
||||
if (maybecx) {
|
||||
while (group->ionLazyLinkListSize() > 100) {
|
||||
jit::IonBuilder* builder = group->ionLazyLinkList().getLast();
|
||||
RootedScript script(maybecx, builder->script());
|
||||
// Link the oldest ones immediately.
|
||||
while (rt->jitRuntime()->ionLazyLinkListSize() > 100) {
|
||||
jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getLast();
|
||||
RootedScript script(cx, builder->script());
|
||||
|
||||
AutoUnlockHelperThreadState unlock(lock);
|
||||
AutoCompartment ac(maybecx, script);
|
||||
jit::LinkIonScript(maybecx, script);
|
||||
}
|
||||
AutoUnlockHelperThreadState unlock(lock);
|
||||
AutoCompartment ac(cx, script);
|
||||
jit::LinkIonScript(cx, script);
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!group->numFinishedBuilders);
|
||||
MOZ_ASSERT(!rt->jitRuntime()->numFinishedBuilders());
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -145,7 +145,7 @@ LIRGraph* GenerateLIR(MIRGenerator* mir);
|
|||
CodeGenerator* GenerateCode(MIRGenerator* mir, LIRGraph* lir);
|
||||
CodeGenerator* CompileBackEnd(MIRGenerator* mir);
|
||||
|
||||
void AttachFinishedCompilations(ZoneGroup* group, JSContext* maybecx);
|
||||
void AttachFinishedCompilations(JSContext* cx);
|
||||
void FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
|
||||
const AutoLockHelperThreadState& lock);
|
||||
void FreeIonBuilder(IonBuilder* builder);
|
||||
|
|
|
@ -135,6 +135,22 @@ class JitRuntime
|
|||
// Global table of jitcode native address => bytecode address mappings.
|
||||
UnprotectedData<JitcodeGlobalTable*> jitcodeGlobalTable_;
|
||||
|
||||
#ifdef DEBUG
|
||||
// The number of possible bailing places encounters before forcefully bailing
|
||||
// in that place. Zero means inactive.
|
||||
ActiveThreadData<uint32_t> ionBailAfter_;
|
||||
#endif
|
||||
|
||||
// Number of Ion compilations which were finished off thread and are
|
||||
// waiting to be lazily linked. This is only set while holding the helper
|
||||
// thread state lock, but may be read from at other times.
|
||||
mozilla::Atomic<size_t> numFinishedBuilders_;
|
||||
|
||||
// List of Ion compilation waiting to get linked.
|
||||
using IonBuilderList = mozilla::LinkedList<js::jit::IonBuilder>;
|
||||
ActiveThreadData<IonBuilderList> ionLazyLinkList_;
|
||||
ActiveThreadData<size_t> ionLazyLinkListSize_;
|
||||
|
||||
private:
|
||||
void generateLazyLinkStub(MacroAssembler& masm);
|
||||
void generateInterpreterStub(MacroAssembler& masm);
|
||||
|
@ -275,6 +291,32 @@ class JitRuntime
|
|||
bool isOptimizationTrackingEnabled(ZoneGroup* group) {
|
||||
return isProfilerInstrumentationEnabled(group->runtime);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void* addressOfIonBailAfter() { return &ionBailAfter_; }
|
||||
|
||||
// Set after how many bailing places we should forcefully bail.
|
||||
// Zero disables this feature.
|
||||
void setIonBailAfter(uint32_t after) {
|
||||
ionBailAfter_ = after;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t numFinishedBuilders() const {
|
||||
return numFinishedBuilders_;
|
||||
}
|
||||
mozilla::Atomic<size_t>& numFinishedBuildersRef(const AutoLockHelperThreadState& locked) {
|
||||
return numFinishedBuilders_;
|
||||
}
|
||||
|
||||
IonBuilderList& ionLazyLinkList(JSRuntime* rt);
|
||||
|
||||
size_t ionLazyLinkListSize() const {
|
||||
return ionLazyLinkListSize_;
|
||||
}
|
||||
|
||||
void ionLazyLinkListRemove(JSRuntime* rt, js::jit::IonBuilder* builder);
|
||||
void ionLazyLinkListAdd(JSRuntime* rt, js::jit::IonBuilder* builder);
|
||||
};
|
||||
|
||||
enum class CacheKind : uint8_t;
|
||||
|
|
|
@ -209,7 +209,7 @@ FinishOffThreadIonCompile(jit::IonBuilder* builder, const AutoLockHelperThreadSt
|
|||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
if (!HelperThreadState().ionFinishedList(lock).append(builder))
|
||||
oomUnsafe.crash("FinishOffThreadIonCompile");
|
||||
builder->script()->zoneFromAnyThread()->group()->numFinishedBuilders++;
|
||||
builder->script()->runtimeFromAnyThread()->jitRuntime()->numFinishedBuildersRef(lock)++;
|
||||
}
|
||||
|
||||
static JSRuntime*
|
||||
|
@ -309,8 +309,9 @@ CancelOffThreadIonCompileLocked(const CompilationSelector& selector, bool discar
|
|||
for (size_t i = 0; i < finished.length(); i++) {
|
||||
jit::IonBuilder* builder = finished[i];
|
||||
if (IonBuilderMatches(selector, builder)) {
|
||||
builder->script()->zoneFromAnyThread()->group()->numFinishedBuilders--;
|
||||
jit::FinishOffThreadBuilder(builder->script()->runtimeFromAnyThread(), builder, lock);
|
||||
JSRuntime* rt = builder->script()->runtimeFromAnyThread();
|
||||
rt->jitRuntime()->numFinishedBuildersRef(lock)--;
|
||||
jit::FinishOffThreadBuilder(rt, builder, lock);
|
||||
HelperThreadState().remove(finished, &i);
|
||||
}
|
||||
}
|
||||
|
@ -319,14 +320,12 @@ CancelOffThreadIonCompileLocked(const CompilationSelector& selector, bool discar
|
|||
if (discardLazyLinkList) {
|
||||
MOZ_ASSERT(!selector.is<AllCompilations>());
|
||||
JSRuntime* runtime = GetSelectorRuntime(selector);
|
||||
for (ZoneGroupsIter group(runtime); !group.done(); group.next()) {
|
||||
jit::IonBuilder* builder = group->ionLazyLinkList().getFirst();
|
||||
while (builder) {
|
||||
jit::IonBuilder* next = builder->getNext();
|
||||
if (IonBuilderMatches(selector, builder))
|
||||
jit::FinishOffThreadBuilder(runtime, builder, lock);
|
||||
builder = next;
|
||||
}
|
||||
jit::IonBuilder* builder = runtime->jitRuntime()->ionLazyLinkList(runtime).getFirst();
|
||||
while (builder) {
|
||||
jit::IonBuilder* next = builder->getNext();
|
||||
if (IonBuilderMatches(selector, builder))
|
||||
jit::FinishOffThreadBuilder(runtime, builder, lock);
|
||||
builder = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +368,8 @@ js::HasOffThreadIonCompile(JSCompartment* comp)
|
|||
return true;
|
||||
}
|
||||
|
||||
jit::IonBuilder* builder = comp->zone()->group()->ionLazyLinkList().getFirst();
|
||||
JSRuntime* rt = comp->runtimeFromActiveCooperatingThread();
|
||||
jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getFirst();
|
||||
while (builder) {
|
||||
if (builder->script()->compartment() == comp)
|
||||
return true;
|
||||
|
@ -2108,8 +2108,9 @@ GlobalHelperThreadState::trace(JSTracer* trc, gc::AutoTraceSession& session)
|
|||
}
|
||||
}
|
||||
|
||||
for (ZoneGroupsIter group(trc->runtime()); !group.done(); group.next()) {
|
||||
jit::IonBuilder* builder = group->ionLazyLinkList().getFirst();
|
||||
JSRuntime* rt = trc->runtime();
|
||||
if (auto* jitRuntime = rt->jitRuntime()) {
|
||||
jit::IonBuilder* builder = jitRuntime->ionLazyLinkList(rt).getFirst();
|
||||
while (builder) {
|
||||
builder->trace(trc);
|
||||
builder = builder->getNext();
|
||||
|
|
|
@ -434,7 +434,7 @@ InvokeInterruptCallback(JSContext* cx)
|
|||
|
||||
// A worker thread may have requested an interrupt after finishing an Ion
|
||||
// compilation.
|
||||
jit::AttachFinishedCompilations(cx->zone()->group(), cx);
|
||||
jit::AttachFinishedCompilations(cx);
|
||||
|
||||
// Important: Additional callbacks can occur inside the callback handler
|
||||
// if it re-enters the JS engine. The embedding must ensure that the
|
||||
|
|
Загрузка…
Ссылка в новой задаче