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 (auto 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 
     68 ZonePool::ZonePool() : max_allocated_bytes_(0), total_deleted_bytes_(0) {}
     69 
     70 
     71 ZonePool::~ZonePool() {
     72   DCHECK(used_.empty());
     73   DCHECK(stats_.empty());
     74   for (Zone* zone : unused_) {
     75     delete zone;
     76   }
     77 }
     78 
     79 
     80 size_t ZonePool::GetMaxAllocatedBytes() {
     81   return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
     82 }
     83 
     84 
     85 size_t ZonePool::GetCurrentAllocatedBytes() {
     86   size_t total = 0;
     87   for (Zone* zone : used_) {
     88     total += static_cast<size_t>(zone->allocation_size());
     89   }
     90   return total;
     91 }
     92 
     93 
     94 size_t ZonePool::GetTotalAllocatedBytes() {
     95   return total_deleted_bytes_ + GetCurrentAllocatedBytes();
     96 }
     97 
     98 
     99 Zone* ZonePool::NewEmptyZone() {
    100   Zone* zone;
    101   // Grab a zone from pool if possible.
    102   if (!unused_.empty()) {
    103     zone = unused_.back();
    104     unused_.pop_back();
    105   } else {
    106     zone = new Zone();
    107   }
    108   used_.push_back(zone);
    109   DCHECK_EQ(0u, zone->allocation_size());
    110   return zone;
    111 }
    112 
    113 
    114 void ZonePool::ReturnZone(Zone* zone) {
    115   size_t current_total = GetCurrentAllocatedBytes();
    116   // Update max.
    117   max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
    118   // Update stats.
    119   for (auto stat_scope : stats_) {
    120     stat_scope->ZoneReturned(zone);
    121   }
    122   // Remove from used.
    123   Used::iterator it = std::find(used_.begin(), used_.end(), zone);
    124   DCHECK(it != used_.end());
    125   used_.erase(it);
    126   total_deleted_bytes_ += static_cast<size_t>(zone->allocation_size());
    127   // Delete zone or clear and stash on unused_.
    128   if (unused_.size() >= kMaxUnusedSize) {
    129     delete zone;
    130   } else {
    131     zone->DeleteAll();
    132     DCHECK_EQ(0u, zone->allocation_size());
    133     unused_.push_back(zone);
    134   }
    135 }
    136 
    137 }  // namespace compiler
    138 }  // namespace internal
    139 }  // namespace v8
    140