Source code
Revision control
Copy as Markdown
Other Tools
// Access property once.
function simple() {
var obj = {
get p() {
return 1;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
r += o.p;
}
assertEq(r, 200);
}
simple();
// Access property multiple times (consecutive) to test that MGuardHasGetterSetter
// ops can be merged.
function consecutive() {
var obj = {
get p() {
return 1;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
r += o.p;
r += o.p;
r += o.p;
r += o.p;
}
assertEq(r, 4 * 200);
}
consecutive();
// Access property multiple times (loop) to test LICM.
function loop() {
var obj = {
get p() {
return 1;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
for (var j = 0; j < 5; ++j) {
r += o.p;
}
}
assertEq(r, 5 * 200);
}
loop();
// Bailout when prototype changes.
function modifyProto() {
var obj = {
get p() {
return 1;
}
};
var obj2 = {
get p() {
return 2;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
r += o.p;
// Always execute Object.setPrototypeOf() to avoid cold code bailouts,
// which would happen for conditional code like if-statements. But only
// actually change |o|'s prototype once.
var j = (i === 100) | 0;
var q = [{}, o][j];
Object.setPrototypeOf(q, obj2);
r += o.p;
}
assertEq(r, 2 * 200 + Math.floor(100 / 8) * 2 + 1);
}
modifyProto();
// Bailout when property is changed to own data property.
function modifyToOwnValue() {
var obj = {
get p() {
return 1;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
r += o.p;
// Always execute Object.setPrototypeOf() to avoid cold code bailouts,
// which would happen for conditional code like if-statements. But only
// actually change |o|'s prototype once.
var j = (i === 100) | 0;
var q = [{}, o][j];
Object.defineProperty(q, "p", {value: 2});
r += o.p;
}
assertEq(r, 2 * 200 + Math.floor(100 / 8) * 2 + 1);
}
modifyToOwnValue();
// Bailout when property is changed to own accessor property.
function modifyToOwnAccessor() {
var obj = {
get p() {
return 1;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
r += o.p;
// Always execute Object.setPrototypeOf() to avoid cold code bailouts,
// which would happen for conditional code like if-statements. But only
// actually change |o|'s prototype once.
var j = (i === 100) | 0;
var q = [{}, o][j];
Object.defineProperty(q, "p", {get() { return 2; }});
r += o.p;
}
assertEq(r, 2 * 200 + Math.floor(100 / 8) * 2 + 1);
}
modifyToOwnAccessor();
// Bailout when changing accessor.
function modifyProtoAccessor() {
var obj = {
get p() {
return 1;
}
};
// Use objects with different shapes to enter megamorphic state for
// the JSOp::GetProp opcode.
var array = [
Object.create(obj, {a: {value: 1}}),
Object.create(obj, {b: {value: 2}}),
Object.create(obj, {c: {value: 3}}),
Object.create(obj, {d: {value: 4}}),
Object.create(obj, {e: {value: 5}}),
Object.create(obj, {f: {value: 6}}),
Object.create(obj, {g: {value: 7}}),
Object.create(obj, {h: {value: 8}}),
];
var r = 0;
for (var i = 0; i < 200; ++i) {
var o = array[i & 7];
r += o.p;
// Always execute Object.setPrototypeOf() to avoid cold code bailouts,
// which would happen for conditional code like if-statements. But only
// actually change |o|'s prototype once.
var j = (i === 100) | 0;
var q = [{}, obj][j];
Object.defineProperty(q, "p", {get() { return 2; }});
r += o.p;
}
assertEq(r, 2 * 200 + 100 * 2 - 1);
}
modifyProtoAccessor();