Bug 1566466 - Clean up relazification conditions. r=jandem

Move the relazification decisions to JSScript since the check is made after
delazification happens. The JSScript::isRelazifiable check inspects
characteristics of the script itself, while JSScript::canRelazify includes
additional checks for runtime conditions outside the script.

Depends on D55362

Differential Revision: https://phabricator.services.mozilla.com/D55390

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ted Campbell 2019-12-02 14:32:16 +00:00
Родитель 932d0d59fe
Коммит dd2de5a33d
3 изменённых файлов: 29 добавлений и 21 удалений

Просмотреть файл

@ -1108,7 +1108,7 @@ static bool IsRelazifiableFunction(JSContext* cx, unsigned argc, Value* vp) {
JSFunction* fun = &args[0].toObject().as<JSFunction>();
args.rval().setBoolean(fun->hasScript() &&
fun->nonLazyScript()->isRelazifiableIgnoringJitCode());
fun->nonLazyScript()->isRelazifiable());
return true;
}

Просмотреть файл

@ -1607,7 +1607,7 @@ static bool DelazifyCanonicalScriptedFunction(JSContext* cx,
RootedScript script(cx, fun->nonLazyScript());
MOZ_ASSERT(lazy->maybeScript() == script);
if (lazy->canRelazify()) {
if (script->isRelazifiable()) {
// Remember the lazy script on the compiled script, so it can be
// stored on the function again in case of re-lazification.
// Only functions without inner functions are re-lazified.
@ -1726,7 +1726,7 @@ void JSFunction::maybeRelazify(JSRuntime* rt) {
// Don't relazify functions with JIT code.
JSScript* script = nonLazyScript();
if (!script->isRelazifiable()) {
if (!script->canRelazify()) {
return;
}

Просмотреть файл

@ -2822,17 +2822,34 @@ class JSScript : public js::BaseScript {
void updateJitCodeRaw(JSRuntime* rt);
// We don't relazify functions with a JitScript or JIT code, but some
// callers (XDR, testing functions) want to know whether this script is
// relazifiable ignoring (or after) discarding JIT code.
bool isRelazifiableIgnoringJitCode() const {
return (selfHosted() || lazyScript) && !hasInnerFunctions() &&
!isGenerator() && !isAsync() && !isDefaultClassConstructor() &&
!doNotRelazify() && !hasCallSiteObj();
}
bool isRelazifiable() const {
return isRelazifiableIgnoringJitCode() && !hasJitScript();
// A script may not be relazifiable if parts of it can be entrained in
// interesting ways:
// - Scripts with inner-functions or direct-eval (which can add
// inner-functions) should not be relazified as their Scopes may be part
// of another scope-chain.
// - Generators and async functions may be re-entered in complex ways so
// don't discard bytecode.
// - Functions with template literals must always return the same object
// instance so must not discard it by relazifying.
return !hasInnerFunctions() && !hasDirectEval() && !isGenerator() &&
!isAsync() && !hasCallSiteObj();
}
bool canRelazify() const {
// In order to actually relazify we must satisfy additional runtime
// conditions:
// - The lazy form must still exist. This is either the original LazyScript
// or the self-hosted script that we cloned from.
// - There must not be any JIT code attached since the relazification
// process does not know how to discard it. In general, the GC should
// discard most JIT code before attempting relazification.
// - Specific subsystems (such as the Debugger) may disable scripts for
// their own reasons.
bool lazyAvailable = selfHosted() || lazyScript;
return isRelazifiable() && lazyAvailable && !hasJitScript() &&
!doNotRelazify();
}
void setLazyScript(js::LazyScript* lazy) { lazyScript = lazy; }
js::LazyScript* maybeLazyScript() { return lazyScript; }
@ -3377,15 +3394,6 @@ class LazyScript : public BaseScript {
HandleScriptSourceObject sourceObject,
Handle<LazyScript*> lazy);
bool canRelazify() const {
// Only functions without inner functions or direct eval are re-lazified.
// Functions with either of those are on the static scope chain of their
// inner functions, or in the case of eval, possibly eval'd inner
// functions. Note that if this ever changes, XDRRelazificationInfo will
// have to be fixed.
return !hasInnerFunctions() && !hasDirectEval();
}
void initScript(JSScript* script);
JSScript* maybeScript() { return script_; }