// Copyright 2014 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 "src/base/utils/random-number-generator.h" #include "src/compiler/zone-pool.h" #include "test/unittests/test-utils.h" namespace v8 { namespace internal { namespace compiler { class ZonePoolTest : public TestWithIsolate { public: ZonePoolTest() : zone_pool_(&allocator_) {} protected: ZonePool* zone_pool() { return &zone_pool_; } void ExpectForPool(size_t current, size_t max, size_t total) { ASSERT_EQ(current, zone_pool()->GetCurrentAllocatedBytes()); ASSERT_EQ(max, zone_pool()->GetMaxAllocatedBytes()); ASSERT_EQ(total, zone_pool()->GetTotalAllocatedBytes()); } void Expect(ZonePool::StatsScope* stats, size_t current, size_t max, size_t total) { ASSERT_EQ(current, stats->GetCurrentAllocatedBytes()); ASSERT_EQ(max, stats->GetMaxAllocatedBytes()); ASSERT_EQ(total, stats->GetTotalAllocatedBytes()); } size_t Allocate(Zone* zone) { size_t bytes = rng.NextInt(25) + 7; size_t size_before = zone->allocation_size(); zone->New(bytes); return zone->allocation_size() - size_before; } private: base::AccountingAllocator allocator_; ZonePool zone_pool_; base::RandomNumberGenerator rng; }; TEST_F(ZonePoolTest, Empty) { ExpectForPool(0, 0, 0); { ZonePool::StatsScope stats(zone_pool()); Expect(&stats, 0, 0, 0); } ExpectForPool(0, 0, 0); { ZonePool::Scope scope(zone_pool()); scope.zone(); } ExpectForPool(0, 0, 0); } TEST_F(ZonePoolTest, MultipleZonesWithDeletion) { static const size_t kArraySize = 10; ZonePool::Scope* scopes[kArraySize]; // Initialize. size_t before_stats = 0; for (size_t i = 0; i < kArraySize; ++i) { scopes[i] = new ZonePool::Scope(zone_pool()); before_stats += Allocate(scopes[i]->zone()); // Add some stuff. } ExpectForPool(before_stats, before_stats, before_stats); ZonePool::StatsScope stats(zone_pool()); size_t before_deletion = 0; for (size_t i = 0; i < kArraySize; ++i) { before_deletion += Allocate(scopes[i]->zone()); // Add some stuff. } Expect(&stats, before_deletion, before_deletion, before_deletion); ExpectForPool(before_stats + before_deletion, before_stats + before_deletion, before_stats + before_deletion); // Delete the scopes and create new ones. for (size_t i = 0; i < kArraySize; ++i) { delete scopes[i]; scopes[i] = new ZonePool::Scope(zone_pool()); } Expect(&stats, 0, before_deletion, before_deletion); ExpectForPool(0, before_stats + before_deletion, before_stats + before_deletion); size_t after_deletion = 0; for (size_t i = 0; i < kArraySize; ++i) { after_deletion += Allocate(scopes[i]->zone()); // Add some stuff. } Expect(&stats, after_deletion, std::max(after_deletion, before_deletion), before_deletion + after_deletion); ExpectForPool(after_deletion, std::max(after_deletion, before_stats + before_deletion), before_stats + before_deletion + after_deletion); // Cleanup. for (size_t i = 0; i < kArraySize; ++i) { delete scopes[i]; } Expect(&stats, 0, std::max(after_deletion, before_deletion), before_deletion + after_deletion); ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion), before_stats + before_deletion + after_deletion); } TEST_F(ZonePoolTest, SimpleAllocationLoop) { int runs = 20; size_t total_allocated = 0; size_t max_loop_allocation = 0; ZonePool::StatsScope outer_stats(zone_pool()); { ZonePool::Scope outer_scope(zone_pool()); size_t outer_allocated = 0; for (int i = 0; i < runs; ++i) { { size_t bytes = Allocate(outer_scope.zone()); outer_allocated += bytes; total_allocated += bytes; } ZonePool::StatsScope inner_stats(zone_pool()); size_t allocated = 0; { ZonePool::Scope inner_scope(zone_pool()); for (int j = 0; j < 20; ++j) { size_t bytes = Allocate(inner_scope.zone()); allocated += bytes; total_allocated += bytes; max_loop_allocation = std::max(max_loop_allocation, outer_allocated + allocated); Expect(&inner_stats, allocated, allocated, allocated); Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation, total_allocated); ExpectForPool(outer_allocated + allocated, max_loop_allocation, total_allocated); } } Expect(&inner_stats, 0, allocated, allocated); Expect(&outer_stats, outer_allocated, max_loop_allocation, total_allocated); ExpectForPool(outer_allocated, max_loop_allocation, total_allocated); } } Expect(&outer_stats, 0, max_loop_allocation, total_allocated); ExpectForPool(0, max_loop_allocation, total_allocated); } } // namespace compiler } // namespace internal } // namespace v8