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 30// Test uint32 handing in optimized frames. 31 32var K1 = 0x7fffffff; 33var K2 = 0xffffffff; 34 35var uint32_array = new Uint32Array(2); 36uint32_array[0] = K1; 37uint32_array[1] = K2; 38 39function ChangeI2T(arr, i) { 40 return uint32_array[i]; 41} 42 43assertEquals(K1, ChangeI2T(uint32_array, 0)); 44assertEquals(K2, ChangeI2T(uint32_array, 1)); 45%OptimizeFunctionOnNextCall(ChangeI2T); 46assertEquals(K1, ChangeI2T(uint32_array, 0)); 47// Loop to force inline allocation failure and a call into runtime. 48for (var i = 0; i < 80000; i++) { 49 assertEquals(K2, ChangeI2T(uint32_array, 1)); 50} 51 52function SideEffect() { 53 with ({}) { } // not inlinable 54} 55 56function Deopt(obj, arr, i) { 57 var x = arr[i]; 58 SideEffect(); // x will be used by HSimulate. 59 obj.x; 60 return x; 61} 62 63assertEquals(K1, Deopt({x: 0}, uint32_array, 0)); 64assertEquals(K2, Deopt({x: 0}, uint32_array, 1)); 65%OptimizeFunctionOnNextCall(Deopt); 66assertEquals(K2, Deopt({}, uint32_array, 1)); 67 68function ChangeI2D(arr) { 69 // This addition will have a double type feedback so ChangeI2D will 70 // be generated for its operands. 71 return arr[0] + arr[1]; 72} 73 74assertEquals(K1 + K2, ChangeI2D(uint32_array)); 75assertEquals(K1 + K2, ChangeI2D(uint32_array)); 76%OptimizeFunctionOnNextCall(ChangeI2D); 77assertEquals(K1 + K2, ChangeI2D(uint32_array)); 78 79function ShrShr(val) { 80 return (val >>> 0) >>> 1; 81} 82 83assertEquals(K1, ShrShr(K2 | 0)); 84assertEquals(K1, ShrShr(K2 | 0)); 85%OptimizeFunctionOnNextCall(ShrShr); 86assertEquals(K1, ShrShr(K2 | 0)); 87 88function SarShr(val) { 89 return val >> (-2 >>> 0); 90} 91 92var K3 = 0x80000000; 93assertEquals(-2, SarShr(K3 | 0)); 94assertEquals(-2, SarShr(K3 | 0)); 95%OptimizeFunctionOnNextCall(SarShr); 96assertEquals(-2, SarShr(K3 | 0)); 97 98function Uint32Phi(a, b, c) { 99 var i = a ? (b >>> 0) : (c >>> 0); 100 return (i | 0); 101} 102 103var K4 = 0x80000001; 104assertEquals(K3 | 0, Uint32Phi(true, K3, K4)); 105assertEquals(K4 | 0, Uint32Phi(false, K3, K4)); 106assertEquals(K3 | 0, Uint32Phi(true, K3, K4)); 107assertEquals(K4 | 0, Uint32Phi(false, K3, K4)); 108%OptimizeFunctionOnNextCall(Uint32Phi); 109assertEquals(K3 | 0, Uint32Phi(true, K3, K4)); 110assertEquals(K4 | 0, Uint32Phi(false, K3, K4)); 111 112function NonUint32Phi(a, b, c) { 113 var i = a ? (b >>> 0) : c; 114 return (i | 0); 115} 116 117assertEquals(K3 | 0, NonUint32Phi(true, K3, K4)); 118assertEquals(K4 | 0, NonUint32Phi(false, K3, K4)); 119assertEquals(K3 | 0, NonUint32Phi(true, K3, K4)); 120assertEquals(K4 | 0, NonUint32Phi(false, K3, K4)); 121%OptimizeFunctionOnNextCall(NonUint32Phi); 122assertEquals(K3 | 0, NonUint32Phi(true, K3, K4)); 123assertEquals(K4 | 0, NonUint32Phi(false, K3, K4)); 124 125function PhiOfPhi(x) { 126 var a = (x >>> 0); 127 for (var i = 0; i < 2; i++) { 128 for (var j = 0; j < 2; j++) { 129 a = (a >>> 0); 130 } 131 } 132 return (a | 0); 133} 134 135assertEquals(1, PhiOfPhi(1)); 136assertEquals(1, PhiOfPhi(1)); 137%OptimizeFunctionOnNextCall(PhiOfPhi); 138assertEquals(K3 | 0, PhiOfPhi(K3)); 139 140function PhiOfPhiUnsafe(x) { 141 var a = x >>> 0; 142 for (var i = 0; i < 2; i++) { 143 for (var j = 0; j < 2; j++) { 144 a = (a >>> 0); 145 } 146 } 147 return a + a; 148} 149 150assertEquals(2, PhiOfPhiUnsafe(1)); 151assertEquals(2, PhiOfPhiUnsafe(1)); 152%OptimizeFunctionOnNextCall(PhiOfPhiUnsafe); 153assertEquals(2 * K3, PhiOfPhiUnsafe(K3)); 154 155var old_array = new Array(1000); 156 157for (var i = 0; i < old_array.length; i++) old_array[i] = null; 158 159// Force promotion. 160gc(); 161gc(); 162 163function FillOldArrayWithHeapNumbers(N) { 164 for (var i = 0; i < N; i++) { 165 old_array[i] = uint32_array[1]; 166 } 167} 168 169FillOldArrayWithHeapNumbers(1); 170FillOldArrayWithHeapNumbers(1); 171%OptimizeFunctionOnNextCall(FillOldArrayWithHeapNumbers); 172FillOldArrayWithHeapNumbers(old_array.length); 173gc(); 174 175// Test that HArgumentsObject does not prevent uint32 optimization and 176// that arguments object with uint32 values inside is correctly materialized. 177function Pack(x, y) { 178 try { // Prevent inlining. 179 return [x, y]; 180 } catch (e) { 181 } 182} 183 184function InnerWithArguments(x, f) { 185 "use strict"; 186 x >>>= 8; 187 return f(arguments[0], x|0); 188} 189 190function Outer(v, f) { 191 return InnerWithArguments(v >>> 0, f); 192} 193 194assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack)); 195assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack)); 196assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack)); 197%OptimizeFunctionOnNextCall(Outer); 198assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack)); 199assertArrayEquals([0xFFFFFFFF, 0x00FFFFFF], Outer(-1, Pack)); 200 201// Cause deopt inside InnerWithArguments by passing different pack function. 202assertArrayEquals([0xFFFFFFFF, 0x00FFFFFF], Outer(-1, function (x, y) { 203 return [x, y]; 204})); 205