| // 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/compiler/zone-stats.h" |
| #include "src/base/utils/random-number-generator.h" |
| #include "test/unittests/test-utils.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace compiler { |
| |
| class ZoneStatsTest : public ::testing::Test { |
| public: |
| ZoneStatsTest() : zone_stats_(&allocator_) {} |
| |
| protected: |
| ZoneStats* zone_stats() { return &zone_stats_; } |
| |
| void ExpectForPool(size_t current, size_t max, size_t total) { |
| ASSERT_EQ(current, zone_stats()->GetCurrentAllocatedBytes()); |
| ASSERT_EQ(max, zone_stats()->GetMaxAllocatedBytes()); |
| ASSERT_EQ(total, zone_stats()->GetTotalAllocatedBytes()); |
| } |
| |
| void Expect(ZoneStats::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: |
| v8::internal::AccountingAllocator allocator_; |
| ZoneStats zone_stats_; |
| base::RandomNumberGenerator rng; |
| }; |
| |
| TEST_F(ZoneStatsTest, Empty) { |
| ExpectForPool(0, 0, 0); |
| { |
| ZoneStats::StatsScope stats(zone_stats()); |
| Expect(&stats, 0, 0, 0); |
| } |
| ExpectForPool(0, 0, 0); |
| { |
| ZoneStats::Scope scope(zone_stats(), ZONE_NAME); |
| scope.zone(); |
| } |
| ExpectForPool(0, 0, 0); |
| } |
| |
| TEST_F(ZoneStatsTest, MultipleZonesWithDeletion) { |
| static const size_t kArraySize = 10; |
| |
| ZoneStats::Scope* scopes[kArraySize]; |
| |
| // Initialize. |
| size_t before_stats = 0; |
| for (size_t i = 0; i < kArraySize; ++i) { |
| scopes[i] = new ZoneStats::Scope(zone_stats(), ZONE_NAME); |
| before_stats += Allocate(scopes[i]->zone()); // Add some stuff. |
| } |
| |
| ExpectForPool(before_stats, before_stats, before_stats); |
| |
| ZoneStats::StatsScope stats(zone_stats()); |
| |
| 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 ZoneStats::Scope(zone_stats(), ZONE_NAME); |
| } |
| |
| 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(ZoneStatsTest, SimpleAllocationLoop) { |
| int runs = 20; |
| size_t total_allocated = 0; |
| size_t max_loop_allocation = 0; |
| ZoneStats::StatsScope outer_stats(zone_stats()); |
| { |
| ZoneStats::Scope outer_scope(zone_stats(), ZONE_NAME); |
| 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; |
| } |
| ZoneStats::StatsScope inner_stats(zone_stats()); |
| size_t allocated = 0; |
| { |
| ZoneStats::Scope inner_scope(zone_stats(), ZONE_NAME); |
| 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 |