| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-ayle license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Flags: --allow-natives-syntax --track-fields --expose-gc | |
| 6 | |
| 7 var global = Function('return this')(); | |
| 8 var verbose = 0; | |
| 9 | |
| 10 function test(ctor_desc, use_desc, migr_desc) { | |
| 11 var n = 5; | |
| 12 var objects = []; | |
| 13 var results = []; | |
| 14 | |
| 15 if (verbose) { | |
| 16 print(); | |
| 17 print("==========================================================="); | |
| 18 print("=== " + ctor_desc.name + | |
| 19 " | " + use_desc.name + " |--> " + migr_desc.name); | |
| 20 print("==========================================================="); | |
| 21 } | |
| 22 | |
| 23 // Clean ICs and transitions. | |
| 24 %NotifyContextDisposed(); | |
| 25 gc(); gc(); gc(); | |
| 26 | |
| 27 | |
| 28 // create objects | |
| 29 if (verbose) { | |
| 30 print("-----------------------------"); | |
| 31 print("--- construct"); | |
| 32 print(); | |
| 33 } | |
| 34 for (var i = 0; i < n; i++) { | |
| 35 objects[i] = ctor_desc.ctor.apply(ctor_desc, ctor_desc.args(i)); | |
| 36 } | |
| 37 | |
| 38 try { | |
| 39 // use them | |
| 40 if (verbose) { | |
| 41 print("-----------------------------"); | |
| 42 print("--- use 1"); | |
| 43 print(); | |
| 44 } | |
| 45 var use = use_desc.use1; | |
| 46 for (var i = 0; i < n; i++) { | |
| 47 if (i == 3) %OptimizeFunctionOnNextCall(use); | |
| 48 results[i] = use(objects[i], i); | |
| 49 } | |
| 50 | |
| 51 // trigger migrations | |
| 52 if (verbose) { | |
| 53 print("-----------------------------"); | |
| 54 print("--- trigger migration"); | |
| 55 print(); | |
| 56 } | |
| 57 var migr = migr_desc.migr; | |
| 58 for (var i = 0; i < n; i++) { | |
| 59 if (i == 3) %OptimizeFunctionOnNextCall(migr); | |
| 60 migr(objects[i], i); | |
| 61 } | |
| 62 | |
| 63 // use again | |
| 64 if (verbose) { | |
| 65 print("-----------------------------"); | |
| 66 print("--- use 2"); | |
| 67 print(); | |
| 68 } | |
| 69 var use = use_desc.use2 !== undefined ? use_desc.use2 : use_desc.use1; | |
| 70 for (var i = 0; i < n; i++) { | |
| 71 if (i == 3) %OptimizeFunctionOnNextCall(use); | |
| 72 results[i] = use(objects[i], i); | |
| 73 if (verbose >= 2) print(results[i]); | |
| 74 } | |
| 75 | |
| 76 } catch (e) { | |
| 77 if (verbose) print("--- incompatible use: " + e); | |
| 78 } | |
| 79 return results; | |
| 80 } | |
| 81 | |
| 82 | |
| 83 var ctors = [ | |
| 84 { | |
| 85 name: "none-to-double", | |
| 86 ctor: function(v) { return {a: v}; }, | |
| 87 args: function(i) { return [1.5 + i]; }, | |
| 88 }, | |
| 89 { | |
| 90 name: "double", | |
| 91 ctor: function(v) { var o = {}; o.a = v; return o; }, | |
| 92 args: function(i) { return [1.5 + i]; }, | |
| 93 }, | |
| 94 { | |
| 95 name: "none-to-smi", | |
| 96 ctor: function(v) { return {a: v}; }, | |
| 97 args: function(i) { return [i]; }, | |
| 98 }, | |
| 99 { | |
| 100 name: "smi", | |
| 101 ctor: function(v) { var o = {}; o.a = v; return o; }, | |
| 102 args: function(i) { return [i]; }, | |
| 103 }, | |
| 104 { | |
| 105 name: "none-to-object", | |
| 106 ctor: function(v) { return {a: v}; }, | |
| 107 args: function(i) { return ["s"]; }, | |
| 108 }, | |
| 109 { | |
| 110 name: "object", | |
| 111 ctor: function(v) { var o = {}; o.a = v; return o; }, | |
| 112 args: function(i) { return ["s"]; }, | |
| 113 }, | |
| 114 { | |
| 115 name: "{a:, b:, c:}", | |
| 116 ctor: function(v1, v2, v3) { return {a: v1, b: v2, c: v3}; }, | |
| 117 args: function(i) { return [1.5 + i, 1.6, 1.7]; }, | |
| 118 }, | |
| 119 { | |
| 120 name: "{a..h:}", | |
| 121 ctor: function(v) { var o = {}; o.h=o.g=o.f=o.e=o.d=o.c=o.b=o.a=v; return o;
}, | |
| 122 args: function(i) { return [1.5 + i]; }, | |
| 123 }, | |
| 124 { | |
| 125 name: "1", | |
| 126 ctor: function(v) { var o = 1; o.a = v; return o; }, | |
| 127 args: function(i) { return [1.5 + i]; }, | |
| 128 }, | |
| 129 { | |
| 130 name: "f()", | |
| 131 ctor: function(v) { var o = function() { return v;}; o.a = v; return o; }, | |
| 132 args: function(i) { return [1.5 + i]; }, | |
| 133 }, | |
| 134 { | |
| 135 name: "f().bind", | |
| 136 ctor: function(v) { var o = function(a,b,c) { return a+b+c; }; o = o.bind(o,
v, v+1, v+2.2); return o; }, | |
| 137 args: function(i) { return [1.5 + i]; }, | |
| 138 }, | |
| 139 { | |
| 140 name: "dictionary elements", | |
| 141 ctor: function(v) { var o = []; o[1] = v; o[200000] = v; return o; }, | |
| 142 args: function(i) { return [1.5 + i]; }, | |
| 143 }, | |
| 144 { | |
| 145 name: "json", | |
| 146 ctor: function(v) { var json = '{"a":' + v + ',"b":' + v + '}'; return JSON.
parse(json); }, | |
| 147 args: function(i) { return [1.5 + i]; }, | |
| 148 }, | |
| 149 { | |
| 150 name: "fast accessors", | |
| 151 accessor: { | |
| 152 get: function() { return this.a_; }, | |
| 153 set: function(value) {this.a_ = value; }, | |
| 154 configurable: true, | |
| 155 }, | |
| 156 ctor: function(v) { | |
| 157 var o = {a_:v}; | |
| 158 Object.defineProperty(o, "a", this.accessor); | |
| 159 return o; | |
| 160 }, | |
| 161 args: function(i) { return [1.5 + i]; }, | |
| 162 }, | |
| 163 { | |
| 164 name: "slow accessor", | |
| 165 accessor1: { value: this.a_, configurable: true }, | |
| 166 accessor2: { | |
| 167 get: function() { return this.a_; }, | |
| 168 set: function(value) {this.a_ = value; }, | |
| 169 configurable: true, | |
| 170 }, | |
| 171 ctor: function(v) { | |
| 172 var o = {a_:v}; | |
| 173 Object.defineProperty(o, "a", this.accessor1); | |
| 174 Object.defineProperty(o, "a", this.accessor2); | |
| 175 return o; | |
| 176 }, | |
| 177 args: function(i) { return [1.5 + i]; }, | |
| 178 }, | |
| 179 { | |
| 180 name: "slow", | |
| 181 proto: {}, | |
| 182 ctor: function(v) { | |
| 183 var o = {__proto__: this.proto}; | |
| 184 o.a = v; | |
| 185 for (var i = 0; %HasFastProperties(o); i++) o["f"+i] = v; | |
| 186 return o; | |
| 187 }, | |
| 188 args: function(i) { return [1.5 + i]; }, | |
| 189 }, | |
| 190 { | |
| 191 name: "global", | |
| 192 ctor: function(v) { return global; }, | |
| 193 args: function(i) { return [i]; }, | |
| 194 }, | |
| 195 ]; | |
| 196 | |
| 197 | |
| 198 | |
| 199 var uses = [ | |
| 200 { | |
| 201 name: "o.a+1.0", | |
| 202 use1: function(o, i) { return o.a + 1.0; }, | |
| 203 use2: function(o, i) { return o.a + 1.1; }, | |
| 204 }, | |
| 205 { | |
| 206 name: "o.b+1.0", | |
| 207 use1: function(o, i) { return o.b + 1.0; }, | |
| 208 use2: function(o, i) { return o.b + 1.1; }, | |
| 209 }, | |
| 210 { | |
| 211 name: "o[1]+1.0", | |
| 212 use1: function(o, i) { return o[1] + 1.0; }, | |
| 213 use2: function(o, i) { return o[1] + 1.1; }, | |
| 214 }, | |
| 215 { | |
| 216 name: "o[-1]+1.0", | |
| 217 use1: function(o, i) { return o[-1] + 1.0; }, | |
| 218 use2: function(o, i) { return o[-1] + 1.1; }, | |
| 219 }, | |
| 220 { | |
| 221 name: "()", | |
| 222 use1: function(o, i) { return o() + 1.0; }, | |
| 223 use2: function(o, i) { return o() + 1.1; }, | |
| 224 }, | |
| 225 ]; | |
| 226 | |
| 227 | |
| 228 | |
| 229 var migrations = [ | |
| 230 { | |
| 231 name: "to smi", | |
| 232 migr: function(o, i) { if (i == 0) o.a = 1; }, | |
| 233 }, | |
| 234 { | |
| 235 name: "to double", | |
| 236 migr: function(o, i) { if (i == 0) o.a = 1.1; }, | |
| 237 }, | |
| 238 { | |
| 239 name: "to object", | |
| 240 migr: function(o, i) { if (i == 0) o.a = {}; }, | |
| 241 }, | |
| 242 { | |
| 243 name: "set prototype {}", | |
| 244 migr: function(o, i) { o.__proto__ = {}; }, | |
| 245 }, | |
| 246 { | |
| 247 name: "%FunctionSetPrototype", | |
| 248 migr: function(o, i) { %FunctionSetPrototype(o, null); }, | |
| 249 }, | |
| 250 { | |
| 251 name: "modify prototype", | |
| 252 migr: function(o, i) { if (i == 0) o.__proto__.__proto1__ = [,,,5,,,]; }, | |
| 253 }, | |
| 254 { | |
| 255 name: "freeze prototype", | |
| 256 migr: function(o, i) { if (i == 0) Object.freeze(o.__proto__); }, | |
| 257 }, | |
| 258 { | |
| 259 name: "delete and re-add property", | |
| 260 migr: function(o, i) { var v = o.a; delete o.a; o.a = v; }, | |
| 261 }, | |
| 262 { | |
| 263 name: "modify prototype", | |
| 264 migr: function(o, i) { if (i >= 0) o.__proto__ = {}; }, | |
| 265 }, | |
| 266 { | |
| 267 name: "set property callback", | |
| 268 migr: function(o, i) { | |
| 269 Object.defineProperty(o, "a", { | |
| 270 get: function() { return 1.5 + i; }, | |
| 271 set: function(value) {}, | |
| 272 configurable: true, | |
| 273 }); | |
| 274 }, | |
| 275 }, | |
| 276 { | |
| 277 name: "observe", | |
| 278 migr: function(o, i) { Object.observe(o, function(){}); }, | |
| 279 }, | |
| 280 { | |
| 281 name: "%EnableAccessChecks", | |
| 282 migr: function(o, i) { %EnableAccessChecks(o); }, | |
| 283 }, | |
| 284 { | |
| 285 name: "%DisableAccessChecks", | |
| 286 migr: function(o, i) { if (o !== global) %DisableAccessChecks(o); }, | |
| 287 }, | |
| 288 { | |
| 289 name: "seal", | |
| 290 migr: function(o, i) { Object.seal(o); }, | |
| 291 }, | |
| 292 { // Must be the last in the sequence, because after the global object freeze | |
| 293 // the other modifications does not make sence. | |
| 294 name: "freeze", | |
| 295 migr: function(o, i) { Object.freeze(o); }, | |
| 296 }, | |
| 297 ]; | |
| 298 | |
| 299 | |
| 300 | |
| 301 migrations.forEach(function(migr) { | |
| 302 uses.forEach(function(use) { | |
| 303 ctors.forEach(function(ctor) { | |
| 304 test(ctor, use, migr); | |
| 305 }); | |
| 306 }); | |
| 307 }); | |
| OLD | NEW |