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 60 61TEST(SNPrintF) { 62 // Make sure that strings that are truncated because of too small 63 // buffers are zero-terminated anyway. 64 const char* s = "the quick lazy .... oh forget it!"; 65 int length = StrLength(s); 66 for (int i = 1; i < length * 2; i++) { 67 static const char kMarker = static_cast<char>(42); 68 Vector<char> buffer = Vector<char>::New(i + 1); 69 buffer[i] = kMarker; 70 int n = OS::SNPrintF(Vector<char>(buffer.start(), i), "%s", s); 71 CHECK(n <= i); 72 CHECK(n == length || n == -1); 73 CHECK_EQ(0, strncmp(buffer.start(), s, i - 1)); 74 CHECK_EQ(kMarker, buffer[i]); 75 if (i <= length) { 76 CHECK_EQ(i - 1, StrLength(buffer.start())); 77 } else { 78 CHECK_EQ(length, StrLength(buffer.start())); 79 } 80 buffer.Dispose(); 81 } 82} 83 84 85void TestMemCopy(Vector<byte> src, 86 Vector<byte> dst, 87 int source_alignment, 88 int destination_alignment, 89 int length_alignment) { 90 memset(dst.start(), 0xFF, dst.length()); 91 byte* to = dst.start() + 32 + destination_alignment; 92 byte* from = src.start() + source_alignment; 93 int length = OS::kMinComplexMemCopy + length_alignment; 94 OS::MemCopy(to, from, static_cast<size_t>(length)); 95 printf("[%d,%d,%d]\n", 96 source_alignment, destination_alignment, length_alignment); 97 for (int i = 0; i < length; i++) { 98 CHECK_EQ(from[i], to[i]); 99 } 100 CHECK_EQ(0xFF, to[-1]); 101 CHECK_EQ(0xFF, to[length]); 102} 103 104 105 106TEST(MemCopy) { 107 v8::V8::Initialize(); 108 OS::SetUp(); 109 const int N = OS::kMinComplexMemCopy + 128; 110 Vector<byte> buffer1 = Vector<byte>::New(N); 111 Vector<byte> buffer2 = Vector<byte>::New(N); 112 113 for (int i = 0; i < N; i++) { 114 buffer1[i] = static_cast<byte>(i & 0x7F); 115 } 116 117 // Same alignment. 118 for (int i = 0; i < 32; i++) { 119 TestMemCopy(buffer1, buffer2, i, i, i * 2); 120 } 121 122 // Different alignment. 123 for (int i = 0; i < 32; i++) { 124 for (int j = 1; j < 32; j++) { 125 TestMemCopy(buffer1, buffer2, i, (i + j) & 0x1F , 0); 126 } 127 } 128 129 // Different lengths 130 for (int i = 0; i < 32; i++) { 131 TestMemCopy(buffer1, buffer2, 3, 7, i); 132 } 133 134 buffer2.Dispose(); 135 buffer1.Dispose(); 136} 137 138 139TEST(Collector) { 140 Collector<int> collector(8); 141 const int kLoops = 5; 142 const int kSequentialSize = 1000; 143 const int kBlockSize = 7; 144 for (int loop = 0; loop < kLoops; loop++) { 145 Vector<int> block = collector.AddBlock(7, 0xbadcafe); 146 for (int i = 0; i < kSequentialSize; i++) { 147 collector.Add(i); 148 } 149 for (int i = 0; i < kBlockSize - 1; i++) { 150 block[i] = i * 7; 151 } 152 } 153 Vector<int> result = collector.ToVector(); 154 CHECK_EQ(kLoops * (kBlockSize + kSequentialSize), result.length()); 155 for (int i = 0; i < kLoops; i++) { 156 int offset = i * (kSequentialSize + kBlockSize); 157 for (int j = 0; j < kBlockSize - 1; j++) { 158 CHECK_EQ(j * 7, result[offset + j]); 159 } 160 CHECK_EQ(0xbadcafe, result[offset + kBlockSize - 1]); 161 for (int j = 0; j < kSequentialSize; j++) { 162 CHECK_EQ(j, result[offset + kBlockSize + j]); 163 } 164 } 165 result.Dispose(); 166} 167 168 169TEST(SequenceCollector) { 170 SequenceCollector<int> collector(8); 171 const int kLoops = 5000; 172 const int kMaxSequenceSize = 13; 173 int total_length = 0; 174 for (int loop = 0; loop < kLoops; loop++) { 175 int seq_length = loop % kMaxSequenceSize; 176 collector.StartSequence(); 177 for (int j = 0; j < seq_length; j++) { 178 collector.Add(j); 179 } 180 Vector<int> sequence = collector.EndSequence(); 181 for (int j = 0; j < seq_length; j++) { 182 CHECK_EQ(j, sequence[j]); 183 } 184 total_length += seq_length; 185 } 186 Vector<int> result = collector.ToVector(); 187 CHECK_EQ(total_length, result.length()); 188 int offset = 0; 189 for (int loop = 0; loop < kLoops; loop++) { 190 int seq_length = loop % kMaxSequenceSize; 191 for (int j = 0; j < seq_length; j++) { 192 CHECK_EQ(j, result[offset]); 193 offset++; 194 } 195 } 196 result.Dispose(); 197} 198 199 200TEST(SequenceCollectorRegression) { 201 SequenceCollector<char> collector(16); 202 collector.StartSequence(); 203 collector.Add('0'); 204 collector.AddBlock( 205 i::Vector<const char>("12345678901234567890123456789012", 32)); 206 i::Vector<char> seq = collector.EndSequence(); 207 CHECK_EQ(0, strncmp("0123456789012345678901234567890123", 208 seq.start(), seq.length())); 209} 210