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