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

@ -1605,6 +1605,7 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
bool catchTermination = false;
bool loadBytecode = false;
bool saveBytecode = false;
bool saveIncrementalBytecode = false;
bool assertEqBytecode = false;
RootedObject callerGlobal(cx, cx->global());
@ -1668,6 +1669,11 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
if (!v.isUndefined())
saveBytecode = ToBoolean(v);
if (!JS_GetProperty(cx, opts, "saveIncrementalBytecode", &v))
return false;
if (!v.isUndefined())
saveIncrementalBytecode = ToBoolean(v);
if (!JS_GetProperty(cx, opts, "assertEqBytecode", &v))
return false;
if (!v.isUndefined())
@ -1675,12 +1681,17 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
// We cannot load or save the bytecode if we have no object where the
// bytecode cache is stored.
if (loadBytecode || saveBytecode) {
if (loadBytecode || saveBytecode || saveIncrementalBytecode) {
if (!cacheEntry) {
JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
"evaluate");
return false;
}
if (saveIncrementalBytecode && saveBytecode) {
JS_ReportErrorASCII(cx, "saveIncrementalBytecode and saveBytecode cannot be used"
" at the same time.");
return false;
}
}
}
@ -1758,6 +1769,15 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
if (!script->scriptSource()->setSourceMapURL(cx, smurl))
return false;
}
// If we want to save the bytecode incrementally, then we should
// register ahead the fact that every JSFunction which is being
// delazified should be encoded at the end of the delazification.
if (saveIncrementalBytecode) {
if (!StartIncrementalEncoding(cx, saveBuffer, script))
return false;
}
if (!JS_ExecuteScript(cx, script, args.rval())) {
if (catchTermination && !JS_IsExceptionPending(cx)) {
JSAutoCompartment ac1(cx, callerGlobal);
@ -1770,14 +1790,21 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
return false;
}
// Encode the bytecode after the execution of the script.
if (saveBytecode) {
JS::TranscodeResult rv = JS::EncodeScript(cx, saveBuffer, script);
if (!ConvertTranscodeResultToJSException(cx, rv))
return false;
}
// Serialize the encoded bytecode, recorded before the execution, into a
// buffer which can be deserialized linearly.
if (saveIncrementalBytecode) {
if (!FinishIncrementalEncoding(cx, script))
return false;
}
}
if (saveBytecode) {
if (saveBytecode || saveIncrementalBytecode) {
// If we are both loading and saving, we assert that we are going to
// replace the current bytecode by the same stream of bytes.
if (loadBytecode && assertEqBytecode) {