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) { |
| 283 if (typeof (o) !== 'function') %EnableAccessChecks(o); |
| 284 }, |
| 285 }, |
| 286 { |
| 287 name: "%DisableAccessChecks", |
| 288 migr: function(o, i) { |
| 289 if ((typeof (o) !== 'function') && (o !== global)) %DisableAccessChecks(o)
; |
| 290 }, |
| 291 }, |
| 292 { |
| 293 name: "seal", |
| 294 migr: function(o, i) { Object.seal(o); }, |
| 295 }, |
| 296 { // Must be the last in the sequence, because after the global object freeze |
| 297 // the other modifications does not make sence. |
| 298 name: "freeze", |
| 299 migr: function(o, i) { Object.freeze(o); }, |
| 300 }, |
| 301 ]; |
| 302 |
| 303 |
| 304 |
| 305 migrations.forEach(function(migr) { |
| 306 uses.forEach(function(use) { |
| 307 ctors.forEach(function(ctor) { |
| 308 test(ctor, use, migr); |
| 309 }); |
| 310 }); |
| 311 }); |
OLD | NEW |