Issue #1691 - Part 7e: Dependencies for required to finish part 7d. https://bugzilla.mozilla.org/show_bug.cgi?id=1331662 Reimplement EvaluateString using the ExecutionContext class. https://bugzilla.mozilla.org/show_bug.cgi?id=1316078 Extract redudant code into StartOffThreadParseTask. Use an ExclusiveContext instead of a JSContext in XDR functions. Add a script decoder as a valid off-main-thread parse-task. https://bugzilla.mozilla.org/show_bug.cgi?id=900784 Add nsJSUtils functions for encoding and decoding the bytecode. https://bugzilla.mozilla.org/show_bug.cgi?id=1316081 Add XDRIncrementalEncoder to replace delazified LazyScript in the encoded XDR buffer. Add an XDRIncrementalEncoder instance on the ScriptSource. Expose a new JSAPI to incrementally encode bytecode when it is generated. https://bugzilla.mozilla.org/show_bug.cgi?id=1334091 XDR function use the sourceObject instead of the enclosingScript as argument.

(cherry picked from commit d6de9a669f4b2f5115670bd771cd53d7cfb3956a)
This commit is contained in:
Brian Smith 2023-04-20 07:38:48 -05:00 committed by roytam1
commit 993476283d
22 changed files with 1224 additions and 171 deletions

View file

@ -304,6 +304,18 @@ ParseTask::ParseTask(ParseTaskKind kind, ExclusiveContext* cx, JSObject* exclusi
{
}
ParseTask::ParseTask(ParseTaskKind kind, ExclusiveContext* cx, JSObject* exclusiveContextGlobal,
JSContext* initCx, JS::TranscodeBuffer& buffer, size_t cursor,
JS::OffThreadCompileCallback callback, void* callbackData)
: kind(kind), cx(cx), options(initCx), buffer(&buffer), cursor(cursor),
alloc(JSRuntime::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
exclusiveContextGlobal(exclusiveContextGlobal),
callback(callback), callbackData(callbackData),
script(nullptr), sourceObject(nullptr),
errors(cx), overRecursed(false), outOfMemory(false)
{
}
bool
ParseTask::init(JSContext* cx, const ReadOnlyCompileOptions& options)
{
@ -389,6 +401,29 @@ ModuleParseTask::parse()
script = module->script();
}
ScriptDecodeTask::ScriptDecodeTask(ExclusiveContext* cx, JSObject* exclusiveContextGlobal,
JSContext* initCx, JS::TranscodeBuffer& buffer, size_t cursor,
JS::OffThreadCompileCallback callback, void* callbackData)
: ParseTask(ParseTaskKind::ScriptDecode, cx, exclusiveContextGlobal, initCx,
buffer, cursor, callback, callbackData)
{
}
void
ScriptDecodeTask::parse()
{
RootedScript resultScript(cx);
XDROffThreadDecoder decoder(cx, alloc, &options, /* sourceObjectOut = */ &sourceObject,
*buffer, cursor);
decoder.codeScript(&resultScript);
MOZ_ASSERT(bool(resultScript) == (decoder.resultCode() == JS::TranscodeResult_Ok));
if (decoder.resultCode() == JS::TranscodeResult_Ok) {
script = resultScript.get();
} else {
sourceObject = nullptr;
}
}
void
js::CancelOffThreadParses(JSRuntime* rt)
{
@ -557,10 +592,10 @@ QueueOffThreadParseTask(JSContext* cx, ParseTask* task)
return true;
}
template <typename TaskFunctor>
bool
js::StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& options,
const char16_t* chars, size_t length,
JS::OffThreadCompileCallback callback, void* callbackData)
StartOffThreadParseTask(JSContext* cx, const ReadOnlyCompileOptions& options,
ParseTaskKind kind, TaskFunctor& taskFunctor)
{
// Suppress GC so that calls below do not trigger a new incremental GC
// which could require barriers on the atoms compartment.
@ -568,7 +603,7 @@ js::StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& optio
gc::AutoAssertNoNurseryAlloc noNurseryAlloc(cx->runtime());
AutoSuppressAllocationMetadataBuilder suppressMetadata(cx);
JSObject* global = CreateGlobalForOffThreadParse(cx, ParseTaskKind::Script, nogc);
JSObject* global = CreateGlobalForOffThreadParse(cx, kind, nogc);
if (!global)
return false;
@ -578,9 +613,7 @@ js::StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& optio
if (!helpercx)
return false;
ScopedJSDeletePtr<ParseTask> task(
cx->new_<ScriptParseTask>(helpercx.get(), global, cx, chars, length,
callback, callbackData));
ScopedJSDeletePtr<ParseTask> task(taskFunctor(helpercx.get(), global));
if (!task)
return false;
@ -594,41 +627,40 @@ js::StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& optio
return true;
}
bool
js::StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& options,
const char16_t* chars, size_t length,
JS::OffThreadCompileCallback callback, void* callbackData)
{
auto functor = [&](ExclusiveContext* helpercx, JSObject* global) -> ScriptParseTask* {
return cx->new_<ScriptParseTask>(helpercx, global, cx, chars, length,
callback, callbackData);
};
return StartOffThreadParseTask(cx, options, ParseTaskKind::Script, functor);
}
bool
js::StartOffThreadParseModule(JSContext* cx, const ReadOnlyCompileOptions& options,
const char16_t* chars, size_t length,
JS::OffThreadCompileCallback callback, void* callbackData)
{
// Suppress GC so that calls below do not trigger a new incremental GC
// which could require barriers on the atoms compartment.
gc::AutoSuppressGC nogc(cx);
gc::AutoAssertNoNurseryAlloc noNurseryAlloc(cx->runtime());
AutoSuppressAllocationMetadataBuilder suppressMetadata(cx);
auto functor = [&](ExclusiveContext* helpercx, JSObject* global) -> ModuleParseTask* {
return cx->new_<ModuleParseTask>(helpercx, global, cx, chars, length,
callback, callbackData);
};
return StartOffThreadParseTask(cx, options, ParseTaskKind::Module, functor);
}
JSObject* global = CreateGlobalForOffThreadParse(cx, ParseTaskKind::Module, nogc);
if (!global)
return false;
ScopedJSDeletePtr<ExclusiveContext> helpercx(
cx->new_<ExclusiveContext>(cx->runtime(), (PerThreadData*) nullptr,
ExclusiveContext::Context_Exclusive, cx->options()));
if (!helpercx)
return false;
ScopedJSDeletePtr<ParseTask> task(
cx->new_<ModuleParseTask>(helpercx.get(), global, cx, chars, length,
callback, callbackData));
if (!task)
return false;
helpercx.forget();
if (!task->init(cx, options) || !QueueOffThreadParseTask(cx, task))
return false;
task.forget();
return true;
bool
js::StartOffThreadDecodeScript(JSContext* cx, const ReadOnlyCompileOptions& options,
JS::TranscodeBuffer& buffer, size_t cursor,
JS::OffThreadCompileCallback callback, void* callbackData)
{
auto functor = [&](ExclusiveContext* helpercx, JSObject* global) -> ScriptDecodeTask* {
return cx->new_<ScriptDecodeTask>(helpercx, global, cx, buffer, cursor,
callback, callbackData);
};
return StartOffThreadParseTask(cx, options, ParseTaskKind::ScriptDecode, functor);
}
void
@ -1280,6 +1312,14 @@ GlobalHelperThreadState::finishScriptParseTask(JSContext* cx, void* token)
return script;
}
JSScript*
GlobalHelperThreadState::finishScriptDecodeTask(JSContext* cx, void* token)
{
JSScript* script = finishParseTask(cx, ParseTaskKind::ScriptDecode, token);
MOZ_ASSERT_IF(script, script->isGlobalCode());
return script;
}
JSObject*
GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, void* token)
{