1 // Copyright 2014 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 29 30 var global = this; 31 32 // For the HConstant 33 Array.prototype.fun = function() { 34 funRecv = this; 35 called++; 36 assertEquals(0, arguments.length); 37 }; 38 39 Array.prototype.funStrict = function() { 40 "use strict"; 41 funStrictRecv = this; 42 called++; 43 assertEquals(0, arguments.length); 44 }; 45 46 Array.prototype.manyArgs = function() { 47 "use strict"; 48 assertEquals(5, arguments.length); 49 assertEquals(0, this); 50 assertEquals(5, arguments[4]); 51 called++; 52 } 53 54 Array.prototype.manyArgsSloppy = function() { 55 assertEquals(global, this); 56 assertEquals(5, arguments.length); 57 assertEquals(5, arguments[4]); 58 called++; 59 } 60 61 var array = []; 62 for (var i = 0; i < 100; ++i) { 63 array[i] = i; 64 } 65 66 var copy = array.slice(); 67 68 function unshiftsArray(num) { 69 [].unshift.call(array, num); 70 } 71 72 unshiftsArray(50); 73 unshiftsArray(60); 74 %OptimizeFunctionOnNextCall(unshiftsArray); 75 unshiftsArray(80); 76 unshiftsArray(50); 77 unshiftsArray(60); 78 79 copy.unshift(50); 80 copy.unshift(60); 81 copy.unshift(80); 82 copy.unshift(50); 83 copy.unshift(60); 84 85 assertOptimized(unshiftsArray); 86 assertArrayEquals(array, copy); 87 88 89 var called = 0; 90 var funRecv; 91 92 function callNoArgs() { 93 [].fun.call(); 94 } 95 96 callNoArgs(); 97 callNoArgs(); 98 assertEquals(this, funRecv); 99 %OptimizeFunctionOnNextCall(callNoArgs); 100 callNoArgs(); 101 assertEquals(this, funRecv); 102 assertEquals(3, called); 103 assertOptimized(callNoArgs); 104 105 var funStrictRecv; 106 called = 0; 107 108 function callStrictNoArgs() { 109 [].funStrict.call(); 110 } 111 112 callStrictNoArgs(); 113 callStrictNoArgs(); 114 assertEquals(undefined, funStrictRecv); 115 %OptimizeFunctionOnNextCall(callStrictNoArgs); 116 callStrictNoArgs(); 117 assertEquals(undefined, funStrictRecv); 118 assertEquals(3, called); 119 assertOptimized(callStrictNoArgs); 120 121 called = 0; 122 123 124 function callManyArgs() { 125 [].manyArgs.call(0, 1, 2, 3, 4, 5); 126 } 127 128 callManyArgs(); 129 callManyArgs(); 130 %OptimizeFunctionOnNextCall(callManyArgs); 131 callManyArgs(); 132 assertOptimized(callManyArgs); 133 assertEquals(called, 3); 134 135 called = 0; 136 137 138 function callManyArgsSloppy() { 139 [].manyArgsSloppy.call(null, 1, 2, 3, 4, 5); 140 } 141 142 callManyArgsSloppy(); 143 callManyArgsSloppy(); 144 %OptimizeFunctionOnNextCall(callManyArgsSloppy); 145 callManyArgsSloppy(); 146 assertOptimized(callManyArgsSloppy); 147 assertEquals(called, 3); 148 149 var str = "hello"; 150 var code = str.charCodeAt(3); 151 called = 0; 152 function callBuiltinIndirectly() { 153 called++; 154 return "".charCodeAt.call(str, 3); 155 } 156 157 callBuiltinIndirectly(); 158 callBuiltinIndirectly(); 159 %OptimizeFunctionOnNextCall(callBuiltinIndirectly); 160 assertEquals(code, callBuiltinIndirectly()); 161 assertOptimized(callBuiltinIndirectly); 162 assertEquals(3, called); 163 164 this.array = [1,2,3,4,5,6,7,8,9]; 165 var copy = this.array.slice(); 166 called = 0; 167 168 function callInlineableBuiltinIndirectlyWhileInlined() { 169 called++; 170 return [].push.apply(array, arguments); 171 } 172 173 function callInlined(num) { 174 return callInlineableBuiltinIndirectlyWhileInlined(num); 175 } 176 177 callInlineableBuiltinIndirectlyWhileInlined(1); 178 callInlineableBuiltinIndirectlyWhileInlined(2); 179 %OptimizeFunctionOnNextCall(callInlineableBuiltinIndirectlyWhileInlined); 180 callInlineableBuiltinIndirectlyWhileInlined(3); 181 assertOptimized(callInlineableBuiltinIndirectlyWhileInlined); 182 183 callInlined(1); 184 callInlined(2); 185 %OptimizeFunctionOnNextCall(callInlined); 186 callInlined(3); 187 copy.push(1, 2, 3, 1, 2, 3); 188 assertOptimized(callInlined); 189 assertArrayEquals(copy, this.array); 190 assertEquals(6, called); 191