1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/base/utils/random-number-generator.h" 6 #include "src/compiler/zone-pool.h" 7 #include "test/unittests/test-utils.h" 8 9 namespace v8 { 10 namespace internal { 11 namespace compiler { 12 13 class ZonePoolTest : public TestWithIsolate { 14 public: 15 ZonePoolTest() : zone_pool_(&allocator_) {} 16 17 protected: 18 ZonePool* zone_pool() { return &zone_pool_; } 19 20 void ExpectForPool(size_t current, size_t max, size_t total) { 21 ASSERT_EQ(current, zone_pool()->GetCurrentAllocatedBytes()); 22 ASSERT_EQ(max, zone_pool()->GetMaxAllocatedBytes()); 23 ASSERT_EQ(total, zone_pool()->GetTotalAllocatedBytes()); 24 } 25 26 void Expect(ZonePool::StatsScope* stats, size_t current, size_t max, 27 size_t total) { 28 ASSERT_EQ(current, stats->GetCurrentAllocatedBytes()); 29 ASSERT_EQ(max, stats->GetMaxAllocatedBytes()); 30 ASSERT_EQ(total, stats->GetTotalAllocatedBytes()); 31 } 32 33 size_t Allocate(Zone* zone) { 34 size_t bytes = rng.NextInt(25) + 7; 35 size_t size_before = zone->allocation_size(); 36 zone->New(bytes); 37 return zone->allocation_size() - size_before; 38 } 39 40 private: 41 base::AccountingAllocator allocator_; 42 ZonePool zone_pool_; 43 base::RandomNumberGenerator rng; 44 }; 45 46 47 TEST_F(ZonePoolTest, Empty) { 48 ExpectForPool(0, 0, 0); 49 { 50 ZonePool::StatsScope stats(zone_pool()); 51 Expect(&stats, 0, 0, 0); 52 } 53 ExpectForPool(0, 0, 0); 54 { 55 ZonePool::Scope scope(zone_pool()); 56 scope.zone(); 57 } 58 ExpectForPool(0, 0, 0); 59 } 60 61 62 TEST_F(ZonePoolTest, MultipleZonesWithDeletion) { 63 static const size_t kArraySize = 10; 64 65 ZonePool::Scope* scopes[kArraySize]; 66 67 // Initialize. 68 size_t before_stats = 0; 69 for (size_t i = 0; i < kArraySize; ++i) { 70 scopes[i] = new ZonePool::Scope(zone_pool()); 71 before_stats += Allocate(scopes[i]->zone()); // Add some stuff. 72 } 73 74 ExpectForPool(before_stats, before_stats, before_stats); 75 76 ZonePool::StatsScope stats(zone_pool()); 77 78 size_t before_deletion = 0; 79 for (size_t i = 0; i < kArraySize; ++i) { 80 before_deletion += Allocate(scopes[i]->zone()); // Add some stuff. 81 } 82 83 Expect(&stats, before_deletion, before_deletion, before_deletion); 84 ExpectForPool(before_stats + before_deletion, before_stats + before_deletion, 85 before_stats + before_deletion); 86 87 // Delete the scopes and create new ones. 88 for (size_t i = 0; i < kArraySize; ++i) { 89 delete scopes[i]; 90 scopes[i] = new ZonePool::Scope(zone_pool()); 91 } 92 93 Expect(&stats, 0, before_deletion, before_deletion); 94 ExpectForPool(0, before_stats + before_deletion, 95 before_stats + before_deletion); 96 97 size_t after_deletion = 0; 98 for (size_t i = 0; i < kArraySize; ++i) { 99 after_deletion += Allocate(scopes[i]->zone()); // Add some stuff. 100 } 101 102 Expect(&stats, after_deletion, std::max(after_deletion, before_deletion), 103 before_deletion + after_deletion); 104 ExpectForPool(after_deletion, 105 std::max(after_deletion, before_stats + before_deletion), 106 before_stats + before_deletion + after_deletion); 107 108 // Cleanup. 109 for (size_t i = 0; i < kArraySize; ++i) { 110 delete scopes[i]; 111 } 112 113 Expect(&stats, 0, std::max(after_deletion, before_deletion), 114 before_deletion + after_deletion); 115 ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion), 116 before_stats + before_deletion + after_deletion); 117 } 118 119 120 TEST_F(ZonePoolTest, SimpleAllocationLoop) { 121 int runs = 20; 122 size_t total_allocated = 0; 123 size_t max_loop_allocation = 0; 124 ZonePool::StatsScope outer_stats(zone_pool()); 125 { 126 ZonePool::Scope outer_scope(zone_pool()); 127 size_t outer_allocated = 0; 128 for (int i = 0; i < runs; ++i) { 129 { 130 size_t bytes = Allocate(outer_scope.zone()); 131 outer_allocated += bytes; 132 total_allocated += bytes; 133 } 134 ZonePool::StatsScope inner_stats(zone_pool()); 135 size_t allocated = 0; 136 { 137 ZonePool::Scope inner_scope(zone_pool()); 138 for (int j = 0; j < 20; ++j) { 139 size_t bytes = Allocate(inner_scope.zone()); 140 allocated += bytes; 141 total_allocated += bytes; 142 max_loop_allocation = 143 std::max(max_loop_allocation, outer_allocated + allocated); 144 Expect(&inner_stats, allocated, allocated, allocated); 145 Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation, 146 total_allocated); 147 ExpectForPool(outer_allocated + allocated, max_loop_allocation, 148 total_allocated); 149 } 150 } 151 Expect(&inner_stats, 0, allocated, allocated); 152 Expect(&outer_stats, outer_allocated, max_loop_allocation, 153 total_allocated); 154 ExpectForPool(outer_allocated, max_loop_allocation, total_allocated); 155 } 156 } 157 Expect(&outer_stats, 0, max_loop_allocation, total_allocated); 158 ExpectForPool(0, max_loop_allocation, total_allocated); 159 } 160 161 } // namespace compiler 162 } // namespace internal 163 } // namespace v8 164