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