mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 05:45:33 +00:00
Bug 1456774 - Remove linear search for finished parse task and type off thread parse token r=jandem r=baku
This commit is contained in:
parent
da3f5d7ce7
commit
0924042900
@ -197,7 +197,7 @@ nsJSUtils::ExecutionContext::SetScopeChain(
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::ExecutionContext::JoinAndExec(void **aOffThreadToken,
|
||||
nsJSUtils::ExecutionContext::JoinAndExec(JS::OffThreadToken** aOffThreadToken,
|
||||
JS::MutableHandle<JSScript*> aScript)
|
||||
{
|
||||
if (mSkip) {
|
||||
@ -324,7 +324,7 @@ nsJSUtils::ExecutionContext::DecodeAndExec(JS::CompileOptions& aCompileOptions,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::ExecutionContext::DecodeJoinAndExec(void **aOffThreadToken)
|
||||
nsJSUtils::ExecutionContext::DecodeJoinAndExec(JS::OffThreadToken** aOffThreadToken)
|
||||
{
|
||||
if (mSkip) {
|
||||
return mRv;
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
// thread before starting the execution of the script.
|
||||
//
|
||||
// The compiled script would be returned in the |aScript| out-param.
|
||||
MOZ_MUST_USE nsresult JoinAndExec(void **aOffThreadToken,
|
||||
MOZ_MUST_USE nsresult JoinAndExec(JS::OffThreadToken** aOffThreadToken,
|
||||
JS::MutableHandle<JSScript*> aScript);
|
||||
|
||||
// Compile a script contained in a SourceBuffer, and execute it.
|
||||
@ -178,7 +178,7 @@ public:
|
||||
// After getting a notification that an off-thread decoding terminated, this
|
||||
// function will get the result of the decoder by moving it to the main
|
||||
// thread before starting the execution of the script.
|
||||
MOZ_MUST_USE nsresult DecodeJoinAndExec(void **aOffThreadToken);
|
||||
MOZ_MUST_USE nsresult DecodeJoinAndExec(JS::OffThreadToken** aOffThreadToken);
|
||||
};
|
||||
|
||||
static nsresult CompileModule(JSContext* aCx,
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
|
||||
virtual void SetReady();
|
||||
|
||||
void** OffThreadTokenPtr()
|
||||
JS::OffThreadToken** OffThreadTokenPtr()
|
||||
{
|
||||
return mOffThreadToken ? &mOffThreadToken : nullptr;
|
||||
}
|
||||
@ -202,7 +202,7 @@ public:
|
||||
bool mIsCanceled; // True if we have been explicitly canceled.
|
||||
bool mWasCompiledOMT; // True if the script has been compiled off main thread.
|
||||
bool mIsTracking; // True if the script comes from a source on our tracking protection list.
|
||||
void* mOffThreadToken; // Off-thread parsing token.
|
||||
JS::OffThreadToken* mOffThreadToken; // Off-thread parsing token.
|
||||
nsString mSourceMapURL; // Holds source map url for loaded scripts
|
||||
|
||||
// Holds the top-level JSScript that corresponds to the current source, once
|
||||
|
@ -1660,7 +1660,7 @@ class NotifyOffThreadScriptLoadCompletedRunnable : public Runnable
|
||||
RefPtr<ScriptLoadRequest> mRequest;
|
||||
RefPtr<ScriptLoader> mLoader;
|
||||
RefPtr<DocGroup> mDocGroup;
|
||||
void* mToken;
|
||||
JS::OffThreadToken* mToken;
|
||||
|
||||
public:
|
||||
NotifyOffThreadScriptLoadCompletedRunnable(ScriptLoadRequest* aRequest,
|
||||
@ -1676,7 +1676,7 @@ public:
|
||||
|
||||
virtual ~NotifyOffThreadScriptLoadCompletedRunnable();
|
||||
|
||||
void SetToken(void* aToken) {
|
||||
void SetToken(JS::OffThreadToken* aToken) {
|
||||
MOZ_ASSERT(aToken && !mToken);
|
||||
mToken = aToken;
|
||||
}
|
||||
@ -1757,7 +1757,7 @@ NotifyOffThreadScriptLoadCompletedRunnable::Run()
|
||||
}
|
||||
|
||||
static void
|
||||
OffThreadScriptLoaderCallback(void* aToken, void* aCallbackData)
|
||||
OffThreadScriptLoaderCallback(JS::OffThreadToken* aToken, void* aCallbackData)
|
||||
{
|
||||
RefPtr<NotifyOffThreadScriptLoadCompletedRunnable> aRunnable =
|
||||
dont_AddRef(static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData));
|
||||
|
@ -2567,11 +2567,11 @@ class NotifyOffThreadScriptCompletedRunnable : public Runnable
|
||||
static bool sSetupClearOnShutdown;
|
||||
|
||||
nsIOffThreadScriptReceiver* mReceiver;
|
||||
void *mToken;
|
||||
JS::OffThreadToken* mToken;
|
||||
|
||||
public:
|
||||
NotifyOffThreadScriptCompletedRunnable(nsIOffThreadScriptReceiver* aReceiver,
|
||||
void* aToken)
|
||||
JS::OffThreadToken* aToken)
|
||||
: mozilla::Runnable("NotifyOffThreadScriptCompletedRunnable")
|
||||
, mReceiver(aReceiver)
|
||||
, mToken(aToken)
|
||||
@ -2628,7 +2628,7 @@ NotifyOffThreadScriptCompletedRunnable::Run()
|
||||
}
|
||||
|
||||
static void
|
||||
OffThreadScriptReceiverCallback(void *aToken, void *aCallbackData)
|
||||
OffThreadScriptReceiverCallback(JS::OffThreadToken* aToken, void* aCallbackData)
|
||||
{
|
||||
// Be careful not to adjust the refcount on the receiver, as this callback
|
||||
// may be invoked off the main thread.
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "vm/Monitor.h"
|
||||
#include "vm/MutexIDs.h"
|
||||
|
||||
|
||||
using namespace JS;
|
||||
using js::AutoLockMonitor;
|
||||
|
||||
@ -17,7 +16,7 @@ struct OffThreadTask {
|
||||
token(nullptr)
|
||||
{}
|
||||
|
||||
void* waitUntilDone(JSContext* cx)
|
||||
OffThreadToken* waitUntilDone(JSContext* cx)
|
||||
{
|
||||
if (OffThreadParsingMustWaitForGC(cx->runtime()))
|
||||
js::gc::FinishGC(cx);
|
||||
@ -26,12 +25,12 @@ struct OffThreadTask {
|
||||
while (!token) {
|
||||
alm.wait();
|
||||
}
|
||||
void* result = token;
|
||||
OffThreadToken* result = token;
|
||||
token = nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
void markDone(void* tokenArg)
|
||||
void markDone(JS::OffThreadToken* tokenArg)
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
token = tokenArg;
|
||||
@ -39,14 +38,14 @@ struct OffThreadTask {
|
||||
}
|
||||
|
||||
static void
|
||||
OffThreadCallback(void* token, void* context)
|
||||
OffThreadCallback(OffThreadToken* token, void* context)
|
||||
{
|
||||
auto self = static_cast<OffThreadTask*>(context);
|
||||
self->markDone(token);
|
||||
}
|
||||
|
||||
js::Monitor monitor;
|
||||
void* token;
|
||||
OffThreadToken* token;
|
||||
};
|
||||
|
||||
|
||||
@ -101,7 +100,7 @@ testCompile(bool nonSyntactic)
|
||||
|
||||
options.forceAsync = true;
|
||||
OffThreadTask task;
|
||||
void* token;
|
||||
OffThreadToken* token;
|
||||
|
||||
CHECK(CompileOffThread(cx, options, src_16, length,
|
||||
task.OffThreadCallback, &task));
|
||||
|
@ -4257,7 +4257,7 @@ JS::DecodeBinASTOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript*)
|
||||
JS::FinishOffThreadBinASTDecode(JSContext* cx, void* token)
|
||||
JS::FinishOffThreadBinASTDecode(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4321,7 +4321,7 @@ JS::CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript*)
|
||||
JS::FinishOffThreadScript(JSContext* cx, void* token)
|
||||
JS::FinishOffThreadScript(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4329,7 +4329,7 @@ JS::FinishOffThreadScript(JSContext* cx, void* token)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::CancelOffThreadScript(JSContext* cx, void* token)
|
||||
JS::CancelOffThreadScript(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4346,7 +4346,7 @@ JS::CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject*)
|
||||
JS::FinishOffThreadModule(JSContext* cx, void* token)
|
||||
JS::FinishOffThreadModule(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4354,7 +4354,7 @@ JS::FinishOffThreadModule(JSContext* cx, void* token)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::CancelOffThreadModule(JSContext* cx, void* token)
|
||||
JS::CancelOffThreadModule(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4396,7 +4396,7 @@ JS::DecodeMultiOffThreadScripts(JSContext* cx, const ReadOnlyCompileOptions& opt
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript*)
|
||||
JS::FinishOffThreadScriptDecoder(JSContext* cx, void* token)
|
||||
JS::FinishOffThreadScriptDecoder(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4404,7 +4404,7 @@ JS::FinishOffThreadScriptDecoder(JSContext* cx, void* token)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::CancelOffThreadScriptDecoder(JSContext* cx, void* token)
|
||||
JS::CancelOffThreadScriptDecoder(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4412,7 +4412,7 @@ JS::CancelOffThreadScriptDecoder(JSContext* cx, void* token)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::FinishMultiOffThreadScriptsDecoder(JSContext* cx, void* token, MutableHandle<ScriptVector> scripts)
|
||||
JS::FinishMultiOffThreadScriptsDecoder(JSContext* cx, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
@ -4420,7 +4420,7 @@ JS::FinishMultiOffThreadScriptsDecoder(JSContext* cx, void* token, MutableHandle
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::CancelMultiOffThreadScriptsDecoder(JSContext* cx, void* token)
|
||||
JS::CancelMultiOffThreadScriptsDecoder(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
|
||||
|
@ -3936,10 +3936,10 @@ CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
OffThreadCompileCallback callback, void* callbackData);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript*)
|
||||
FinishOffThreadScript(JSContext* cx, void* token);
|
||||
FinishOffThreadScript(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
CancelOffThreadScript(JSContext* cx, void* token);
|
||||
CancelOffThreadScript(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
@ -3947,10 +3947,10 @@ CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
OffThreadCompileCallback callback, void* callbackData);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
FinishOffThreadModule(JSContext* cx, void* token);
|
||||
FinishOffThreadModule(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
CancelOffThreadModule(JSContext* cx, void* token);
|
||||
CancelOffThreadModule(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
@ -3963,10 +3963,10 @@ DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
OffThreadCompileCallback callback, void* callbackData);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript*)
|
||||
FinishOffThreadScriptDecoder(JSContext* cx, void* token);
|
||||
FinishOffThreadScriptDecoder(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
CancelOffThreadScriptDecoder(JSContext* cx, void* token);
|
||||
CancelOffThreadScriptDecoder(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
DecodeMultiOffThreadScripts(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
@ -3974,10 +3974,11 @@ DecodeMultiOffThreadScripts(JSContext* cx, const ReadOnlyCompileOptions& options
|
||||
OffThreadCompileCallback callback, void* callbackData);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
FinishMultiOffThreadScriptsDecoder(JSContext* cx, void* token, JS::MutableHandle<JS::ScriptVector> scripts);
|
||||
FinishMultiOffThreadScriptsDecoder(JSContext* cx, OffThreadToken* token,
|
||||
JS::MutableHandle<JS::ScriptVector> scripts);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
CancelMultiOffThreadScriptsDecoder(JSContext* cx, void* token);
|
||||
CancelMultiOffThreadScriptsDecoder(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
/**
|
||||
* Compile a function with envChain plus the global as its scope chain.
|
||||
@ -4247,7 +4248,7 @@ DecodeBinASTOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
OffThreadCompileCallback callback, void* callbackData);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript*)
|
||||
FinishOffThreadBinASTDecode(JSContext* cx, void* token);
|
||||
FinishOffThreadBinASTDecode(JSContext* cx, OffThreadToken* token);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
|
@ -101,7 +101,9 @@ namespace JS {
|
||||
|
||||
struct JS_PUBLIC_API(PropertyDescriptor);
|
||||
|
||||
typedef void (*OffThreadCompileCallback)(void* token, void* callbackData);
|
||||
class OffThreadToken;
|
||||
|
||||
typedef void (*OffThreadCompileCallback)(OffThreadToken* token, void* callbackData);
|
||||
|
||||
enum class HeapState {
|
||||
Idle, // doing nothing with the GC heap
|
||||
|
@ -252,8 +252,8 @@ class js::shell::OffThreadJob {
|
||||
~OffThreadJob();
|
||||
|
||||
void cancel();
|
||||
void markDone(void* newToken);
|
||||
void* waitUntilDone(JSContext* cx);
|
||||
void markDone(JS::OffThreadToken* newToken);
|
||||
JS::OffThreadToken* waitUntilDone(JSContext* cx);
|
||||
|
||||
char16_t* sourceChars() { return source.as<UniqueTwoByteChars>().get(); }
|
||||
JS::TranscodeBuffer& xdrBuffer() { return source.as<JS::TranscodeBuffer>(); }
|
||||
@ -265,7 +265,7 @@ class js::shell::OffThreadJob {
|
||||
private:
|
||||
js::Monitor& monitor;
|
||||
State state;
|
||||
void* token;
|
||||
JS::OffThreadToken* token;
|
||||
Source source;
|
||||
};
|
||||
|
||||
@ -433,7 +433,7 @@ OffThreadJob::cancel()
|
||||
}
|
||||
|
||||
void
|
||||
OffThreadJob::markDone(void* newToken)
|
||||
OffThreadJob::markDone(JS::OffThreadToken* newToken)
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
MOZ_ASSERT(state == RUNNING);
|
||||
@ -445,7 +445,7 @@ OffThreadJob::markDone(void* newToken)
|
||||
alm.notifyAll();
|
||||
}
|
||||
|
||||
void*
|
||||
JS::OffThreadToken*
|
||||
OffThreadJob::waitUntilDone(JSContext* cx)
|
||||
{
|
||||
AutoLockMonitor alm(monitor);
|
||||
@ -4559,7 +4559,7 @@ SyntaxParse(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
static void
|
||||
OffThreadCompileScriptCallback(void* token, void* callbackData)
|
||||
OffThreadCompileScriptCallback(JS::OffThreadToken* token, void* callbackData)
|
||||
{
|
||||
auto job = static_cast<OffThreadJob*>(callbackData);
|
||||
job->markDone(token);
|
||||
@ -4666,7 +4666,7 @@ runOffThreadScript(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!job)
|
||||
return false;
|
||||
|
||||
void* token = job->waitUntilDone(cx);
|
||||
JS::OffThreadToken* token = job->waitUntilDone(cx);
|
||||
MOZ_ASSERT(token);
|
||||
|
||||
DeleteOffThreadJob(cx, job);
|
||||
@ -4752,7 +4752,7 @@ FinishOffThreadModule(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!job)
|
||||
return false;
|
||||
|
||||
void* token = job->waitUntilDone(cx);
|
||||
JS::OffThreadToken* token = job->waitUntilDone(cx);
|
||||
MOZ_ASSERT(token);
|
||||
|
||||
DeleteOffThreadJob(cx, job);
|
||||
@ -4857,7 +4857,7 @@ runOffThreadDecodedScript(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!job)
|
||||
return false;
|
||||
|
||||
void* token = job->waitUntilDone(cx);
|
||||
JS::OffThreadToken* token = job->waitUntilDone(cx);
|
||||
MOZ_ASSERT(token);
|
||||
|
||||
DeleteOffThreadJob(cx, job);
|
||||
|
@ -634,16 +634,19 @@ js::CancelOffThreadParses(JSRuntime* rt)
|
||||
}
|
||||
|
||||
// Clean up any parse tasks which haven't been finished by the main thread.
|
||||
GlobalHelperThreadState::ParseTaskVector& finished = HelperThreadState().parseFinishedList(lock);
|
||||
auto& finished = HelperThreadState().parseFinishedList(lock);
|
||||
while (true) {
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < finished.length(); i++) {
|
||||
ParseTask* task = finished[i];
|
||||
ParseTask* next;
|
||||
ParseTask* task = finished.getFirst();
|
||||
while (task) {
|
||||
next = task->getNext();
|
||||
if (task->runtimeMatches(rt)) {
|
||||
found = true;
|
||||
AutoUnlockHelperThreadState unlock(lock);
|
||||
HelperThreadState().cancelParseTask(rt, task->kind, task);
|
||||
}
|
||||
task = next;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
@ -1619,30 +1622,36 @@ LeaveParseTaskZone(JSRuntime* rt, ParseTask* task)
|
||||
}
|
||||
|
||||
ParseTask*
|
||||
GlobalHelperThreadState::removeFinishedParseTask(ParseTaskKind kind, void* token)
|
||||
GlobalHelperThreadState::removeFinishedParseTask(ParseTaskKind kind, JS::OffThreadToken* token)
|
||||
{
|
||||
// The token is a ParseTask* which should be in the finished list.
|
||||
// Find and remove its entry.
|
||||
// The token is really a ParseTask* which should be in the finished list.
|
||||
// Remove its entry.
|
||||
auto task = static_cast<ParseTask*>(token);
|
||||
MOZ_ASSERT(task->kind == kind);
|
||||
|
||||
AutoLockHelperThreadState lock;
|
||||
ParseTaskVector& finished = parseFinishedList(lock);
|
||||
|
||||
for (size_t i = 0; i < finished.length(); i++) {
|
||||
if (finished[i] == token) {
|
||||
ParseTask* parseTask = finished[i];
|
||||
remove(finished, &i);
|
||||
MOZ_ASSERT(parseTask);
|
||||
MOZ_ASSERT(parseTask->kind == kind);
|
||||
return parseTask;
|
||||
#ifdef DEBUG
|
||||
auto& finished = parseFinishedList(lock);
|
||||
bool found = false;
|
||||
for (auto t : finished) {
|
||||
if (t == task) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(found);
|
||||
#endif
|
||||
|
||||
MOZ_CRASH("Invalid ParseTask token");
|
||||
|
||||
task->remove();
|
||||
return task;
|
||||
}
|
||||
|
||||
template <typename F, typename>
|
||||
bool
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void* token, F&& finishCallback)
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token, F&& finishCallback)
|
||||
{
|
||||
MOZ_ASSERT(cx->compartment());
|
||||
|
||||
@ -1684,7 +1693,8 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
|
||||
}
|
||||
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void* token)
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token)
|
||||
{
|
||||
JS::RootedScript script(cx);
|
||||
|
||||
@ -1715,7 +1725,8 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void* token,
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token,
|
||||
MutableHandle<ScriptVector> scripts)
|
||||
{
|
||||
size_t expectedLength = 0;
|
||||
@ -1758,7 +1769,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
|
||||
}
|
||||
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishScriptParseTask(JSContext* cx, void* token)
|
||||
GlobalHelperThreadState::finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::Script, token);
|
||||
MOZ_ASSERT_IF(script, script->isGlobalCode());
|
||||
@ -1766,7 +1777,7 @@ GlobalHelperThreadState::finishScriptParseTask(JSContext* cx, void* token)
|
||||
}
|
||||
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishScriptDecodeTask(JSContext* cx, void* token)
|
||||
GlobalHelperThreadState::finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::ScriptDecode, token);
|
||||
MOZ_ASSERT_IF(script, script->isGlobalCode());
|
||||
@ -1776,7 +1787,7 @@ GlobalHelperThreadState::finishScriptDecodeTask(JSContext* cx, void* token)
|
||||
#if defined(JS_BUILD_BINAST)
|
||||
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishBinASTDecodeTask(JSContext* cx, void* token)
|
||||
GlobalHelperThreadState::finishBinASTDecodeTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::BinAST, token);
|
||||
MOZ_ASSERT_IF(script, script->isGlobalCode());
|
||||
@ -1786,13 +1797,14 @@ GlobalHelperThreadState::finishBinASTDecodeTask(JSContext* cx, void* token)
|
||||
#endif /* JS_BUILD_BINAST */
|
||||
|
||||
bool
|
||||
GlobalHelperThreadState::finishMultiScriptsDecodeTask(JSContext* cx, void* token, MutableHandle<ScriptVector> scripts)
|
||||
GlobalHelperThreadState::finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token,
|
||||
MutableHandle<ScriptVector> scripts)
|
||||
{
|
||||
return finishParseTask(cx, ParseTaskKind::MultiScriptsDecode, token, scripts);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, void* token)
|
||||
GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::Module, token);
|
||||
if (!script)
|
||||
@ -1809,7 +1821,8 @@ GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, void* token)
|
||||
}
|
||||
|
||||
void
|
||||
GlobalHelperThreadState::cancelParseTask(JSRuntime* rt, ParseTaskKind kind, void* token)
|
||||
GlobalHelperThreadState::cancelParseTask(JSRuntime* rt, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token)
|
||||
{
|
||||
ScopedJSDeletePtr<ParseTask> parseTask(removeFinishedParseTask(kind, token));
|
||||
LeaveParseTaskZone(rt, parseTask);
|
||||
@ -2072,11 +2085,7 @@ HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked)
|
||||
|
||||
// FinishOffThreadScript will need to be called on the script to
|
||||
// migrate it into the correct compartment.
|
||||
{
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
if (!HelperThreadState().parseFinishedList(locked).append(task))
|
||||
oomUnsafe.crash("handleParseWorkload");
|
||||
}
|
||||
HelperThreadState().parseFinishedList(locked).insertBack(task);
|
||||
|
||||
currentTask.reset();
|
||||
|
||||
|
@ -29,6 +29,10 @@
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/MutexIDs.h"
|
||||
|
||||
namespace JS {
|
||||
class OffThreadToken {};
|
||||
} // namespace JS
|
||||
|
||||
namespace js {
|
||||
|
||||
class AutoLockHelperThreadState;
|
||||
@ -90,6 +94,7 @@ class GlobalHelperThreadState
|
||||
|
||||
typedef Vector<jit::IonBuilder*, 0, SystemAllocPolicy> IonBuilderVector;
|
||||
typedef Vector<ParseTask*, 0, SystemAllocPolicy> ParseTaskVector;
|
||||
typedef mozilla::LinkedList<ParseTask> ParseTaskList;
|
||||
typedef Vector<UniquePtr<SourceCompressionTask>, 0, SystemAllocPolicy> SourceCompressionTaskVector;
|
||||
typedef Vector<GCHelperState*, 0, SystemAllocPolicy> GCHelperStateVector;
|
||||
typedef Vector<GCParallelTask*, 0, SystemAllocPolicy> GCParallelTaskVector;
|
||||
@ -118,7 +123,8 @@ class GlobalHelperThreadState
|
||||
PromiseHelperTaskVector promiseHelperTasks_;
|
||||
|
||||
// Script parsing/emitting worklist and finished jobs.
|
||||
ParseTaskVector parseWorklist_, parseFinishedList_;
|
||||
ParseTaskVector parseWorklist_;
|
||||
ParseTaskList parseFinishedList_;
|
||||
|
||||
// Parse tasks waiting for an atoms-zone GC to complete.
|
||||
ParseTaskVector parseWaitingOnGC_;
|
||||
@ -138,7 +144,7 @@ class GlobalHelperThreadState
|
||||
// GC tasks needing to be done in parallel.
|
||||
GCParallelTaskVector gcParallelWorklist_;
|
||||
|
||||
ParseTask* removeFinishedParseTask(ParseTaskKind kind, void* token);
|
||||
ParseTask* removeFinishedParseTask(ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
|
||||
public:
|
||||
|
||||
@ -235,7 +241,7 @@ class GlobalHelperThreadState
|
||||
ParseTaskVector& parseWorklist(const AutoLockHelperThreadState&) {
|
||||
return parseWorklist_;
|
||||
}
|
||||
ParseTaskVector& parseFinishedList(const AutoLockHelperThreadState&) {
|
||||
ParseTaskList& parseFinishedList(const AutoLockHelperThreadState&) {
|
||||
return parseFinishedList_;
|
||||
}
|
||||
ParseTaskVector& parseWaitingOnGC(const AutoLockHelperThreadState&) {
|
||||
@ -291,25 +297,25 @@ class GlobalHelperThreadState
|
||||
mozilla::IsSame<bool, decltype((*(F*)nullptr)((ParseTask*)nullptr))>::value
|
||||
>::Type
|
||||
>
|
||||
bool finishParseTask(JSContext* cx, ParseTaskKind kind, void* token, F&& finishCallback);
|
||||
bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, F&& finishCallback);
|
||||
|
||||
JSScript* finishParseTask(JSContext* cx, ParseTaskKind kind, void* token);
|
||||
JSScript* finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
|
||||
bool finishParseTask(JSContext* cx, ParseTaskKind kind, void* token, MutableHandle<ScriptVector> scripts);
|
||||
bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);
|
||||
|
||||
void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, void* token);
|
||||
void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
|
||||
void mergeParseTaskCompartment(JSContext* cx, ParseTask* parseTask, JSCompartment* dest);
|
||||
|
||||
void trace(JSTracer* trc, js::gc::AutoTraceSession& session);
|
||||
|
||||
JSScript* finishScriptParseTask(JSContext* cx, void* token);
|
||||
JSScript* finishScriptDecodeTask(JSContext* cx, void* token);
|
||||
bool finishMultiScriptsDecodeTask(JSContext* cx, void* token, MutableHandle<ScriptVector> scripts);
|
||||
JSObject* finishModuleParseTask(JSContext* cx, void* token);
|
||||
JSScript* finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token);
|
||||
JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token);
|
||||
bool finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);
|
||||
JSObject* finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token);
|
||||
|
||||
#if defined(JS_BUILD_BINAST)
|
||||
JSScript* finishBinASTDecodeTask(JSContext* cx, void* token);
|
||||
JSScript* finishBinASTDecodeTask(JSContext* cx, JS::OffThreadToken* token);
|
||||
#endif
|
||||
|
||||
bool hasActiveThreads(const AutoLockHelperThreadState&);
|
||||
@ -666,7 +672,7 @@ class MOZ_RAII AutoUnlockHelperThreadState : public UnlockGuard<Mutex>
|
||||
}
|
||||
};
|
||||
|
||||
struct ParseTask
|
||||
struct ParseTask : public mozilla::LinkedListElement<ParseTask>, public JS::OffThreadToken
|
||||
{
|
||||
ParseTaskKind kind;
|
||||
OwningCompileOptions options;
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
nsresult Start(nsIPrincipal* aPrincipal);
|
||||
|
||||
inline void
|
||||
SetToken(void* aToken)
|
||||
SetToken(JS::OffThreadToken* aToken)
|
||||
{
|
||||
mToken = aToken;
|
||||
}
|
||||
@ -82,7 +82,7 @@ private:
|
||||
nsCOMPtr<nsIGlobalObject> mGlobalObject;
|
||||
RefPtr<Promise> mPromise;
|
||||
nsString mCharset;
|
||||
void* mToken;
|
||||
JS::OffThreadToken* mToken;
|
||||
UniqueTwoByteChars mScriptText;
|
||||
size_t mScriptLength;
|
||||
};
|
||||
@ -113,7 +113,7 @@ AsyncScriptCompiler::Start(nsIPrincipal* aPrincipal)
|
||||
}
|
||||
|
||||
static void
|
||||
OffThreadScriptLoaderCallback(void* aToken, void* aCallbackData)
|
||||
OffThreadScriptLoaderCallback(JS::OffThreadToken* aToken, void* aCallbackData)
|
||||
{
|
||||
RefPtr<AsyncScriptCompiler> scriptCompiler = dont_AddRef(
|
||||
static_cast<AsyncScriptCompiler*>(aCallbackData));
|
||||
|
@ -896,7 +896,7 @@ ScriptPreloader::WaitForCachedScript(JSContext* cx, CachedScript* script)
|
||||
|
||||
|
||||
/* static */ void
|
||||
ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
|
||||
ScriptPreloader::OffThreadDecodeCallback(JS::OffThreadToken* token, void* context)
|
||||
{
|
||||
auto cache = static_cast<ScriptPreloader*>(context);
|
||||
|
||||
|
@ -390,7 +390,7 @@ private:
|
||||
|
||||
void DecodeNextBatch(size_t chunkSize, JS::HandleObject scope = nullptr);
|
||||
|
||||
static void OffThreadDecodeCallback(void* token, void* context);
|
||||
static void OffThreadDecodeCallback(JS::OffThreadToken* token, void* context);
|
||||
void MaybeFinishOffThreadDecode();
|
||||
void DoFinishOffThreadDecode();
|
||||
|
||||
@ -439,7 +439,7 @@ private:
|
||||
Vector<CachedScript*> mParsingScripts;
|
||||
|
||||
// The token for the completed off-thread decode task.
|
||||
void* mToken = nullptr;
|
||||
JS::OffThreadToken* mToken = nullptr;
|
||||
|
||||
// True if a runnable has been dispatched to the main thread to finish an
|
||||
// off-thread decode operation.
|
||||
|
Loading…
x
Reference in New Issue
Block a user