// 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 "test/unittests/test-utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "src/wasm/wasm-heap.h" namespace v8 { namespace internal { namespace wasm { class DisjointAllocationPoolTest : public testing::Test { public: Address A(size_t n) { return reinterpret_cast
(n); } void CheckLooksLike(const DisjointAllocationPool& mem, std::vector> expectation); DisjointAllocationPool Make(std::vector> model); }; void DisjointAllocationPoolTest::CheckLooksLike( const DisjointAllocationPool& mem, std::vector> expectation) { const auto& ranges = mem.ranges(); CHECK_EQ(ranges.size(), expectation.size()); auto iter = expectation.begin(); for (auto it = ranges.begin(), e = ranges.end(); it != e; ++it, ++iter) { CHECK_EQ(it->first, A(iter->first)); CHECK_EQ(it->second, A(iter->second)); } } DisjointAllocationPool DisjointAllocationPoolTest::Make( std::vector> model) { DisjointAllocationPool ret; for (auto& pair : model) { ret.Release(DisjointAllocationPool(A(pair.first), A(pair.second))); } return ret; } TEST_F(DisjointAllocationPoolTest, Construct) { DisjointAllocationPool a; CHECK(a.IsEmpty()); CHECK_EQ(a.ranges().size(), 0); DisjointAllocationPool b = Make({{1, 5}}); CHECK(!b.IsEmpty()); CHECK_EQ(b.ranges().size(), 1); a.Release(std::move(b)); CheckLooksLike(a, {{1, 5}}); DisjointAllocationPool c; a.Release(std::move(c)); CheckLooksLike(a, {{1, 5}}); DisjointAllocationPool e, f; e.Release(std::move(f)); CHECK(e.IsEmpty()); } TEST_F(DisjointAllocationPoolTest, SimpleExtract) { DisjointAllocationPool a = Make({{1, 5}}); DisjointAllocationPool b = a.AllocatePool(2); CheckLooksLike(a, {{3, 5}}); CheckLooksLike(b, {{1, 3}}); a.Release(std::move(b)); CheckLooksLike(a, {{1, 5}}); CHECK_EQ(a.ranges().size(), 1); CHECK_EQ(a.ranges().front().first, A(1)); CHECK_EQ(a.ranges().front().second, A(5)); } TEST_F(DisjointAllocationPoolTest, ExtractAll) { DisjointAllocationPool a(A(1), A(5)); DisjointAllocationPool b = a.AllocatePool(4); CheckLooksLike(b, {{1, 5}}); CHECK(a.IsEmpty()); a.Release(std::move(b)); CheckLooksLike(a, {{1, 5}}); } TEST_F(DisjointAllocationPoolTest, ExtractAccross) { DisjointAllocationPool a = Make({{1, 5}, {10, 20}}); DisjointAllocationPool b = a.AllocatePool(5); CheckLooksLike(a, {{11, 20}}); CheckLooksLike(b, {{1, 5}, {10, 11}}); a.Release(std::move(b)); CheckLooksLike(a, {{1, 5}, {10, 20}}); } TEST_F(DisjointAllocationPoolTest, ReassembleOutOfOrder) { DisjointAllocationPool a = Make({{1, 5}, {10, 15}}); DisjointAllocationPool b = Make({{7, 8}, {20, 22}}); a.Release(std::move(b)); CheckLooksLike(a, {{1, 5}, {7, 8}, {10, 15}, {20, 22}}); DisjointAllocationPool c = Make({{1, 5}, {10, 15}}); DisjointAllocationPool d = Make({{7, 8}, {20, 22}}); d.Release(std::move(c)); CheckLooksLike(d, {{1, 5}, {7, 8}, {10, 15}, {20, 22}}); } TEST_F(DisjointAllocationPoolTest, FailToExtract) { DisjointAllocationPool a = Make({{1, 5}}); DisjointAllocationPool b = a.AllocatePool(5); CheckLooksLike(a, {{1, 5}}); CHECK(b.IsEmpty()); } TEST_F(DisjointAllocationPoolTest, FailToExtractExact) { DisjointAllocationPool a = Make({{1, 5}, {10, 14}}); DisjointAllocationPool b = a.Allocate(5); CheckLooksLike(a, {{1, 5}, {10, 14}}); CHECK(b.IsEmpty()); } TEST_F(DisjointAllocationPoolTest, ExtractExact) { DisjointAllocationPool a = Make({{1, 5}, {10, 15}}); DisjointAllocationPool b = a.Allocate(5); CheckLooksLike(a, {{1, 5}}); CheckLooksLike(b, {{10, 15}}); } TEST_F(DisjointAllocationPoolTest, Merging) { DisjointAllocationPool a = Make({{10, 15}, {20, 25}}); a.Release(Make({{15, 20}})); CheckLooksLike(a, {{10, 25}}); } TEST_F(DisjointAllocationPoolTest, MergingMore) { DisjointAllocationPool a = Make({{10, 15}, {20, 25}, {30, 35}}); a.Release(Make({{15, 20}, {25, 30}})); CheckLooksLike(a, {{10, 35}}); } TEST_F(DisjointAllocationPoolTest, MergingSkip) { DisjointAllocationPool a = Make({{10, 15}, {20, 25}, {30, 35}}); a.Release(Make({{25, 30}})); CheckLooksLike(a, {{10, 15}, {20, 35}}); } TEST_F(DisjointAllocationPoolTest, MergingSkipLargerSrc) { DisjointAllocationPool a = Make({{10, 15}, {20, 25}, {30, 35}}); a.Release(Make({{25, 30}, {35, 40}})); CheckLooksLike(a, {{10, 15}, {20, 40}}); } TEST_F(DisjointAllocationPoolTest, MergingSkipLargerSrcWithGap) { DisjointAllocationPool a = Make({{10, 15}, {20, 25}, {30, 35}}); a.Release(Make({{25, 30}, {36, 40}})); CheckLooksLike(a, {{10, 15}, {20, 35}, {36, 40}}); } } // namespace wasm } // namespace internal } // namespace v8