diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/jit-test/tests/basic/shape-teleporting-invalidation.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit-test/tests/basic/shape-teleporting-invalidation.js')
-rw-r--r-- | js/src/jit-test/tests/basic/shape-teleporting-invalidation.js | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/basic/shape-teleporting-invalidation.js b/js/src/jit-test/tests/basic/shape-teleporting-invalidation.js new file mode 100644 index 0000000000..37769bcb5a --- /dev/null +++ b/js/src/jit-test/tests/basic/shape-teleporting-invalidation.js @@ -0,0 +1,144 @@ +// The shape teleporting optimization can be disabled for an object that's used +// as prototype when either it's involved in prototype changes or it had a property +// shadowed on another prototype object. + +function changeProps(o) { + Object.assign(o, {x: 1, y: 2, z: 3}); + o.foo = 4; + delete o.x; +} + +function testProtoChange() { + var receiver = {}; + var A = Object.create(null); + var B = Object.create(A); + + // Change |receiver|'s proto: receiver => B => A => null + // Because |receiver| is not used as a prototype object, this doesn't affect + // teleporting. + Object.setPrototypeOf(receiver, B); + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(A), false); + assertEq(hasInvalidatedTeleporting(B), false); + + // Change B's proto to C: receiver => B => C => null + // Because B is used as prototype object, both A and B invalidate teleporting. + var C = Object.create(null); + Object.setPrototypeOf(B, C); + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(A), true); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(C), false); + + // Change B's proto a second time: receiver => B => D => null + // Now C has teleporting invalidated too. + var D = Object.create(null); + Object.setPrototypeOf(B, D); + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(A), true); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(C), true); + assertEq(hasInvalidatedTeleporting(D), false); + + // Changing properties (without shadowing) must not affect teleporting state. + changeProps(C); + changeProps(D); + assertEq(hasInvalidatedTeleporting(C), true); + assertEq(hasInvalidatedTeleporting(D), false); +} +testProtoChange(); + +function testShadowingProp() { + // receiver => C => B => A => null + var A = Object.create(null); + var B = Object.create(A); + var C = Object.create(B); + var receiver = Object.create(C); + + // Adding non-shadowing properties doesn't affect teleporting. + A.a = 1; + B.b = 1; + C.c = 1; + receiver.receiver = 1; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), false); + assertEq(hasInvalidatedTeleporting(A), false); + + // Objects not used as prototype can shadow properties without affecting + // teleporting. + receiver.a = 1; + receiver.b = 2; + receiver.c = 3; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), false); + assertEq(hasInvalidatedTeleporting(A), false); + + // Shadowing a property of B on C invalidates teleporting for B. + C.b = 1; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(A), false); + + // Shadowing a property of A on C invalidates teleporting for A. + C.a = 2; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(A), true); + + // Changing properties (without shadowing) must not affect teleporting state. + changeProps(C); + changeProps(B); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), true); +} +testShadowingProp(); + +function testShadowingPropStopsAtFirst() { + // receiver => C => B{x,y} => A{x,y,z} => null + var A = Object.create(null); + A.x = 1; + A.y = 2; + A.z = 3; + var B = Object.create(A); + B.x = 1; + B.y = 2; + var C = Object.create(B); + var receiver = Object.create(C); + + // Teleporting is supported. + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), false); + assertEq(hasInvalidatedTeleporting(A), false); + + // Shadowing a property of B (and A) on C. + // This invalidates teleporting for B but not for A, because the search stops + // at B. + C.x = 1; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(A), false); + + // "y" is similar. + C.y = 2; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(A), false); + + // "z" is only defined on A, so now A is affected. + C.z = 3; + assertEq(hasInvalidatedTeleporting(receiver), false); + assertEq(hasInvalidatedTeleporting(C), false); + assertEq(hasInvalidatedTeleporting(B), true); + assertEq(hasInvalidatedTeleporting(A), true); +} +testShadowingPropStopsAtFirst(); + +// Ensure teleporting properties on Object.prototype is still possible. +assertEq(hasInvalidatedTeleporting(Object.prototype), false); |