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() {} 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 ZonePool zone_pool_; 42 base::RandomNumberGenerator rng; 43 }; 44 45 46 TEST_F(ZonePoolTest, Empty) { 47 ExpectForPool(0, 0, 0); 48 { 49 ZonePool::StatsScope stats(zone_pool()); 50 Expect(&stats, 0, 0, 0); 51 } 52 ExpectForPool(0, 0, 0); 53 { 54 ZonePool::Scope scope(zone_pool()); 55 scope.zone(); 56 } 57 ExpectForPool(0, 0, 0); 58 } 59 60 61 TEST_F(ZonePoolTest, MultipleZonesWithDeletion) { 62 static const size_t kArraySize = 10; 63 64 ZonePool::Scope* scopes[kArraySize]; 65 66 // Initialize. 67 size_t before_stats = 0; 68 for (size_t i = 0; i < kArraySize; ++i) { 69 scopes[i] = new ZonePool::Scope(zone_pool()); 70 before_stats += Allocate(scopes[i]->zone()); // Add some stuff. 71 } 72 73 ExpectForPool(before_stats, before_stats, before_stats); 74 75 ZonePool::StatsScope stats(zone_pool()); 76 77 size_t before_deletion = 0; 78 for (size_t i = 0; i < kArraySize; ++i) { 79 before_deletion += Allocate(scopes[i]->zone()); // Add some stuff. 80 } 81 82 Expect(&stats, before_deletion, before_deletion, before_deletion); 83 ExpectForPool(before_stats + before_deletion, before_stats + before_deletion, 84 before_stats + before_deletion); 85 86 // Delete the scopes and create new ones. 87 for (size_t i = 0; i < kArraySize; ++i) { 88 delete scopes[i]; 89 scopes[i] = new ZonePool::Scope(zone_pool()); 90 } 91 92 Expect(&stats, 0, before_deletion, before_deletion); 93 ExpectForPool(0, before_stats + before_deletion, 94 before_stats + before_deletion); 95 96 size_t after_deletion = 0; 97 for (size_t i = 0; i < kArraySize; ++i) { 98 after_deletion += Allocate(scopes[i]->zone()); // Add some stuff. 99 } 100 101 Expect(&stats, after_deletion, std::max(after_deletion, before_deletion), 102 before_deletion + after_deletion); 103 ExpectForPool(after_deletion, 104 std::max(after_deletion, before_stats + before_deletion), 105 before_stats + before_deletion + after_deletion); 106 107 // Cleanup. 108 for (size_t i = 0; i < kArraySize; ++i) { 109 delete scopes[i]; 110 } 111 112 Expect(&stats, 0, std::max(after_deletion, before_deletion), 113 before_deletion + after_deletion); 114 ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion), 115 before_stats + before_deletion + after_deletion); 116 } 117 118 119 TEST_F(ZonePoolTest, SimpleAllocationLoop) { 120 int runs = 20; 121 size_t total_allocated = 0; 122 size_t max_loop_allocation = 0; 123 ZonePool::StatsScope outer_stats(zone_pool()); 124 { 125 ZonePool::Scope outer_scope(zone_pool()); 126 size_t outer_allocated = 0; 127 for (int i = 0; i < runs; ++i) { 128 { 129 size_t bytes = Allocate(outer_scope.zone()); 130 outer_allocated += bytes; 131 total_allocated += bytes; 132 } 133 ZonePool::StatsScope inner_stats(zone_pool()); 134 size_t allocated = 0; 135 { 136 ZonePool::Scope inner_scope(zone_pool()); 137 for (int j = 0; j < 20; ++j) { 138 size_t bytes = Allocate(inner_scope.zone()); 139 allocated += bytes; 140 total_allocated += bytes; 141 max_loop_allocation = 142 std::max(max_loop_allocation, outer_allocated + allocated); 143 Expect(&inner_stats, allocated, allocated, allocated); 144 Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation, 145 total_allocated); 146 ExpectForPool(outer_allocated + allocated, max_loop_allocation, 147 total_allocated); 148 } 149 } 150 Expect(&inner_stats, 0, allocated, allocated); 151 Expect(&outer_stats, outer_allocated, max_loop_allocation, 152 total_allocated); 153 ExpectForPool(outer_allocated, max_loop_allocation, total_allocated); 154 } 155 } 156 Expect(&outer_stats, 0, max_loop_allocation, total_allocated); 157 ExpectForPool(0, max_loop_allocation, total_allocated); 158 } 159 160 } // namespace compiler 161 } // namespace internal 162 } // namespace v8 163