1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/base/functional.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <limits> 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <set> 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "test/unittests/test-utils.h" 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace base { 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, HashBool) { 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<bool> h, h1, h2; 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(h1(true), h2(true)); 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(h1(false), h2(false)); 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_NE(h(true), h(false)); 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, HashFloatZero) { 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<float> h; 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(h(0.0f), h(-0.0f)); 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, HashDoubleZero) { 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<double> h; 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(h(0.0), h(-0.0)); 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <typename T> 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass FunctionalTest : public TestWithRandomNumberGenerator {}; 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef ::testing::Types<signed char, unsigned char, 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier short, // NOLINT(runtime/int) 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned short, // NOLINT(runtime/int) 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int, unsigned int, long, // NOLINT(runtime/int) 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned long, // NOLINT(runtime/int) 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier long long, // NOLINT(runtime/int) 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned long long, // NOLINT(runtime/int) 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int64_t, uint64_t, float, double> FunctionalTypes; 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST_CASE(FunctionalTest, FunctionalTypes); 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, EqualToImpliesSameHashCode) { 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<TypeParam> h; 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::equal_to<TypeParam> e; 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam values[32]; 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(values, sizeof(values)); 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TRACED_FOREACH(TypeParam, v1, values) { 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TRACED_FOREACH(TypeParam, v2, values) { 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (e(v1, v2)) EXPECT_EQ(h(v1), h(v2)); 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, HashEqualsHashValue) { 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < 128; ++i) { 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam v; 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&v, sizeof(v)); 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<TypeParam> h; 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(h(v), hash_value(v)); 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, HashIsStateless) { 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<TypeParam> h1, h2; 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < 128; ++i) { 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam v; 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&v, sizeof(v)); 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(h1(v), h2(v)); 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, HashIsOkish) { 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::set<TypeParam> vs; 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < 128; ++i) { 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam v; 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&v, sizeof(v)); 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vs.insert(v); 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::set<size_t> hs; 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (const auto& v : vs) { 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<TypeParam> h; 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hs.insert(h(v)); 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_LE(vs.size() / 4u, hs.size()); 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, HashValueArrayUsesHashRange) { 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam values[128]; 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&values, sizeof(values)); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(hash_range(values, values + arraysize(values)), hash_value(values)); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, BitEqualTo) { 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_equal_to<TypeParam> pred; 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < 128; ++i) { 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam v1, v2; 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&v1, sizeof(v1)); 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&v2, sizeof(v2)); 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_PRED2(pred, v1, v1); 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_PRED2(pred, v2, v2); 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(memcmp(&v1, &v2, sizeof(TypeParam)) == 0, pred(v1, v2)); 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTYPED_TEST(FunctionalTest, BitEqualToImpliesSameBitHash) { 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_hash<TypeParam> h; 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_equal_to<TypeParam> e; 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeParam values[32]; 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->rng()->NextBytes(&values, sizeof(values)); 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TRACED_FOREACH(TypeParam, v1, values) { 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TRACED_FOREACH(TypeParam, v2, values) { 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (e(v1, v2)) EXPECT_EQ(h(v1), h(v2)); 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct Foo { 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int x; 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double y; 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t hash_value(Foo const& v) { return hash_combine(v.x, v.y); } 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, HashUsesArgumentDependentLookup) { 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int kIntValues[] = {std::numeric_limits<int>::min(), -1, 0, 1, 42, 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::numeric_limits<int>::max()}; 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const double kDoubleValues[] = { 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::numeric_limits<double>::min(), -1, -0, 0, 1, 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::numeric_limits<double>::max()}; 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TRACED_FOREACH(int, x, kIntValues) { 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TRACED_FOREACH(double, y, kDoubleValues) { 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hash<Foo> h; 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Foo foo = {x, y}; 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_EQ(hash_combine(x, y), h(foo)); 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, BitEqualToFloat) { 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_equal_to<float> pred; 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_FALSE(pred(0.0f, -0.0f)); 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_FALSE(pred(-0.0f, 0.0f)); 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier float const qNaN = std::numeric_limits<float>::quiet_NaN(); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier float const sNaN = std::numeric_limits<float>::signaling_NaN(); 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_PRED2(pred, qNaN, qNaN); 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_PRED2(pred, sNaN, sNaN); 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, BitHashFloatDifferentForZeroAndMinusZero) { 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_hash<float> h; 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_NE(h(0.0f), h(-0.0f)); 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, BitEqualToDouble) { 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_equal_to<double> pred; 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_FALSE(pred(0.0, -0.0)); 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_FALSE(pred(-0.0, 0.0)); 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double const qNaN = std::numeric_limits<double>::quiet_NaN(); 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double const sNaN = std::numeric_limits<double>::signaling_NaN(); 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_PRED2(pred, qNaN, qNaN); 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_PRED2(pred, sNaN, sNaN); 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierTEST(FunctionalTest, BitHashDoubleDifferentForZeroAndMinusZero) { 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bit_hash<double> h; 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EXPECT_NE(h(0.0), h(-0.0)); 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace base 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 197