1 // Copyright 2011 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 #include <stdlib.h> 29 30 #include "src/v8.h" 31 32 #include "src/platform.h" 33 #include "src/utils-inl.h" 34 #include "test/cctest/cctest.h" 35 36 using namespace v8::internal; 37 38 39 TEST(Utils1) { 40 CHECK_EQ(-1000000, FastD2I(-1000000.0)); 41 CHECK_EQ(-1, FastD2I(-1.0)); 42 CHECK_EQ(0, FastD2I(0.0)); 43 CHECK_EQ(1, FastD2I(1.0)); 44 CHECK_EQ(1000000, FastD2I(1000000.0)); 45 46 CHECK_EQ(-1000000, FastD2I(-1000000.123)); 47 CHECK_EQ(-1, FastD2I(-1.234)); 48 CHECK_EQ(0, FastD2I(0.345)); 49 CHECK_EQ(1, FastD2I(1.234)); 50 CHECK_EQ(1000000, FastD2I(1000000.123)); 51 // Check that >> is implemented as arithmetic shift right. 52 // If this is not true, then ArithmeticShiftRight() must be changed, 53 // There are also documented right shifts in assembler.cc of 54 // int8_t and intptr_t signed integers. 55 CHECK_EQ(-2, -8 >> 2); 56 CHECK_EQ(-2, static_cast<int8_t>(-8) >> 2); 57 CHECK_EQ(-2, static_cast<int>(static_cast<intptr_t>(-8) >> 2)); 58 59 CHECK_EQ(-1000000, FastD2IChecked(-1000000.0)); 60 CHECK_EQ(-1, FastD2IChecked(-1.0)); 61 CHECK_EQ(0, FastD2IChecked(0.0)); 62 CHECK_EQ(1, FastD2IChecked(1.0)); 63 CHECK_EQ(1000000, FastD2IChecked(1000000.0)); 64 65 CHECK_EQ(-1000000, FastD2IChecked(-1000000.123)); 66 CHECK_EQ(-1, FastD2IChecked(-1.234)); 67 CHECK_EQ(0, FastD2IChecked(0.345)); 68 CHECK_EQ(1, FastD2IChecked(1.234)); 69 CHECK_EQ(1000000, FastD2IChecked(1000000.123)); 70 71 CHECK_EQ(INT_MAX, FastD2IChecked(1.0e100)); 72 CHECK_EQ(INT_MIN, FastD2IChecked(-1.0e100)); 73 CHECK_EQ(INT_MIN, FastD2IChecked(OS::nan_value())); 74 } 75 76 77 TEST(SNPrintF) { 78 // Make sure that strings that are truncated because of too small 79 // buffers are zero-terminated anyway. 80 const char* s = "the quick lazy .... oh forget it!"; 81 int length = StrLength(s); 82 for (int i = 1; i < length * 2; i++) { 83 static const char kMarker = static_cast<char>(42); 84 Vector<char> buffer = Vector<char>::New(i + 1); 85 buffer[i] = kMarker; 86 int n = SNPrintF(Vector<char>(buffer.start(), i), "%s", s); 87 CHECK(n <= i); 88 CHECK(n == length || n == -1); 89 CHECK_EQ(0, strncmp(buffer.start(), s, i - 1)); 90 CHECK_EQ(kMarker, buffer[i]); 91 if (i <= length) { 92 CHECK_EQ(i - 1, StrLength(buffer.start())); 93 } else { 94 CHECK_EQ(length, StrLength(buffer.start())); 95 } 96 buffer.Dispose(); 97 } 98 } 99 100 101 static const int kAreaSize = 512; 102 103 104 void TestMemMove(byte* area1, 105 byte* area2, 106 int src_offset, 107 int dest_offset, 108 int length) { 109 for (int i = 0; i < kAreaSize; i++) { 110 area1[i] = i & 0xFF; 111 area2[i] = i & 0xFF; 112 } 113 MemMove(area1 + dest_offset, area1 + src_offset, length); 114 memmove(area2 + dest_offset, area2 + src_offset, length); 115 if (memcmp(area1, area2, kAreaSize) != 0) { 116 printf("MemMove(): src_offset: %d, dest_offset: %d, length: %d\n", 117 src_offset, dest_offset, length); 118 for (int i = 0; i < kAreaSize; i++) { 119 if (area1[i] == area2[i]) continue; 120 printf("diff at offset %d (%p): is %d, should be %d\n", i, 121 reinterpret_cast<void*>(area1 + i), area1[i], area2[i]); 122 } 123 CHECK(false); 124 } 125 } 126 127 128 TEST(MemMove) { 129 v8::V8::Initialize(); 130 byte* area1 = new byte[kAreaSize]; 131 byte* area2 = new byte[kAreaSize]; 132 133 static const int kMinOffset = 32; 134 static const int kMaxOffset = 64; 135 static const int kMaxLength = 128; 136 STATIC_ASSERT(kMaxOffset + kMaxLength < kAreaSize); 137 138 for (int src_offset = kMinOffset; src_offset <= kMaxOffset; src_offset++) { 139 for (int dst_offset = kMinOffset; dst_offset <= kMaxOffset; dst_offset++) { 140 for (int length = 0; length <= kMaxLength; length++) { 141 TestMemMove(area1, area2, src_offset, dst_offset, length); 142 } 143 } 144 } 145 delete[] area1; 146 delete[] area2; 147 } 148 149 150 TEST(Collector) { 151 Collector<int> collector(8); 152 const int kLoops = 5; 153 const int kSequentialSize = 1000; 154 const int kBlockSize = 7; 155 for (int loop = 0; loop < kLoops; loop++) { 156 Vector<int> block = collector.AddBlock(7, 0xbadcafe); 157 for (int i = 0; i < kSequentialSize; i++) { 158 collector.Add(i); 159 } 160 for (int i = 0; i < kBlockSize - 1; i++) { 161 block[i] = i * 7; 162 } 163 } 164 Vector<int> result = collector.ToVector(); 165 CHECK_EQ(kLoops * (kBlockSize + kSequentialSize), result.length()); 166 for (int i = 0; i < kLoops; i++) { 167 int offset = i * (kSequentialSize + kBlockSize); 168 for (int j = 0; j < kBlockSize - 1; j++) { 169 CHECK_EQ(j * 7, result[offset + j]); 170 } 171 CHECK_EQ(0xbadcafe, result[offset + kBlockSize - 1]); 172 for (int j = 0; j < kSequentialSize; j++) { 173 CHECK_EQ(j, result[offset + kBlockSize + j]); 174 } 175 } 176 result.Dispose(); 177 } 178 179 180 TEST(SequenceCollector) { 181 SequenceCollector<int> collector(8); 182 const int kLoops = 5000; 183 const int kMaxSequenceSize = 13; 184 int total_length = 0; 185 for (int loop = 0; loop < kLoops; loop++) { 186 int seq_length = loop % kMaxSequenceSize; 187 collector.StartSequence(); 188 for (int j = 0; j < seq_length; j++) { 189 collector.Add(j); 190 } 191 Vector<int> sequence = collector.EndSequence(); 192 for (int j = 0; j < seq_length; j++) { 193 CHECK_EQ(j, sequence[j]); 194 } 195 total_length += seq_length; 196 } 197 Vector<int> result = collector.ToVector(); 198 CHECK_EQ(total_length, result.length()); 199 int offset = 0; 200 for (int loop = 0; loop < kLoops; loop++) { 201 int seq_length = loop % kMaxSequenceSize; 202 for (int j = 0; j < seq_length; j++) { 203 CHECK_EQ(j, result[offset]); 204 offset++; 205 } 206 } 207 result.Dispose(); 208 } 209 210 211 TEST(SequenceCollectorRegression) { 212 SequenceCollector<char> collector(16); 213 collector.StartSequence(); 214 collector.Add('0'); 215 collector.AddBlock( 216 i::Vector<const char>("12345678901234567890123456789012", 32)); 217 i::Vector<char> seq = collector.EndSequence(); 218 CHECK_EQ(0, strncmp("0123456789012345678901234567890123", 219 seq.start(), seq.length())); 220 } 221