Bug 1919217 part 2 - Support non-wrapper proxies in MacroAssembler::branchIfObjectEmulatesUndefined. r=anba

This eliminates a few hundred thousand calls to `js::EmulatesUndefined` on Speedometer 3.

Differential Revision: https://phabricator.services.mozilla.com/D222428
This commit is contained in:
Jan de Mooij 2024-09-18 14:37:11 +00:00
Родитель 69188d7421
Коммит ce133eb070
2 изменённых файлов: 54 добавлений и 4 удалений

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

@ -0,0 +1,48 @@
function testMixed() {
var global = newGlobal({newCompartment: true});
var wrapperEmulatesUndefined = global.evaluate("createIsHTMLDDA()");
var wrapperPlain = global.evaluate("({})");
var arr = [
createIsHTMLDDA(),
wrapperEmulatesUndefined,
wrapperPlain,
this,
new Proxy({}, {})
];
var res = 0;
for (var i = 0; i < 100; i++) {
var val = arr[i % arr.length];
if (val) {
res++;
}
if (val == null) {
res++;
}
if (val != undefined) {
res++;
}
}
assertEq(res, 160);
}
testMixed();
function testNonWrapperProxy() {
var proxies = [new Proxy({}, {}), new Proxy({}, {})];
var res = 0;
for (var i = 0; i < 100; i++) {
var val = proxies[i % proxies.length];
if (val) {
res++;
}
if (val == null) {
throw "failure";
}
if (val != undefined) {
res++;
}
}
assertEq(res, 200);
}
testNonWrapperProxy();

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

@ -554,15 +554,17 @@ void MacroAssembler::branchIfObjectEmulatesUndefined(Register objReg,
scratch); scratch);
branchPtr(Assembler::Equal, scratch, ImmPtr(nullptr), &done); branchPtr(Assembler::Equal, scratch, ImmPtr(nullptr), &done);
// The branches to out-of-line code here implement a conservative version
// of the JSObject::isWrapper test performed in EmulatesUndefined.
loadObjClassUnsafe(objReg, scratch); loadObjClassUnsafe(objReg, scratch);
branchTestClassIsProxy(true, scratch, slowCheck);
Address flags(scratch, JSClass::offsetOfFlags()); Address flags(scratch, JSClass::offsetOfFlags());
branchTest32(Assembler::NonZero, flags, Imm32(JSCLASS_EMULATES_UNDEFINED), branchTest32(Assembler::NonZero, flags, Imm32(JSCLASS_EMULATES_UNDEFINED),
label); label);
// Call into C++ if the object is a wrapper.
branchTestClassIsProxy(false, scratch, &done);
branchTestProxyHandlerFamily(Assembler::Equal, objReg, scratch,
&Wrapper::family, slowCheck);
bind(&done); bind(&done);
} }