Issue #2271 - Separate cloning of native and interpreted functions

Separate code paths make it easier to follow and specialize than a single
one-size-fits-all function.

Based-on: m-c 1405766, 1411954
This commit is contained in:
Martok 2023-07-13 02:37:07 +02:00 committed by roytam1
commit 3eb7729d04
7 changed files with 108 additions and 68 deletions

View file

@ -2909,23 +2909,29 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
RootedObject clone(cx);
if (selfHostedObject->is<JSFunction>()) {
RootedFunction selfHostedFunction(cx, &selfHostedObject->as<JSFunction>());
bool hasName = selfHostedFunction->explicitName() != nullptr;
if (selfHostedFunction->isInterpreted()) {
bool hasName = selfHostedFunction->explicitName() != nullptr;
// Arrow functions use the first extended slot for their lexical |this| value.
MOZ_ASSERT(!selfHostedFunction->isArrow());
js::gc::AllocKind kind = hasName
? gc::AllocKind::FUNCTION_EXTENDED
: selfHostedFunction->getAllocKind();
MOZ_ASSERT(!CanReuseScriptForClone(cx->compartment(), selfHostedFunction, cx->global()));
Rooted<LexicalEnvironmentObject*> globalLexical(cx, &cx->global()->lexicalEnvironment());
RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical, emptyGlobalScope,
kind);
// To be able to re-lazify the cloned function, its name in the
// self-hosting compartment has to be stored on the clone.
if (clone && hasName) {
clone->as<JSFunction>().setExtendedSlot(LAZY_FUNCTION_NAME_SLOT,
StringValue(selfHostedFunction->explicitName()));
// Arrow functions use the first extended slot for their lexical |this| value.
MOZ_ASSERT(!selfHostedFunction->isArrow());
js::gc::AllocKind kind = hasName
? gc::AllocKind::FUNCTION_EXTENDED
: selfHostedFunction->getAllocKind();
Handle<GlobalObject*> global = cx->global();
Rooted<LexicalEnvironmentObject*> globalLexical(cx, &global->lexicalEnvironment());
RootedScope emptyGlobalScope(cx, &global->emptyGlobalScope());
MOZ_ASSERT(!CanReuseScriptForClone(cx->compartment(), selfHostedFunction, global));
clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical, emptyGlobalScope,
kind);
// To be able to re-lazify the cloned function, its name in the
// self-hosting compartment has to be stored on the clone.
if (clone && hasName) {
clone->as<JSFunction>().setExtendedSlot(LAZY_FUNCTION_NAME_SLOT,
StringValue(selfHostedFunction->explicitName()));
}
} else {
clone = CloneSelfHostingIntrinsic(cx, selfHostedFunction);
}
} else if (selfHostedObject->is<RegExpObject>()) {
RegExpObject& reobj = selfHostedObject->as<RegExpObject>();