Bug 1692130 - Move DelazifyCanonicalScriptedFunction into frontend, and categorie the entire function as delazification in profiler. r=tcampbell

Depends on D105910

Differential Revision: https://phabricator.services.mozilla.com/D107302
This commit is contained in:
Tooru Fujisawa 2021-03-24 04:14:47 +00:00
parent d68f6fc838
commit 1b4f665f90
3 changed files with 70 additions and 94 deletions

View File

@ -96,14 +96,8 @@ extern JSScript* CompileEvalScript(JSContext* cx,
JS::Handle<js::Scope*> enclosingScope,
JS::Handle<JSObject*> enclosingEnv);
extern void FillCompileOptionsForLazyFunction(JS::CompileOptions& options,
Handle<BaseScript*> lazy);
extern bool CompileLazyFunction(JSContext* cx, CompilationInput& input,
const char16_t* units, size_t length);
extern bool CompileLazyFunction(JSContext* cx, CompilationInput& input,
const mozilla::Utf8Unit* units, size_t length);
extern bool DelazifyCanonicalScriptedFunction(JSContext* cx,
Handle<JSFunction*> fun);
// Certain compile options will disable the syntax parser entirely.
inline bool CanLazilyParse(const JS::ReadOnlyCompileOptions& options) {

View File

@ -29,8 +29,9 @@
#include "vm/GlobalObject.h"
#include "vm/HelperThreadState.h" // ParseTask
#include "vm/JSContext.h"
#include "vm/JSScript.h"
#include "vm/JSScript.h" // ScriptSource, UncompressedSourceCache
#include "vm/ModuleBuilder.h" // js::ModuleBuilder
#include "vm/Time.h" // AutoIncrementalTimer
#include "vm/TraceLogging.h"
#include "wasm/AsmJS.h"
@ -1001,19 +1002,9 @@ ModuleObject* frontend::CompileModule(JSContext* cx,
return CompileModuleImpl(cx, options, srcBuf);
}
void frontend::FillCompileOptionsForLazyFunction(JS::CompileOptions& options,
JS::Handle<BaseScript*> lazy) {
options.setMutedErrors(lazy->mutedErrors())
.setFileAndLine(lazy->filename(), lazy->lineno())
.setColumn(lazy->column())
.setScriptSourceOffset(lazy->sourceStart())
.setNoScriptRval(false)
.setSelfHostingMode(false);
}
template <typename Unit>
static bool CompileLazyFunctionImpl(JSContext* cx, CompilationInput& input,
const Unit* units, size_t length) {
static bool CompileLazyFunction(JSContext* cx, CompilationInput& input,
const Unit* units, size_t length) {
MOZ_ASSERT(input.source);
MOZ_ASSERT(cx->compartment() == input.lazy->compartment());
@ -1045,9 +1036,6 @@ static bool CompileLazyFunctionImpl(JSContext* cx, CompilationInput& input,
return false;
}
AutoGeckoProfilerEntry pseudoFrame(cx, "script delazify",
JS::ProfilingCategoryPair::JS_Parsing);
FunctionNode* pn = parser.standaloneLazyFunction(
fun, input.lazy->toStringStart(), input.lazy->strict(),
input.lazy->generatorKind(), input.lazy->asyncKind());
@ -1104,15 +1092,63 @@ static bool CompileLazyFunctionImpl(JSContext* cx, CompilationInput& input,
return true;
}
bool frontend::CompileLazyFunction(JSContext* cx, CompilationInput& input,
const char16_t* units, size_t length) {
return CompileLazyFunctionImpl(cx, input, units, length);
template <typename Unit>
static bool DelazifyCanonicalScriptedFunctionImpl(JSContext* cx,
HandleFunction fun,
Handle<BaseScript*> lazy,
ScriptSource* ss) {
MOZ_ASSERT(!lazy->hasBytecode(), "Script is already compiled!");
MOZ_ASSERT(lazy->function() == fun);
AutoIncrementalTimer timer(cx->realm()->timers.delazificationTime);
size_t sourceStart = lazy->sourceStart();
size_t sourceLength = lazy->sourceEnd() - lazy->sourceStart();
MOZ_ASSERT(ss->hasSourceText());
// Parse and compile the script from source.
UncompressedSourceCache::AutoHoldEntry holder;
MOZ_ASSERT(ss->hasSourceType<Unit>());
ScriptSource::PinnedUnits<Unit> units(cx, ss, holder, sourceStart,
sourceLength);
if (!units.get()) {
return false;
}
JS::CompileOptions options(cx);
options.setMutedErrors(lazy->mutedErrors())
.setFileAndLine(lazy->filename(), lazy->lineno())
.setColumn(lazy->column())
.setScriptSourceOffset(lazy->sourceStart())
.setNoScriptRval(false)
.setSelfHostingMode(false);
Rooted<CompilationInput> input(cx, CompilationInput(options));
input.get().initFromLazy(lazy, ss);
return CompileLazyFunction(cx, input.get(), units.get(), sourceLength);
}
bool frontend::CompileLazyFunction(JSContext* cx, CompilationInput& input,
const mozilla::Utf8Unit* units,
size_t length) {
return CompileLazyFunctionImpl(cx, input, units, length);
bool frontend::DelazifyCanonicalScriptedFunction(JSContext* cx,
HandleFunction fun) {
AutoGeckoProfilerEntry pseudoFrame(cx, "script delazify",
JS::ProfilingCategoryPair::JS_Parsing);
Rooted<BaseScript*> lazy(cx, fun->baseScript());
ScriptSource* ss = lazy->scriptSource();
if (ss->hasSourceType<Utf8Unit>()) {
// UTF-8 source text.
return DelazifyCanonicalScriptedFunctionImpl<Utf8Unit>(cx, fun, lazy, ss);
}
MOZ_ASSERT(ss->hasSourceType<char16_t>());
// UTF-16 source text.
return DelazifyCanonicalScriptedFunctionImpl<char16_t>(cx, fun, lazy, ss);
}
static JSFunction* CompileStandaloneFunction(

View File

@ -1514,68 +1514,6 @@ bool JSFunction::finishBoundFunctionInit(JSContext* cx, HandleFunction bound,
return true;
}
template <typename Unit>
bool DelazifyCanonicalScriptedFunctionImpl(JSContext* cx, HandleFunction fun,
Handle<BaseScript*> lazy,
ScriptSource* ss) {
MOZ_ASSERT(!lazy->hasBytecode(), "Script is already compiled!");
MOZ_ASSERT(lazy->function() == fun);
AutoIncrementalTimer timer(cx->realm()->timers.delazificationTime);
size_t sourceStart = lazy->sourceStart();
size_t sourceLength = lazy->sourceEnd() - lazy->sourceStart();
{
MOZ_ASSERT(ss->hasSourceText());
// Parse and compile the script from source.
UncompressedSourceCache::AutoHoldEntry holder;
MOZ_ASSERT(ss->hasSourceType<Unit>());
ScriptSource::PinnedUnits<Unit> units(cx, ss, holder, sourceStart,
sourceLength);
if (!units.get()) {
return false;
}
JS::CompileOptions options(cx);
frontend::FillCompileOptionsForLazyFunction(options, lazy);
Rooted<frontend::CompilationInput> input(
cx, frontend::CompilationInput(options));
input.get().initFromLazy(lazy, ss);
if (!frontend::CompileLazyFunction(cx, input.get(), units.get(),
sourceLength)) {
// The frontend shouldn't fail after linking the function and the
// non-lazy script together.
MOZ_ASSERT(fun->baseScript() == lazy);
MOZ_ASSERT(lazy->isReadyForDelazification());
return false;
}
}
return true;
}
static bool DelazifyCanonicalScriptedFunction(JSContext* cx,
HandleFunction fun) {
Rooted<BaseScript*> lazy(cx, fun->baseScript());
ScriptSource* ss = lazy->scriptSource();
if (ss->hasSourceType<Utf8Unit>()) {
// UTF-8 source text.
return DelazifyCanonicalScriptedFunctionImpl<Utf8Unit>(cx, fun, lazy, ss);
}
MOZ_ASSERT(ss->hasSourceType<char16_t>());
// UTF-16 source text.
return DelazifyCanonicalScriptedFunctionImpl<char16_t>(cx, fun, lazy, ss);
}
/* static */
bool JSFunction::delazifyLazilyInterpretedFunction(JSContext* cx,
HandleFunction fun) {
@ -1606,7 +1544,15 @@ bool JSFunction::delazifyLazilyInterpretedFunction(JSContext* cx,
}
// Finally, compile the script if it really doesn't exist.
return DelazifyCanonicalScriptedFunction(cx, fun);
if (!frontend::DelazifyCanonicalScriptedFunction(cx, fun)) {
// The frontend shouldn't fail after linking the function and the
// non-lazy script together.
MOZ_ASSERT(fun->baseScript() == lazy);
MOZ_ASSERT(lazy->isReadyForDelazification());
return false;
}
return true;
}
/* static */