• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/compiler/zone-pool.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10 
StatsScope(ZonePool * zone_pool)11 ZonePool::StatsScope::StatsScope(ZonePool* zone_pool)
12     : zone_pool_(zone_pool),
13       total_allocated_bytes_at_start_(zone_pool->GetTotalAllocatedBytes()),
14       max_allocated_bytes_(0) {
15   zone_pool_->stats_.push_back(this);
16   for (Zone* zone : zone_pool_->used_) {
17     size_t size = static_cast<size_t>(zone->allocation_size());
18     std::pair<InitialValues::iterator, bool> res =
19         initial_values_.insert(std::make_pair(zone, size));
20     USE(res);
21     DCHECK(res.second);
22   }
23 }
24 
25 
~StatsScope()26 ZonePool::StatsScope::~StatsScope() {
27   DCHECK_EQ(zone_pool_->stats_.back(), this);
28   zone_pool_->stats_.pop_back();
29 }
30 
31 
GetMaxAllocatedBytes()32 size_t ZonePool::StatsScope::GetMaxAllocatedBytes() {
33   return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
34 }
35 
36 
GetCurrentAllocatedBytes()37 size_t ZonePool::StatsScope::GetCurrentAllocatedBytes() {
38   size_t total = 0;
39   for (Zone* zone : zone_pool_->used_) {
40     total += static_cast<size_t>(zone->allocation_size());
41     // Adjust for initial values.
42     InitialValues::iterator it = initial_values_.find(zone);
43     if (it != initial_values_.end()) {
44       total -= it->second;
45     }
46   }
47   return total;
48 }
49 
50 
GetTotalAllocatedBytes()51 size_t ZonePool::StatsScope::GetTotalAllocatedBytes() {
52   return zone_pool_->GetTotalAllocatedBytes() - total_allocated_bytes_at_start_;
53 }
54 
55 
ZoneReturned(Zone * zone)56 void ZonePool::StatsScope::ZoneReturned(Zone* zone) {
57   size_t current_total = GetCurrentAllocatedBytes();
58   // Update max.
59   max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
60   // Drop zone from initial value map.
61   InitialValues::iterator it = initial_values_.find(zone);
62   if (it != initial_values_.end()) {
63     initial_values_.erase(it);
64   }
65 }
66 
ZonePool(base::AccountingAllocator * allocator)67 ZonePool::ZonePool(base::AccountingAllocator* allocator)
68     : max_allocated_bytes_(0), total_deleted_bytes_(0), allocator_(allocator) {}
69 
~ZonePool()70 ZonePool::~ZonePool() {
71   DCHECK(used_.empty());
72   DCHECK(stats_.empty());
73   for (Zone* zone : unused_) {
74     delete zone;
75   }
76 }
77 
78 
GetMaxAllocatedBytes()79 size_t ZonePool::GetMaxAllocatedBytes() {
80   return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
81 }
82 
83 
GetCurrentAllocatedBytes()84 size_t ZonePool::GetCurrentAllocatedBytes() {
85   size_t total = 0;
86   for (Zone* zone : used_) {
87     total += static_cast<size_t>(zone->allocation_size());
88   }
89   return total;
90 }
91 
92 
GetTotalAllocatedBytes()93 size_t ZonePool::GetTotalAllocatedBytes() {
94   return total_deleted_bytes_ + GetCurrentAllocatedBytes();
95 }
96 
97 
NewEmptyZone()98 Zone* ZonePool::NewEmptyZone() {
99   Zone* zone;
100   // Grab a zone from pool if possible.
101   if (!unused_.empty()) {
102     zone = unused_.back();
103     unused_.pop_back();
104   } else {
105     zone = new Zone(allocator_);
106   }
107   used_.push_back(zone);
108   DCHECK_EQ(0u, zone->allocation_size());
109   return zone;
110 }
111 
112 
ReturnZone(Zone * zone)113 void ZonePool::ReturnZone(Zone* zone) {
114   size_t current_total = GetCurrentAllocatedBytes();
115   // Update max.
116   max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
117   // Update stats.
118   for (StatsScope* stat_scope : stats_) {
119     stat_scope->ZoneReturned(zone);
120   }
121   // Remove from used.
122   Used::iterator it = std::find(used_.begin(), used_.end(), zone);
123   DCHECK(it != used_.end());
124   used_.erase(it);
125   total_deleted_bytes_ += static_cast<size_t>(zone->allocation_size());
126   // Delete zone or clear and stash on unused_.
127   if (unused_.size() >= kMaxUnusedSize) {
128     delete zone;
129   } else {
130     zone->DeleteAll();
131     DCHECK_EQ(0u, zone->allocation_size());
132     unused_.push_back(zone);
133   }
134 }
135 
136 }  // namespace compiler
137 }  // namespace internal
138 }  // namespace v8
139