Home | History | Annotate | Download | only in mjsunit
      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 });
    312