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 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 OS::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("OS::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", 121 i, reinterpret_cast<void*>(area1 + i), area1[i], area2[i]); 122 } 123 CHECK(false); 124 } 125} 126 127 128TEST(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 150TEST(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 180TEST(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 211TEST(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