v8/test/unittests/compiler/persistent-unittest.cc
Leszek Swirski 0ff8205261 [test] Add a unittest platform setup mixin
Change the unittest runner to no longer uncondtionally set up a default
platform in the "environment", but to instead make platform set-up part
of the "mixin" framework for test fixtures.

Requires modifying some tests that expect the platform to be available,
and all flag implications resolved, before the mixin constructors run.

We still keep the environment for setting up the process for cppgc. This
process setup can only be done once per process, so it can no longer use
the platform -- that's ok though, the page allocator used by cppgc's
process initialisation doesn't have to be the same as the platform's so
we can just pass in a separate new one.

Change-Id: Ic8ccf39722e8212962c5bba87350c4b304388a7c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3571886
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79820}
2022-04-06 13:07:43 +00:00

137 lines
3.8 KiB
C++

// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <tuple>
#include "src/base/utils/random-number-generator.h"
#include "src/compiler/persistent-map.h"
#include "test/unittests/test-utils.h"
namespace v8 {
namespace internal {
namespace compiler {
// A random distribution that produces both small values and arbitrary numbers.
static int small_big_distr(base::RandomNumberGenerator* rand) {
return rand->NextInt() / std::max(1, rand->NextInt() / 100);
}
class PersistentMapTest : public TestWithPlatform {};
TEST_F(PersistentMapTest, RefTest) {
base::RandomNumberGenerator rand(92834738);
AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
std::vector<PersistentMap<int, int>> pers_maps;
pers_maps.emplace_back(&zone);
std::vector<std::map<int, int>> ref_maps(1);
for (int i = 0; i < 100000; ++i) {
if (rand.NextInt(2) == 0) {
// Read value;
int key = small_big_distr(&rand);
if (ref_maps[0].count(key) > 0) {
ASSERT_EQ(pers_maps[0].Get(key), ref_maps[0][key]);
} else {
ASSERT_EQ(pers_maps[0].Get(key), 0);
}
}
if (rand.NextInt(2) == 0) {
// Add value;
int key = small_big_distr(&rand);
int value = small_big_distr(&rand);
pers_maps[0].Set(key, value);
ref_maps[0][key] = value;
}
if (rand.NextInt(1000) == 0) {
// Create empty map.
pers_maps.emplace_back(&zone);
ref_maps.emplace_back();
}
if (rand.NextInt(100) == 0) {
// Copy and move around maps.
int num_maps = static_cast<int>(pers_maps.size());
int source = rand.NextInt(num_maps - 1) + 1;
int target = rand.NextInt(num_maps - 1) + 1;
pers_maps[target] = std::move(pers_maps[0]);
ref_maps[target] = std::move(ref_maps[0]);
pers_maps[0] = pers_maps[source];
ref_maps[0] = ref_maps[source];
}
}
for (size_t i = 0; i < pers_maps.size(); ++i) {
std::set<int> keys;
for (auto pair : pers_maps[i]) {
ASSERT_EQ(keys.count(pair.first), 0u);
keys.insert(pair.first);
ASSERT_EQ(ref_maps[i][pair.first], pair.second);
}
for (auto pair : ref_maps[i]) {
int value = pers_maps[i].Get(pair.first);
ASSERT_EQ(pair.second, value);
if (value != 0) {
ASSERT_EQ(keys.count(pair.first), 1u);
keys.erase(pair.first);
}
}
ASSERT_TRUE(keys.empty());
}
}
TEST_F(PersistentMapTest, Zip) {
base::RandomNumberGenerator rand(92834738);
AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
// Provoke hash collisions to stress the iterator.
struct bad_hash {
size_t operator()(uint32_t key) {
return base::hash_value(static_cast<size_t>(key) % 1000);
}
};
PersistentMap<int, uint32_t, bad_hash> a(&zone);
PersistentMap<int, uint32_t, bad_hash> b(&zone);
uint32_t sum_a = 0;
uint32_t sum_b = 0;
for (int i = 0; i < 30000; ++i) {
int key = small_big_distr(&rand);
uint32_t value = small_big_distr(&rand);
if (rand.NextBool()) {
sum_a += value;
a.Set(key, a.Get(key) + value);
} else {
sum_b += value;
b.Set(key, b.Get(key) + value);
}
}
uint32_t sum = sum_a + sum_b;
for (auto pair : a) {
sum_a -= pair.second;
}
ASSERT_EQ(0u, sum_a);
for (auto pair : b) {
sum_b -= pair.second;
}
ASSERT_EQ(0u, sum_b);
for (auto triple : a.Zip(b)) {
int key = std::get<0>(triple);
uint32_t value_a = std::get<1>(triple);
uint32_t value_b = std::get<2>(triple);
ASSERT_EQ(value_a, a.Get(key));
ASSERT_EQ(value_b, b.Get(key));
sum -= value_a;
sum -= value_b;
}
ASSERT_EQ(0u, sum);
}
} // namespace compiler
} // namespace internal
} // namespace v8