Home | History | Annotate | Download | only in webkit
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions
      6 // are met:
      7 // 1.  Redistributions of source code must retain the above copyright
      8 //     notice, this list of conditions and the following disclaimer.
      9 // 2.  Redistributions in binary form must reproduce the above copyright
     10 //     notice, this list of conditions and the following disclaimer in the
     11 //     documentation and/or other materials provided with the distribution.
     12 //
     13 // THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16 // DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23 
     24 description(
     25 "This tests that register allocation still works under register pressure induced by inlining, out-of-line function calls (i.e. unconditional register flushing), and slow paths for object creation (i.e. conditional register flushing)."
     26 );
     27 
     28 // Inlineable constructor.
     29 function foo(a, b, c) {
     30     this.a = a;
     31     this.b = b;
     32     this.c = c;
     33 }
     34 
     35 // Non-inlineable function. This relies on a size limit for inlining, but still
     36 // produces integers. It also relies on the VM not reasoning about Math.log deeply
     37 // enough to find some way of optimizing this code to be small enough to inline.
     38 function bar(a, b) {
     39     a += b;
     40     a -= b;
     41     b ^= a;
     42     a += Math.log(b);
     43     b += a;
     44     b -= a;
     45     a ^= b;
     46     a += b;
     47     a -= b;
     48     b ^= a;
     49     a += Math.log(b);
     50     b += a;
     51     b -= a;
     52     a ^= b;
     53     a += b;
     54     a -= b;
     55     b ^= a;
     56     a += Math.log(b);
     57     b += a;
     58     b -= a;
     59     a ^= b;
     60     a += b;
     61     a -= b;
     62     b ^= a;
     63     a += Math.log(b);
     64     b += a;
     65     b -= a;
     66     a ^= b;
     67     a += b;
     68     a -= b;
     69     b ^= a;
     70     a += Math.log(b);
     71     b += a;
     72     b -= a;
     73     a ^= b;
     74     a += b;
     75     a -= b;
     76     b ^= a;
     77     a += Math.log(b);
     78     b += a;
     79     b -= a;
     80     a ^= b;
     81     a += b;
     82     a -= b;
     83     b ^= a;
     84     a += Math.log(b);
     85     b += a;
     86     b -= a;
     87     a ^= b;
     88     a += b;
     89     a -= b;
     90     b ^= a;
     91     a += Math.log(b);
     92     b += a;
     93     b -= a;
     94     a ^= b;
     95     a += b;
     96     a -= b;
     97     b ^= a;
     98     a += Math.log(b);
     99     b += a;
    100     b -= a;
    101     a ^= b;
    102     a += b;
    103     a -= b;
    104     b ^= a;
    105     a += Math.log(b);
    106     b += a;
    107     b -= a;
    108     a ^= b;
    109     a += b;
    110     a -= b;
    111     b ^= a;
    112     a += Math.log(b);
    113     b += a;
    114     b -= a;
    115     a ^= b;
    116     a += b;
    117     a -= b;
    118     b ^= a;
    119     a += Math.log(b);
    120     b += a;
    121     b -= a;
    122     a ^= b;
    123     a += b;
    124     a -= b;
    125     b ^= a;
    126     a += Math.log(b);
    127     b += a;
    128     b -= a;
    129     a ^= b;
    130     a += b;
    131     a -= b;
    132     b ^= a;
    133     a += Math.log(b);
    134     b += a;
    135     b -= a;
    136     a ^= b;
    137     a += b;
    138     a -= b;
    139     b ^= a;
    140     a += Math.log(b);
    141     b += a;
    142     b -= a;
    143     a ^= b;
    144     a += b;
    145     a -= b;
    146     b ^= a;
    147     a += Math.log(b);
    148     b += a;
    149     b -= a;
    150     a ^= b;
    151     return (a - b) | 0;
    152 }
    153 
    154 // Function into which we will inline foo but not bar.
    155 function baz(a, b) {
    156     return new foo(bar(2 * a + 1, b - 1), bar(2 * a, b - 1), a);
    157 }
    158 
    159 // Do the test. It's crucial that o.a, o.b, and o.c are checked on each
    160 // loop iteration.
    161 for (var i = 0; i < 1000; ++i) {
    162     var o = baz(i, i + 1);
    163     shouldBe("o.a", "bar(2 * i + 1, i)");
    164     shouldBe("o.b", "bar(2 * i, i)");
    165     shouldBe("o.c", "i");
    166 }
    167