Home | History | Annotate | Download | only in compiler
      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 
     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 
     26 ZonePool::StatsScope::~StatsScope() {
     27   DCHECK_EQ(zone_pool_->stats_.back(), this);
     28   zone_pool_->stats_.pop_back();
     29 }
     30 
     31 
     32 size_t ZonePool::StatsScope::GetMaxAllocatedBytes() {
     33   return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
     34 }
     35 
     36 
     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 
     51 size_t ZonePool::StatsScope::GetTotalAllocatedBytes() {
     52   return zone_pool_->GetTotalAllocatedBytes() - total_allocated_bytes_at_start_;
     53 }
     54 
     55 
     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 
     67 ZonePool::ZonePool(base::AccountingAllocator* allocator)
     68     : max_allocated_bytes_(0), total_deleted_bytes_(0), allocator_(allocator) {}
     69 
     70 ZonePool::~ZonePool() {
     71   DCHECK(used_.empty());
     72   DCHECK(stats_.empty());
     73   for (Zone* zone : unused_) {
     74     delete zone;
     75   }
     76 }
     77 
     78 
     79 size_t ZonePool::GetMaxAllocatedBytes() {
     80   return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
     81 }
     82 
     83 
     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 
     93 size_t ZonePool::GetTotalAllocatedBytes() {
     94   return total_deleted_bytes_ + GetCurrentAllocatedBytes();
     95 }
     96 
     97 
     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 
    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