guard-has-getter-setter.js (6555B)
1 // Access property once. 2 function simple() { 3 var obj = { 4 get p() { 5 return 1; 6 } 7 }; 8 9 // Use objects with different shapes to enter megamorphic state for 10 // the JSOp::GetProp opcode. 11 var array = [ 12 Object.create(obj, {a: {value: 1}}), 13 Object.create(obj, {b: {value: 2}}), 14 Object.create(obj, {c: {value: 3}}), 15 Object.create(obj, {d: {value: 4}}), 16 Object.create(obj, {e: {value: 5}}), 17 Object.create(obj, {f: {value: 6}}), 18 Object.create(obj, {g: {value: 7}}), 19 Object.create(obj, {h: {value: 8}}), 20 ]; 21 22 var r = 0; 23 for (var i = 0; i < 200; ++i) { 24 var o = array[i & 7]; 25 r += o.p; 26 } 27 assertEq(r, 200); 28 } 29 simple(); 30 31 // Access property multiple times (consecutive) to test that MGuardHasGetterSetter 32 // ops can be merged. 33 function consecutive() { 34 var obj = { 35 get p() { 36 return 1; 37 } 38 }; 39 40 // Use objects with different shapes to enter megamorphic state for 41 // the JSOp::GetProp opcode. 42 var array = [ 43 Object.create(obj, {a: {value: 1}}), 44 Object.create(obj, {b: {value: 2}}), 45 Object.create(obj, {c: {value: 3}}), 46 Object.create(obj, {d: {value: 4}}), 47 Object.create(obj, {e: {value: 5}}), 48 Object.create(obj, {f: {value: 6}}), 49 Object.create(obj, {g: {value: 7}}), 50 Object.create(obj, {h: {value: 8}}), 51 ]; 52 53 var r = 0; 54 for (var i = 0; i < 200; ++i) { 55 var o = array[i & 7]; 56 57 r += o.p; 58 r += o.p; 59 r += o.p; 60 r += o.p; 61 } 62 assertEq(r, 4 * 200); 63 } 64 consecutive(); 65 66 // Access property multiple times (loop) to test LICM. 67 function loop() { 68 var obj = { 69 get p() { 70 return 1; 71 } 72 }; 73 74 // Use objects with different shapes to enter megamorphic state for 75 // the JSOp::GetProp opcode. 76 var array = [ 77 Object.create(obj, {a: {value: 1}}), 78 Object.create(obj, {b: {value: 2}}), 79 Object.create(obj, {c: {value: 3}}), 80 Object.create(obj, {d: {value: 4}}), 81 Object.create(obj, {e: {value: 5}}), 82 Object.create(obj, {f: {value: 6}}), 83 Object.create(obj, {g: {value: 7}}), 84 Object.create(obj, {h: {value: 8}}), 85 ]; 86 87 var r = 0; 88 for (var i = 0; i < 200; ++i) { 89 var o = array[i & 7]; 90 91 for (var j = 0; j < 5; ++j) { 92 r += o.p; 93 } 94 } 95 assertEq(r, 5 * 200); 96 } 97 loop(); 98 99 // Bailout when prototype changes. 100 function modifyProto() { 101 var obj = { 102 get p() { 103 return 1; 104 } 105 }; 106 107 var obj2 = { 108 get p() { 109 return 2; 110 } 111 }; 112 113 // Use objects with different shapes to enter megamorphic state for 114 // the JSOp::GetProp opcode. 115 var array = [ 116 Object.create(obj, {a: {value: 1}}), 117 Object.create(obj, {b: {value: 2}}), 118 Object.create(obj, {c: {value: 3}}), 119 Object.create(obj, {d: {value: 4}}), 120 Object.create(obj, {e: {value: 5}}), 121 Object.create(obj, {f: {value: 6}}), 122 Object.create(obj, {g: {value: 7}}), 123 Object.create(obj, {h: {value: 8}}), 124 ]; 125 126 var r = 0; 127 for (var i = 0; i < 200; ++i) { 128 var o = array[i & 7]; 129 130 r += o.p; 131 132 // Always execute Object.setPrototypeOf() to avoid cold code bailouts, 133 // which would happen for conditional code like if-statements. But only 134 // actually change |o|'s prototype once. 135 var j = (i === 100) | 0; 136 var q = [{}, o][j]; 137 Object.setPrototypeOf(q, obj2); 138 139 r += o.p; 140 } 141 assertEq(r, 2 * 200 + Math.floor(100 / 8) * 2 + 1); 142 } 143 modifyProto(); 144 145 // Bailout when property is changed to own data property. 146 function modifyToOwnValue() { 147 var obj = { 148 get p() { 149 return 1; 150 } 151 }; 152 153 // Use objects with different shapes to enter megamorphic state for 154 // the JSOp::GetProp opcode. 155 var array = [ 156 Object.create(obj, {a: {value: 1}}), 157 Object.create(obj, {b: {value: 2}}), 158 Object.create(obj, {c: {value: 3}}), 159 Object.create(obj, {d: {value: 4}}), 160 Object.create(obj, {e: {value: 5}}), 161 Object.create(obj, {f: {value: 6}}), 162 Object.create(obj, {g: {value: 7}}), 163 Object.create(obj, {h: {value: 8}}), 164 ]; 165 166 var r = 0; 167 for (var i = 0; i < 200; ++i) { 168 var o = array[i & 7]; 169 170 r += o.p; 171 172 // Always execute Object.setPrototypeOf() to avoid cold code bailouts, 173 // which would happen for conditional code like if-statements. But only 174 // actually change |o|'s prototype once. 175 var j = (i === 100) | 0; 176 var q = [{}, o][j]; 177 Object.defineProperty(q, "p", {value: 2}); 178 179 r += o.p; 180 } 181 assertEq(r, 2 * 200 + Math.floor(100 / 8) * 2 + 1); 182 } 183 modifyToOwnValue(); 184 185 // Bailout when property is changed to own accessor property. 186 function modifyToOwnAccessor() { 187 var obj = { 188 get p() { 189 return 1; 190 } 191 }; 192 193 // Use objects with different shapes to enter megamorphic state for 194 // the JSOp::GetProp opcode. 195 var array = [ 196 Object.create(obj, {a: {value: 1}}), 197 Object.create(obj, {b: {value: 2}}), 198 Object.create(obj, {c: {value: 3}}), 199 Object.create(obj, {d: {value: 4}}), 200 Object.create(obj, {e: {value: 5}}), 201 Object.create(obj, {f: {value: 6}}), 202 Object.create(obj, {g: {value: 7}}), 203 Object.create(obj, {h: {value: 8}}), 204 ]; 205 206 var r = 0; 207 for (var i = 0; i < 200; ++i) { 208 var o = array[i & 7]; 209 210 r += o.p; 211 212 // Always execute Object.setPrototypeOf() to avoid cold code bailouts, 213 // which would happen for conditional code like if-statements. But only 214 // actually change |o|'s prototype once. 215 var j = (i === 100) | 0; 216 var q = [{}, o][j]; 217 Object.defineProperty(q, "p", {get() { return 2; }}); 218 219 r += o.p; 220 } 221 assertEq(r, 2 * 200 + Math.floor(100 / 8) * 2 + 1); 222 } 223 modifyToOwnAccessor(); 224 225 // Bailout when changing accessor. 226 function modifyProtoAccessor() { 227 var obj = { 228 get p() { 229 return 1; 230 } 231 }; 232 233 // Use objects with different shapes to enter megamorphic state for 234 // the JSOp::GetProp opcode. 235 var array = [ 236 Object.create(obj, {a: {value: 1}}), 237 Object.create(obj, {b: {value: 2}}), 238 Object.create(obj, {c: {value: 3}}), 239 Object.create(obj, {d: {value: 4}}), 240 Object.create(obj, {e: {value: 5}}), 241 Object.create(obj, {f: {value: 6}}), 242 Object.create(obj, {g: {value: 7}}), 243 Object.create(obj, {h: {value: 8}}), 244 ]; 245 246 var r = 0; 247 for (var i = 0; i < 200; ++i) { 248 var o = array[i & 7]; 249 250 r += o.p; 251 252 // Always execute Object.setPrototypeOf() to avoid cold code bailouts, 253 // which would happen for conditional code like if-statements. But only 254 // actually change |o|'s prototype once. 255 var j = (i === 100) | 0; 256 var q = [{}, obj][j]; 257 Object.defineProperty(q, "p", {get() { return 2; }}); 258 259 r += o.p; 260 } 261 assertEq(r, 2 * 200 + 100 * 2 - 1); 262 } 263 modifyProtoAccessor();