summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/warp/guard-has-getter-setter.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/warp/guard-has-getter-setter.js')
-rw-r--r--js/src/jit-test/tests/warp/guard-has-getter-setter.js263
1 files changed, 263 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/warp/guard-has-getter-setter.js b/js/src/jit-test/tests/warp/guard-has-getter-setter.js
new file mode 100644
index 0000000000..dc4b1d9ebd
--- /dev/null
+++ b/js/src/jit-test/tests/warp/guard-has-getter-setter.js
@@ -0,0 +1,263 @@
+// 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();