Home | History | Annotate | Download | only in cctest
      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/collector.h"
     36 #include "test/cctest/cctest.h"
     37 
     38 using namespace v8::internal;
     39 
     40 
     41 TEST(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(std::numeric_limits<double>::quiet_NaN()));
     76 }
     77 
     78 
     79 TEST(BitSetComputer) {
     80   typedef BitSetComputer<bool, 1, kSmiValueSize, uint32_t> BoolComputer;
     81   CHECK_EQ(0, BoolComputer::word_count(0));
     82   CHECK_EQ(1, BoolComputer::word_count(8));
     83   CHECK_EQ(2, BoolComputer::word_count(50));
     84   CHECK_EQ(0, BoolComputer::index(0, 8));
     85   CHECK_EQ(100, BoolComputer::index(100, 8));
     86   CHECK_EQ(1, BoolComputer::index(0, 40));
     87   uint32_t data = 0;
     88   data = BoolComputer::encode(data, 1, true);
     89   data = BoolComputer::encode(data, 4, true);
     90   CHECK_EQ(true, BoolComputer::decode(data, 1));
     91   CHECK_EQ(true, BoolComputer::decode(data, 4));
     92   CHECK_EQ(false, BoolComputer::decode(data, 0));
     93   CHECK_EQ(false, BoolComputer::decode(data, 2));
     94   CHECK_EQ(false, BoolComputer::decode(data, 3));
     95 
     96   // Lets store 2 bits per item with 3000 items and verify the values are
     97   // correct.
     98   typedef BitSetComputer<unsigned char, 2, 8, unsigned char> TwoBits;
     99   const int words = 750;
    100   CHECK_EQ(words, TwoBits::word_count(3000));
    101   const int offset = 10;
    102   Vector<unsigned char> buffer = Vector<unsigned char>::New(offset + words);
    103   memset(buffer.start(), 0, sizeof(unsigned char) * buffer.length());
    104   for (int i = 0; i < words; i++) {
    105     const int index = TwoBits::index(offset, i);
    106     unsigned char data = buffer[index];
    107     data = TwoBits::encode(data, i, i % 4);
    108     buffer[index] = data;
    109   }
    110 
    111   for (int i = 0; i < words; i++) {
    112     const int index = TwoBits::index(offset, i);
    113     unsigned char data = buffer[index];
    114     CHECK_EQ(i % 4, TwoBits::decode(data, i));
    115   }
    116   buffer.Dispose();
    117 }
    118 
    119 
    120 TEST(SNPrintF) {
    121   // Make sure that strings that are truncated because of too small
    122   // buffers are zero-terminated anyway.
    123   const char* s = "the quick lazy .... oh forget it!";
    124   int length = StrLength(s);
    125   for (int i = 1; i < length * 2; i++) {
    126     static const char kMarker = static_cast<char>(42);
    127     Vector<char> buffer = Vector<char>::New(i + 1);
    128     buffer[i] = kMarker;
    129     int n = SNPrintF(Vector<char>(buffer.start(), i), "%s", s);
    130     CHECK(n <= i);
    131     CHECK(n == length || n == -1);
    132     CHECK_EQ(0, strncmp(buffer.start(), s, i - 1));
    133     CHECK_EQ(kMarker, buffer[i]);
    134     if (i <= length) {
    135       CHECK_EQ(i - 1, StrLength(buffer.start()));
    136     } else {
    137       CHECK_EQ(length, StrLength(buffer.start()));
    138     }
    139     buffer.Dispose();
    140   }
    141 }
    142 
    143 
    144 static const int kAreaSize = 512;
    145 
    146 
    147 void TestMemMove(byte* area1,
    148                  byte* area2,
    149                  int src_offset,
    150                  int dest_offset,
    151                  int length) {
    152   for (int i = 0; i < kAreaSize; i++) {
    153     area1[i] = i & 0xFF;
    154     area2[i] = i & 0xFF;
    155   }
    156   MemMove(area1 + dest_offset, area1 + src_offset, length);
    157   memmove(area2 + dest_offset, area2 + src_offset, length);
    158   if (memcmp(area1, area2, kAreaSize) != 0) {
    159     printf("MemMove(): src_offset: %d, dest_offset: %d, length: %d\n",
    160            src_offset, dest_offset, length);
    161     for (int i = 0; i < kAreaSize; i++) {
    162       if (area1[i] == area2[i]) continue;
    163       printf("diff at offset %d (%p): is %d, should be %d\n", i,
    164              reinterpret_cast<void*>(area1 + i), area1[i], area2[i]);
    165     }
    166     CHECK(false);
    167   }
    168 }
    169 
    170 
    171 TEST(MemMove) {
    172   v8::V8::Initialize();
    173   byte* area1 = new byte[kAreaSize];
    174   byte* area2 = new byte[kAreaSize];
    175 
    176   static const int kMinOffset = 32;
    177   static const int kMaxOffset = 64;
    178   static const int kMaxLength = 128;
    179   STATIC_ASSERT(kMaxOffset + kMaxLength < kAreaSize);
    180 
    181   for (int src_offset = kMinOffset; src_offset <= kMaxOffset; src_offset++) {
    182     for (int dst_offset = kMinOffset; dst_offset <= kMaxOffset; dst_offset++) {
    183       for (int length = 0; length <= kMaxLength; length++) {
    184         TestMemMove(area1, area2, src_offset, dst_offset, length);
    185       }
    186     }
    187   }
    188   delete[] area1;
    189   delete[] area2;
    190 }
    191 
    192 
    193 TEST(Collector) {
    194   Collector<int> collector(8);
    195   const int kLoops = 5;
    196   const int kSequentialSize = 1000;
    197   const int kBlockSize = 7;
    198   for (int loop = 0; loop < kLoops; loop++) {
    199     Vector<int> block = collector.AddBlock(7, 0xbadcafe);
    200     for (int i = 0; i < kSequentialSize; i++) {
    201       collector.Add(i);
    202     }
    203     for (int i = 0; i < kBlockSize - 1; i++) {
    204       block[i] = i * 7;
    205     }
    206   }
    207   Vector<int> result = collector.ToVector();
    208   CHECK_EQ(kLoops * (kBlockSize + kSequentialSize), result.length());
    209   for (int i = 0; i < kLoops; i++) {
    210     int offset = i * (kSequentialSize + kBlockSize);
    211     for (int j = 0; j < kBlockSize - 1; j++) {
    212       CHECK_EQ(j * 7, result[offset + j]);
    213     }
    214     CHECK_EQ(0xbadcafe, result[offset + kBlockSize - 1]);
    215     for (int j = 0; j < kSequentialSize; j++) {
    216       CHECK_EQ(j, result[offset + kBlockSize + j]);
    217     }
    218   }
    219   result.Dispose();
    220 }
    221 
    222 
    223 TEST(SequenceCollector) {
    224   SequenceCollector<int> collector(8);
    225   const int kLoops = 5000;
    226   const int kMaxSequenceSize = 13;
    227   int total_length = 0;
    228   for (int loop = 0; loop < kLoops; loop++) {
    229     int seq_length = loop % kMaxSequenceSize;
    230     collector.StartSequence();
    231     for (int j = 0; j < seq_length; j++) {
    232       collector.Add(j);
    233     }
    234     Vector<int> sequence = collector.EndSequence();
    235     for (int j = 0; j < seq_length; j++) {
    236       CHECK_EQ(j, sequence[j]);
    237     }
    238     total_length += seq_length;
    239   }
    240   Vector<int> result = collector.ToVector();
    241   CHECK_EQ(total_length, result.length());
    242   int offset = 0;
    243   for (int loop = 0; loop < kLoops; loop++) {
    244     int seq_length = loop % kMaxSequenceSize;
    245     for (int j = 0; j < seq_length; j++) {
    246       CHECK_EQ(j, result[offset]);
    247       offset++;
    248     }
    249   }
    250   result.Dispose();
    251 }
    252 
    253 
    254 TEST(SequenceCollectorRegression) {
    255   SequenceCollector<char> collector(16);
    256   collector.StartSequence();
    257   collector.Add('0');
    258   collector.AddBlock(
    259       i::Vector<const char>("12345678901234567890123456789012", 32));
    260   i::Vector<char> seq = collector.EndSequence();
    261   CHECK_EQ(0, strncmp("0123456789012345678901234567890123",
    262                       seq.start(), seq.length()));
    263 }
    264 
    265 
    266 TEST(CPlusPlus11Features) {
    267   struct S {
    268     bool x;
    269     struct T {
    270       double y;
    271       int z[3];
    272     } t;
    273   };
    274   S s{true, {3.1415, {1, 2, 3}}};
    275   CHECK_EQ(2, s.t.z[1]);
    276 
    277 // TODO(svenpanne) Remove the old-skool code when we ship the new C++ headers.
    278 #if 0
    279   std::vector<int> vec{11, 22, 33, 44};
    280 #else
    281   std::vector<int> vec;
    282   vec.push_back(11);
    283   vec.push_back(22);
    284   vec.push_back(33);
    285   vec.push_back(44);
    286 #endif
    287   vec.push_back(55);
    288   vec.push_back(66);
    289   for (auto& i : vec) {
    290     ++i;
    291   }
    292   int j = 12;
    293   for (auto i : vec) {
    294     CHECK_EQ(j, i);
    295     j += 11;
    296   }
    297 }
    298