1// Copyright 2009 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// Test paths in the code generator where values in specific registers 29// get moved around. 30function identity(x) { 31 return x; 32} 33 34function lookup(w, a) { 35 // This function tests a code path in the generation of a keyed load IC 36 // where the key and the value are both in the same register. 37 a = a; 38 w[a] = a; 39} 40 41function cover_codegen_paths() { 42 var x = 1; 43 44 // This test depends on the fixed order of register allocation. We try to 45 // get values in specific registers (ia32, x64): 46 var a; // Register eax, rax. 47 var b; // Register ebx, rbx. 48 var c; // Register ecx, rcx. 49 var d; // Register edx, rdx. 50 var di; // Register edi, rdi. 51 52 while (x == 1) { 53 // The call will spill registers and leave x in {eax,rax}. 54 x = identity(1); 55 // The add will spill x and reuse {eax,rax} for the result. 56 a = x + 1; 57 // A fresh register {ebx,rbx} will be allocated for x, then reused for 58 // the result. 59 b = x + 1; 60 // Et cetera. 61 c = x + 1; 62 d = x + 1; 63 di = x + 1; 64 // Locals are in the corresponding registers here. 65 assertEquals(8, c << a); 66 67 x = identity(1); 68 a = x + 1; 69 b = x + 1; 70 c = x + 1; 71 d = x + 1; 72 di = x + 1; 73 assertEquals(8, a << c); 74 75 x = identity(1); 76 a = x + 1; 77 b = x + 1; 78 c = x + 1; 79 d = x + 1; 80 di = x + 1; 81 c = 0; // Free register ecx. 82 assertEquals(8, a << d); 83 84 x = identity(1); 85 a = x + 1; 86 b = x + 1; 87 c = x + 1; 88 d = x + 1; 89 di = x + 1; 90 b = 0; // Free register ebx. 91 assertEquals(8, a << d); 92 93 // Test the non-commutative subtraction operation with a smi on the 94 // left, all available registers on the right, and a non-smi result. 95 x = identity(-1073741824); // Least (31-bit) smi. 96 a = x + 1; // Still a smi, the greatest smi negated. 97 b = x + 1; 98 c = x + 1; 99 d = x + 1; 100 di = x + 1; 101 // Subtraction should overflow the 31-bit smi range. The result 102 // (1073741824) is outside the 31-bit smi range so it doesn't hit the 103 // "unsafe smi" code that spills a register. 104 assertEquals(1073741824, 1 - a); 105 106 x = identity(-1073741824); 107 a = x + 1; 108 b = x + 1; 109 c = x + 1; 110 d = x + 1; 111 di = x + 1; 112 assertEquals(1073741824, 1 - b); 113 114 x = identity(-1073741824); 115 a = x + 1; 116 b = x + 1; 117 c = x + 1; 118 d = x + 1; 119 di = x + 1; 120 assertEquals(1073741824, 1 - c); 121 122 x = identity(-1073741824); 123 a = x + 1; 124 b = x + 1; 125 c = x + 1; 126 d = x + 1; 127 di = x + 1; 128 assertEquals(1073741824, 1 - d); 129 130 x = identity(-1073741824); 131 a = x + 1; 132 b = x + 1; 133 c = x + 1; 134 d = x + 1; 135 di = x + 1; 136 assertEquals(1073741824, 1 - di); 137 138 x = 3; 139 var w = { }; 140 lookup(w, x); 141 lookup(w, x); 142 lookup(w, x); 143 144 x = 3; // Terminate while loop. 145 } 146} 147 148cover_codegen_paths(); 149