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 "v8.h" 31 32#include "cctest.h" 33#include "platform.h" 34#include "utils-inl.h" 35 36using namespace v8::internal; 37 38 39TEST(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 77TEST(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 = OS::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 101static const int kAreaSize = 512; 102 103 104void TestMemMove(byte* area1, 105 byte* area2, 106 byte* area3, 107 int src_offset, 108 int dest_offset, 109 int length) { 110 for (int i = 0; i < kAreaSize; i++) { 111 area1[i] = i & 0xFF; 112 area2[i] = i & 0xFF; 113 area3[i] = i & 0xFF; 114 } 115 OS::MemMove(area1 + dest_offset, area1 + src_offset, length); 116 MoveBytes(area2 + dest_offset, area2 + src_offset, length); 117 memmove(area3 + dest_offset, area3 + src_offset, length); 118 if (memcmp(area1, area3, kAreaSize) != 0) { 119 printf("OS::MemMove(): src_offset: %d, dest_offset: %d, length: %d\n", 120 src_offset, dest_offset, length); 121 for (int i = 0; i < kAreaSize; i++) { 122 if (area1[i] == area3[i]) continue; 123 printf("diff at offset %d (%p): is %d, should be %d\n", 124 i, reinterpret_cast<void*>(area1 + i), area1[i], area3[i]); 125 } 126 CHECK(false); 127 } 128 if (memcmp(area2, area3, kAreaSize) != 0) { 129 printf("MoveBytes(): src_offset: %d, dest_offset: %d, length: %d\n", 130 src_offset, dest_offset, length); 131 for (int i = 0; i < kAreaSize; i++) { 132 if (area2[i] == area3[i]) continue; 133 printf("diff at offset %d (%p): is %d, should be %d\n", 134 i, reinterpret_cast<void*>(area2 + i), area2[i], area3[i]); 135 } 136 CHECK(false); 137 } 138} 139 140 141TEST(MemMove) { 142 v8::V8::Initialize(); 143 OS::SetUp(); 144 byte* area1 = new byte[kAreaSize]; 145 byte* area2 = new byte[kAreaSize]; 146 byte* area3 = new byte[kAreaSize]; 147 148 static const int kMinOffset = 32; 149 static const int kMaxOffset = 64; 150 static const int kMaxLength = 128; 151 STATIC_ASSERT(kMaxOffset + kMaxLength < kAreaSize); 152 153 for (int src_offset = kMinOffset; src_offset <= kMaxOffset; src_offset++) { 154 for (int dst_offset = kMinOffset; dst_offset <= kMaxOffset; dst_offset++) { 155 for (int length = 0; length <= kMaxLength; length++) { 156 TestMemMove(area1, area2, area3, src_offset, dst_offset, length); 157 } 158 } 159 } 160 delete[] area1; 161 delete[] area2; 162 delete[] area3; 163} 164 165 166TEST(Collector) { 167 Collector<int> collector(8); 168 const int kLoops = 5; 169 const int kSequentialSize = 1000; 170 const int kBlockSize = 7; 171 for (int loop = 0; loop < kLoops; loop++) { 172 Vector<int> block = collector.AddBlock(7, 0xbadcafe); 173 for (int i = 0; i < kSequentialSize; i++) { 174 collector.Add(i); 175 } 176 for (int i = 0; i < kBlockSize - 1; i++) { 177 block[i] = i * 7; 178 } 179 } 180 Vector<int> result = collector.ToVector(); 181 CHECK_EQ(kLoops * (kBlockSize + kSequentialSize), result.length()); 182 for (int i = 0; i < kLoops; i++) { 183 int offset = i * (kSequentialSize + kBlockSize); 184 for (int j = 0; j < kBlockSize - 1; j++) { 185 CHECK_EQ(j * 7, result[offset + j]); 186 } 187 CHECK_EQ(0xbadcafe, result[offset + kBlockSize - 1]); 188 for (int j = 0; j < kSequentialSize; j++) { 189 CHECK_EQ(j, result[offset + kBlockSize + j]); 190 } 191 } 192 result.Dispose(); 193} 194 195 196TEST(SequenceCollector) { 197 SequenceCollector<int> collector(8); 198 const int kLoops = 5000; 199 const int kMaxSequenceSize = 13; 200 int total_length = 0; 201 for (int loop = 0; loop < kLoops; loop++) { 202 int seq_length = loop % kMaxSequenceSize; 203 collector.StartSequence(); 204 for (int j = 0; j < seq_length; j++) { 205 collector.Add(j); 206 } 207 Vector<int> sequence = collector.EndSequence(); 208 for (int j = 0; j < seq_length; j++) { 209 CHECK_EQ(j, sequence[j]); 210 } 211 total_length += seq_length; 212 } 213 Vector<int> result = collector.ToVector(); 214 CHECK_EQ(total_length, result.length()); 215 int offset = 0; 216 for (int loop = 0; loop < kLoops; loop++) { 217 int seq_length = loop % kMaxSequenceSize; 218 for (int j = 0; j < seq_length; j++) { 219 CHECK_EQ(j, result[offset]); 220 offset++; 221 } 222 } 223 result.Dispose(); 224} 225 226 227TEST(SequenceCollectorRegression) { 228 SequenceCollector<char> collector(16); 229 collector.StartSequence(); 230 collector.Add('0'); 231 collector.AddBlock( 232 i::Vector<const char>("12345678901234567890123456789012", 32)); 233 i::Vector<char> seq = collector.EndSequence(); 234 CHECK_EQ(0, strncmp("0123456789012345678901234567890123", 235 seq.start(), seq.length())); 236} 237