mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 17:31:47 +09:00
Revert "(not to be confused with Basilisk-Dev's implementation) Backport Bugzilla 1379814 and 1431353."
This reverts commit b0cad39d1a.
This commit is contained in:
parent
b0cad39d1a
commit
01553c6695
3 changed files with 128 additions and 283 deletions
|
|
@ -16,7 +16,6 @@
|
|||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/SizePrintfMacros.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
|
@ -174,213 +173,90 @@ enum class ScriptKind
|
|||
Module
|
||||
};
|
||||
|
||||
mozilla::Atomic<int32_t> gOffThreadJobSerial(1);
|
||||
|
||||
class OffThreadJob;
|
||||
|
||||
class OffThreadState {
|
||||
enum State {
|
||||
RUNNING,
|
||||
DONE,
|
||||
IDLE, /* ready to work; no token, no source */
|
||||
COMPILING, /* working; no token, have source */
|
||||
DONE /* compilation done: have token and source */
|
||||
};
|
||||
|
||||
public:
|
||||
OffThreadState()
|
||||
: monitor(mutexid::ShellOffThreadState)
|
||||
{}
|
||||
: monitor(mutexid::ShellOffThreadState),
|
||||
state(IDLE),
|
||||
token(),
|
||||
source(nullptr)
|
||||
{ }
|
||||
|
||||
~OffThreadState()
|
||||
bool startIfIdle(JSContext* cx, ScriptKind kind,
|
||||
ScopedJSFreePtr<char16_t>& newSource)
|
||||
{
|
||||
MOZ_ASSERT(jobs.empty());
|
||||
AutoLockMonitor alm(monitor);
|
||||
if (state != IDLE)
|
||||
return false;
|
||||
|
||||
MOZ_ASSERT(!token);
|
||||
|
||||
source = newSource.forget();
|
||||
|
||||
scriptKind = kind;
|
||||
state = COMPILING;
|
||||
return true;
|
||||
}
|
||||
|
||||
using Source = JS::UniqueTwoByteChars;
|
||||
void abandon(JSContext* cx) {
|
||||
AutoLockMonitor alm(monitor);
|
||||
MOZ_ASSERT(state == COMPILING);
|
||||
MOZ_ASSERT(!token);
|
||||
MOZ_ASSERT(source);
|
||||
|
||||
OffThreadJob* newJob(JSContext* cx, ScriptKind kind, Source&& source);
|
||||
OffThreadJob* getSingleJob(JSContext* cx, ScriptKind kind);
|
||||
OffThreadJob* lookupJobByID(JSContext* cx, ScriptKind kind, int32_t id);
|
||||
OffThreadJob* lookupJobForArgs(JSContext* cx, ScriptKind kind, const CallArgs& args,
|
||||
size_t arg);
|
||||
void deleteJob(JSContext* cx, OffThreadJob* job);
|
||||
void cancelAll(JSContext* cx);
|
||||
js_free(source);
|
||||
source = nullptr;
|
||||
|
||||
|
||||
private:
|
||||
friend class OffThreadJob;
|
||||
|
||||
Monitor monitor;
|
||||
Vector<OffThreadJob*, 0, SystemAllocPolicy> jobs;
|
||||
};
|
||||
|
||||
class OffThreadJob {
|
||||
public:
|
||||
using Source = OffThreadState::Source;
|
||||
|
||||
OffThreadJob(Monitor& monitor, ScriptKind kind, Source&& source)
|
||||
: id(gOffThreadJobSerial++),
|
||||
kind(kind),
|
||||
monitor(monitor),
|
||||
state(RUNNING),
|
||||
token(nullptr),
|
||||
source(Move(source))
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(id > 0, "Off-thread job IDs exhausted");
|
||||
}
|
||||
|
||||
~OffThreadJob() {
|
||||
MOZ_ASSERT(state != RUNNING);
|
||||
state = IDLE;
|
||||
}
|
||||
|
||||
void markDone(void* newToken) {
|
||||
AutoLockMonitor alm(monitor);
|
||||
MOZ_ASSERT(state == RUNNING);
|
||||
MOZ_ASSERT(state == COMPILING);
|
||||
MOZ_ASSERT(!token);
|
||||
MOZ_ASSERT(source);
|
||||
MOZ_ASSERT(newToken);
|
||||
|
||||
token = newToken;
|
||||
state = DONE;
|
||||
alm.notifyAll();
|
||||
alm.notify();
|
||||
}
|
||||
|
||||
void* waitUntilDone(JSContext* cx) {
|
||||
void* waitUntilDone(JSContext* cx, ScriptKind kind) {
|
||||
AutoLockMonitor alm(monitor);
|
||||
MOZ_ASSERT(state != RUNNING || token == nullptr);
|
||||
if (state == IDLE || scriptKind != kind)
|
||||
return nullptr;
|
||||
|
||||
while (state != DONE)
|
||||
alm.wait();
|
||||
if (state == COMPILING) {
|
||||
while (state != DONE)
|
||||
alm.wait();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(source);
|
||||
js_free(source);
|
||||
source = nullptr;
|
||||
|
||||
MOZ_ASSERT(token);
|
||||
return token;
|
||||
void* holdToken = token;
|
||||
token = nullptr;
|
||||
state = IDLE;
|
||||
return holdToken;
|
||||
}
|
||||
|
||||
const char16_t* sourceChars() const {
|
||||
return source.get();
|
||||
}
|
||||
|
||||
const int32_t id;
|
||||
const ScriptKind kind;
|
||||
|
||||
private:
|
||||
Monitor& monitor;
|
||||
Monitor monitor;
|
||||
ScriptKind scriptKind;
|
||||
State state;
|
||||
void* token;
|
||||
Source source;
|
||||
char16_t* source;
|
||||
};
|
||||
|
||||
OffThreadJob*
|
||||
OffThreadState::newJob(JSContext* cx, ScriptKind kind, Source&& source)
|
||||
{
|
||||
UniquePtr<OffThreadJob> job(cx->new_<OffThreadJob>(monitor, kind, Move(source)));
|
||||
if (!job)
|
||||
return nullptr;
|
||||
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
if (!jobs.append(job.get())) {
|
||||
JS_ReportErrorASCII(cx, "OOM adding off-thread job");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return job.release();
|
||||
}
|
||||
|
||||
OffThreadJob*
|
||||
OffThreadState::getSingleJob(JSContext* cx, ScriptKind kind)
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
if (jobs.empty()) {
|
||||
JS_ReportErrorASCII(cx, "No off-thread jobs are pending");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (jobs.length() > 1) {
|
||||
JS_ReportErrorASCII(cx, "Multiple off-thread jobs are pending: must specify job ID");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OffThreadJob* job = jobs[0];
|
||||
if (job->kind != kind) {
|
||||
JS_ReportErrorASCII(cx, "Off-thread job is the wrong kind");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
OffThreadJob*
|
||||
OffThreadState::lookupJobByID(JSContext* cx, ScriptKind kind, int32_t id)
|
||||
{
|
||||
if (id <= 0) {
|
||||
JS_ReportErrorASCII(cx, "Bad off-thread job ID");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoLockMonitor alm(monitor);
|
||||
if (jobs.empty()) {
|
||||
JS_ReportErrorASCII(cx, "No off-thread jobs are pending");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OffThreadJob* job = nullptr;
|
||||
for (auto someJob : jobs) {
|
||||
if (someJob->id == id) {
|
||||
job = someJob;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!job) {
|
||||
JS_ReportErrorASCII(cx, "Off-thread job not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (job->kind != kind) {
|
||||
JS_ReportErrorASCII(cx, "Off-thread job is the wrong kind");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
OffThreadJob*
|
||||
OffThreadState::lookupJobForArgs(JSContext* cx, ScriptKind kind, const CallArgs& args,
|
||||
size_t arg)
|
||||
{
|
||||
if (args.length() <= arg)
|
||||
return getSingleJob(cx, kind);
|
||||
|
||||
int32_t id = 0;
|
||||
RootedValue value(cx, args[arg]);
|
||||
if (!ToInt32(cx, value, &id))
|
||||
return nullptr;
|
||||
|
||||
return lookupJobByID(cx, kind, id);
|
||||
}
|
||||
|
||||
void
|
||||
OffThreadState::deleteJob(JSContext* cx, OffThreadJob* job)
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
for (size_t i = 0; i < jobs.length(); i++) {
|
||||
if (jobs[i] == job) {
|
||||
jobs.erase(&jobs[i]);
|
||||
js_delete(job);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_CRASH("Off-thread job not found");
|
||||
}
|
||||
|
||||
void
|
||||
OffThreadState::cancelAll(JSContext* cx)
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
while (!jobs.empty())
|
||||
js_delete(jobs.popCopy());
|
||||
}
|
||||
|
||||
// Per-context shell state.
|
||||
struct ShellContext
|
||||
{
|
||||
|
|
@ -3561,8 +3437,6 @@ WorkerMain(void* arg)
|
|||
JS::SetEnqueuePromiseJobCallback(cx, nullptr);
|
||||
sc->jobQueue.reset();
|
||||
|
||||
sc->offThreadState.cancelAll(cx);
|
||||
|
||||
KillWatchdog(cx);
|
||||
|
||||
JS_DestroyContext(cx);
|
||||
|
|
@ -4550,8 +4424,8 @@ SyntaxParse(JSContext* cx, unsigned argc, Value* vp)
|
|||
static void
|
||||
OffThreadCompileScriptCallback(void* token, void* callbackData)
|
||||
{
|
||||
auto job = static_cast<OffThreadJob*>(callbackData);
|
||||
job->markDone(token);
|
||||
ShellContext* sc = static_cast<ShellContext*>(callbackData);
|
||||
sc->offThreadState.markDone(token);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -4610,16 +4484,17 @@ OffThreadCompileScript(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
// Make sure we own the string's chars, so that they are not freed before
|
||||
// the compilation is finished.
|
||||
JS::UniqueTwoByteChars ownedChars;
|
||||
ScopedJSFreePtr<char16_t> ownedChars;
|
||||
if (stableChars.maybeGiveOwnershipToCaller()) {
|
||||
ownedChars.reset(const_cast<char16_t*>(chars));
|
||||
ownedChars = const_cast<char16_t*>(chars);
|
||||
} else {
|
||||
ownedChars.reset(cx->pod_malloc<char16_t>(length));
|
||||
if (!ownedChars)
|
||||
char16_t* copy = cx->pod_malloc<char16_t>(length);
|
||||
if (!copy)
|
||||
return false;
|
||||
|
||||
mozilla::PodCopy(ownedChars.get(), chars, length);
|
||||
chars = ownedChars.get();
|
||||
mozilla::PodCopy(copy, chars, length);
|
||||
ownedChars = copy;
|
||||
chars = copy;
|
||||
}
|
||||
|
||||
if (!JS::CanCompileOffThread(cx, options, length)) {
|
||||
|
|
@ -4628,18 +4503,20 @@ OffThreadCompileScript(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
OffThreadJob* job = sc->offThreadState.newJob(cx, ScriptKind::Script, Move(ownedChars));
|
||||
if (!job)
|
||||
return false;
|
||||
|
||||
if (!JS::CompileOffThread(cx, options, chars, length,
|
||||
OffThreadCompileScriptCallback, job))
|
||||
{
|
||||
sc->offThreadState.deleteJob(cx, job);
|
||||
if (!sc->offThreadState.startIfIdle(cx, ScriptKind::Script, ownedChars)) {
|
||||
JS_ReportErrorASCII(cx, "called offThreadCompileScript without calling runOffThreadScript"
|
||||
" to receive prior off-thread compilation");
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setInt32(job->id);
|
||||
if (!JS::CompileOffThread(cx, options, chars, length,
|
||||
OffThreadCompileScriptCallback, sc))
|
||||
{
|
||||
sc->offThreadState.abandon(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -4652,14 +4529,11 @@ runOffThreadScript(JSContext* cx, unsigned argc, Value* vp)
|
|||
gc::FinishGC(cx);
|
||||
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
OffThreadJob* job = sc->offThreadState.lookupJobForArgs(cx, ScriptKind::Script, args, 0);
|
||||
if (!job)
|
||||
void* token = sc->offThreadState.waitUntilDone(cx, ScriptKind::Script);
|
||||
if (!token) {
|
||||
JS_ReportErrorASCII(cx, "called runOffThreadScript when no compilation is pending");
|
||||
return false;
|
||||
|
||||
void* token = job->waitUntilDone(cx);
|
||||
MOZ_ASSERT(token);
|
||||
|
||||
sc->offThreadState.deleteJob(cx, job);
|
||||
}
|
||||
|
||||
RootedScript script(cx, JS::FinishOffThreadScript(cx, token));
|
||||
if (!script)
|
||||
|
|
@ -4697,16 +4571,17 @@ OffThreadCompileModule(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
// Make sure we own the string's chars, so that they are not freed before
|
||||
// the compilation is finished.
|
||||
JS::UniqueTwoByteChars ownedChars;
|
||||
ScopedJSFreePtr<char16_t> ownedChars;
|
||||
if (stableChars.maybeGiveOwnershipToCaller()) {
|
||||
ownedChars.reset(const_cast<char16_t*>(chars));
|
||||
ownedChars = const_cast<char16_t*>(chars);
|
||||
} else {
|
||||
ownedChars.reset(cx->pod_malloc<char16_t>(length));
|
||||
if (!ownedChars)
|
||||
char16_t* copy = cx->pod_malloc<char16_t>(length);
|
||||
if (!copy)
|
||||
return false;
|
||||
|
||||
mozilla::PodCopy(ownedChars.get(), chars, length);
|
||||
chars = ownedChars.get();
|
||||
mozilla::PodCopy(copy, chars, length);
|
||||
ownedChars = copy;
|
||||
chars = copy;
|
||||
}
|
||||
|
||||
if (!JS::CanCompileOffThread(cx, options, length)) {
|
||||
|
|
@ -4715,18 +4590,20 @@ OffThreadCompileModule(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
OffThreadJob* job = sc->offThreadState.newJob(cx, ScriptKind::Module, Move(ownedChars));
|
||||
if (!job)
|
||||
return false;
|
||||
|
||||
if (!JS::CompileOffThreadModule(cx, options, chars, length,
|
||||
OffThreadCompileScriptCallback, job))
|
||||
{
|
||||
sc->offThreadState.deleteJob(cx, job);
|
||||
if (!sc->offThreadState.startIfIdle(cx, ScriptKind::Module, ownedChars)) {
|
||||
JS_ReportErrorASCII(cx, "called offThreadCompileModule without receiving prior off-thread "
|
||||
"compilation");
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setInt32(job->id);
|
||||
if (!JS::CompileOffThreadModule(cx, options, chars, length,
|
||||
OffThreadCompileScriptCallback, sc))
|
||||
{
|
||||
sc->offThreadState.abandon(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -4739,14 +4616,11 @@ FinishOffThreadModule(JSContext* cx, unsigned argc, Value* vp)
|
|||
gc::FinishGC(cx);
|
||||
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
OffThreadJob* job = sc->offThreadState.lookupJobForArgs(cx, ScriptKind::Module, args, 0);
|
||||
if (!job)
|
||||
void* token = sc->offThreadState.waitUntilDone(cx, ScriptKind::Module);
|
||||
if (!token) {
|
||||
JS_ReportErrorASCII(cx, "called finishOffThreadModule when no compilation is pending");
|
||||
return false;
|
||||
|
||||
void* token = job->waitUntilDone(cx);
|
||||
MOZ_ASSERT(token);
|
||||
|
||||
sc->offThreadState.deleteJob(cx, job);
|
||||
}
|
||||
|
||||
RootedObject module(cx, JS::FinishOffThreadModule(cx, token));
|
||||
if (!module)
|
||||
|
|
@ -6363,8 +6237,7 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
|||
JS_FN_HELP("offThreadCompileScript", OffThreadCompileScript, 1, 0,
|
||||
"offThreadCompileScript(code[, options])",
|
||||
" Compile |code| on a helper thread. To wait for the compilation to finish\n"
|
||||
" and run the code, call |runOffThreadScript|. The function returns a job ID.\n"
|
||||
" If present, |options| may\n"
|
||||
" and run the code, call |runOffThreadScript|. If present, |options| may\n"
|
||||
" have properties saying how the code should be compiled:\n"
|
||||
" noScriptRval: use the no-script-rval compiler option (default: false)\n"
|
||||
" fileName: filename for error messages and debug info\n"
|
||||
|
|
@ -6379,22 +6252,19 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
|||
" Debugger.Source.prototype.elementAttributeName returns.\n"),
|
||||
|
||||
JS_FN_HELP("runOffThreadScript", runOffThreadScript, 0, 0,
|
||||
"runOffThreadScript([jobID])",
|
||||
" Wait for an off-thread compilation job to complete. The job ID can be\n"
|
||||
" omitted if there is only one job pending. If an error occurred,\n"
|
||||
"runOffThreadScript()",
|
||||
" Wait for off-thread compilation to complete. If an error occurred,\n"
|
||||
" throw the appropriate exception; otherwise, run the script and return\n"
|
||||
" its value."),
|
||||
|
||||
JS_FN_HELP("offThreadCompileModule", OffThreadCompileModule, 1, 0,
|
||||
"offThreadCompileModule(code)",
|
||||
" Compile |code| on a helper thread, returning a job ID. To wait for the\n"
|
||||
" compilation to finish and get the module object, call |finishOffThreadModule|\n"
|
||||
" passing the job ID."),
|
||||
" Compile |code| on a helper thread. To wait for the compilation to finish\n"
|
||||
" and get the module object, call |finishOffThreadModule|."),
|
||||
|
||||
JS_FN_HELP("finishOffThreadModule", FinishOffThreadModule, 0, 0,
|
||||
"finishOffThreadModule([jobID])",
|
||||
" Wait for an off-thread compilation job to complete. The job ID can be\n"
|
||||
" omitted if there is only one job pending. If an error occurred,\n"
|
||||
"finishOffThreadModule()",
|
||||
" Wait for off-thread compilation to complete. If an error occurred,\n"
|
||||
" throw the appropriate exception; otherwise, return the module object"),
|
||||
|
||||
JS_FN_HELP("timeout", Timeout, 1, 0,
|
||||
|
|
@ -8438,8 +8308,6 @@ main(int argc, char** argv, char** envp)
|
|||
|
||||
DestructSharedArrayBufferMailbox();
|
||||
|
||||
sc->offThreadState.cancelAll(cx);
|
||||
|
||||
JS_DestroyContext(cx);
|
||||
JS_ShutDown();
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -860,31 +860,19 @@ GlobalHelperThreadState::waitForAllThreads()
|
|||
|
||||
template <typename T>
|
||||
bool
|
||||
GlobalHelperThreadState::checkTaskThreadLimit(size_t maxThreads, bool isMaster) const
|
||||
GlobalHelperThreadState::checkTaskThreadLimit(size_t maxThreads) const
|
||||
{
|
||||
MOZ_ASSERT(maxThreads > 0);
|
||||
|
||||
if (maxThreads >= threadCount)
|
||||
return true;
|
||||
|
||||
size_t count = 0;
|
||||
size_t idle = 0;
|
||||
for (auto& thread : *threads) {
|
||||
if (thread.currentTask.isSome()) {
|
||||
if (thread.currentTask->is<T>())
|
||||
count++;
|
||||
} else {
|
||||
idle++;
|
||||
}
|
||||
if (thread.currentTask.isSome() && thread.currentTask->is<T>())
|
||||
count++;
|
||||
if (count >= maxThreads)
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(idle > 0);
|
||||
|
||||
if (isMaster && idle <= 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1103,11 +1091,7 @@ GlobalHelperThreadState::pendingIonCompileHasSufficientPriority(
|
|||
bool
|
||||
GlobalHelperThreadState::canStartParseTask(const AutoLockHelperThreadState& lock)
|
||||
{
|
||||
// Parse tasks that end up compiling asm.js may use Wasm compilation threads
|
||||
// to generate machine code. We do not know ahead of time which parse tasks
|
||||
// will need those resources, so conservatively treat them as master tasks.
|
||||
return !parseWorklist(lock).empty() &&
|
||||
checkTaskThreadLimit<ParseTask*>(maxParseThreads(), /*isMaster=*/true);
|
||||
return !parseWorklist(lock).empty() && checkTaskThreadLimit<ParseTask*>(maxParseThreads());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1908,56 +1892,49 @@ HelperThread::threadLoop()
|
|||
while (true) {
|
||||
MOZ_ASSERT(idle());
|
||||
|
||||
js::oom::ThreadType task = js::oom::THREAD_TYPE_NONE;
|
||||
// Block until a task is available. Save the value of whether we are
|
||||
// going to do an Ion compile, in case the value returned by the method
|
||||
// changes.
|
||||
bool ionCompile = false;
|
||||
while (true) {
|
||||
if (terminate)
|
||||
return;
|
||||
if (HelperThreadState().canStartGCParallelTask(lock))
|
||||
task = js::oom::THREAD_TYPE_GCPARALLEL;
|
||||
else if (HelperThreadState().canStartGCHelperTask(lock))
|
||||
task = js::oom::THREAD_TYPE_GCHELPER;
|
||||
else if (HelperThreadState().pendingIonCompileHasSufficientPriority(lock))
|
||||
task = js::oom::THREAD_TYPE_ION;
|
||||
else if (HelperThreadState().canStartWasmCompile(lock))
|
||||
task = js::oom::THREAD_TYPE_ASMJS;
|
||||
else if (HelperThreadState().canStartPromiseTask(lock))
|
||||
task = js::oom::THREAD_TYPE_PROMISE_TASK;
|
||||
else if (HelperThreadState().canStartParseTask(lock))
|
||||
task = js::oom::THREAD_TYPE_PARSE;
|
||||
else if (HelperThreadState().canStartCompressionTask(lock))
|
||||
task = js::oom::THREAD_TYPE_COMPRESS;
|
||||
|
||||
if (task != js::oom::THREAD_TYPE_NONE)
|
||||
if ((ionCompile = HelperThreadState().pendingIonCompileHasSufficientPriority(lock)) ||
|
||||
HelperThreadState().canStartWasmCompile(lock) ||
|
||||
HelperThreadState().canStartPromiseTask(lock) ||
|
||||
HelperThreadState().canStartParseTask(lock) ||
|
||||
HelperThreadState().canStartCompressionTask(lock) ||
|
||||
HelperThreadState().canStartGCHelperTask(lock) ||
|
||||
HelperThreadState().canStartGCParallelTask(lock))
|
||||
{
|
||||
break;
|
||||
}
|
||||
HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
|
||||
}
|
||||
|
||||
js::oom::SetThreadType(task);
|
||||
switch (task) {
|
||||
case js::oom::THREAD_TYPE_GCPARALLEL:
|
||||
handleGCParallelWorkload(lock);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_GCHELPER:
|
||||
handleGCHelperWorkload(lock);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_ION:
|
||||
if (ionCompile) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_ION);
|
||||
handleIonWorkload(lock);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_ASMJS:
|
||||
} else if (HelperThreadState().canStartWasmCompile(lock)) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_ASMJS);
|
||||
handleWasmWorkload(lock);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_PROMISE_TASK:
|
||||
} else if (HelperThreadState().canStartPromiseTask(lock)) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_PROMISE_TASK);
|
||||
handlePromiseTaskWorkload(lock);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_PARSE:
|
||||
} else if (HelperThreadState().canStartParseTask(lock)) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_PARSE);
|
||||
handleParseWorkload(lock, stackLimit);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_COMPRESS:
|
||||
} else if (HelperThreadState().canStartCompressionTask(lock)) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_COMPRESS);
|
||||
handleCompressionWorkload(lock);
|
||||
break;
|
||||
default:
|
||||
} else if (HelperThreadState().canStartGCHelperTask(lock)) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_GCHELPER);
|
||||
handleGCHelperWorkload(lock);
|
||||
} else if (HelperThreadState().canStartGCParallelTask(lock)) {
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_GCPARALLEL);
|
||||
handleGCParallelWorkload(lock);
|
||||
} else {
|
||||
MOZ_CRASH("No task to perform");
|
||||
}
|
||||
js::oom::SetThreadType(js::oom::THREAD_TYPE_NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ class GlobalHelperThreadState
|
|||
void waitForAllThreads();
|
||||
|
||||
template <typename T>
|
||||
bool checkTaskThreadLimit(size_t maxThreads, bool isMaster = false) const;
|
||||
bool checkTaskThreadLimit(size_t maxThreads) const;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue