Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 // Flags: --allow-natives-syntax --expose-gc
     29 // Flags: --noincremental-marking
     30 
     31 // Check that objects that are used for prototypes are in the fast mode.
     32 
     33 function Super() {
     34 }
     35 
     36 
     37 function Sub() {
     38 }
     39 
     40 
     41 function AddProps(obj) {
     42   for (var i = 0; i < 26; i++) {
     43     obj["x" + i] = 0;
     44   }
     45 }
     46 
     47 
     48 function DoProtoMagic(proto, set__proto__) {
     49   if (set__proto__) {
     50     (new Sub()).__proto__ = proto;
     51   } else {
     52     Sub.prototype = proto;
     53     // Need to instantiate Sub to mark .prototype as prototype.
     54     new Sub();
     55   }
     56 }
     57 
     58 
     59 function test(use_new, add_first, set__proto__, same_map_as) {
     60   var proto = use_new ? new Super() : {};
     61 
     62   // New object is fast.
     63   assertTrue(%HasFastProperties(proto));
     64 
     65   if (add_first) {
     66     AddProps(proto);
     67     // Adding this many properties makes it slow.
     68     assertFalse(%HasFastProperties(proto));
     69     DoProtoMagic(proto, set__proto__);
     70     // Making it a prototype makes it fast again.
     71     assertTrue(%HasFastProperties(proto));
     72   } else {
     73     DoProtoMagic(proto, set__proto__);
     74     // Still fast
     75     assertTrue(%HasFastProperties(proto));
     76     AddProps(proto);
     77     if (set__proto__) {
     78       // After we add all those properties it went slow mode again :-(
     79       assertFalse(%HasFastProperties(proto));
     80     } else {
     81       // .prototype keeps it fast.
     82       assertTrue(%HasFastProperties(proto));
     83     }
     84   }
     85   if (same_map_as && !add_first && set__proto__) {
     86     assertTrue(%HaveSameMap(same_map_as, proto));
     87   }
     88   return proto;
     89 }
     90 
     91 // TODO(mstarzinger): This test fails easily if gc happens at the wrong time.
     92 gc();
     93 
     94 for (var i = 0; i < 4; i++) {
     95   var set__proto__ = ((i & 1) != 0);
     96   var use_new = ((i & 2) != 0);
     97 
     98   test(use_new, true, set__proto__);
     99 
    100   var last = test(use_new, false, set__proto__);
    101   test(use_new, false, set__proto__, last);
    102 }
    103 
    104 
    105 var x = {a: 1, b: 2, c: 3};
    106 var o = { __proto__: x };
    107 assertTrue(%HasFastProperties(x));
    108 for (key in x) {
    109   assertTrue(key == 'a');
    110   break;
    111 }
    112 delete x.b;
    113 for (key in x) {
    114   assertTrue(key == 'a');
    115   break;
    116 }
    117 assertFalse(%HasFastProperties(x));
    118 x.d = 4;
    119 assertFalse(%HasFastProperties(x));
    120 for (key in x) {
    121   assertTrue(key == 'a');
    122   break;
    123 }
    124