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 <algorithm>
6
7#include "src/compiler/zone-stats.h"
8
9namespace v8 {
10namespace internal {
11namespace compiler {
12
13ZoneStats::StatsScope::StatsScope(ZoneStats* zone_stats)
14    : zone_stats_(zone_stats),
15      total_allocated_bytes_at_start_(zone_stats->GetTotalAllocatedBytes()),
16      max_allocated_bytes_(0) {
17  zone_stats_->stats_.push_back(this);
18  for (Zone* zone : zone_stats_->zones_) {
19    size_t size = static_cast<size_t>(zone->allocation_size());
20    std::pair<InitialValues::iterator, bool> res =
21        initial_values_.insert(std::make_pair(zone, size));
22    USE(res);
23    DCHECK(res.second);
24  }
25}
26
27ZoneStats::StatsScope::~StatsScope() {
28  DCHECK_EQ(zone_stats_->stats_.back(), this);
29  zone_stats_->stats_.pop_back();
30}
31
32size_t ZoneStats::StatsScope::GetMaxAllocatedBytes() {
33  return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
34}
35
36size_t ZoneStats::StatsScope::GetCurrentAllocatedBytes() {
37  size_t total = 0;
38  for (Zone* zone : zone_stats_->zones_) {
39    total += static_cast<size_t>(zone->allocation_size());
40    // Adjust for initial values.
41    InitialValues::iterator it = initial_values_.find(zone);
42    if (it != initial_values_.end()) {
43      total -= it->second;
44    }
45  }
46  return total;
47}
48
49size_t ZoneStats::StatsScope::GetTotalAllocatedBytes() {
50  return zone_stats_->GetTotalAllocatedBytes() -
51         total_allocated_bytes_at_start_;
52}
53
54void ZoneStats::StatsScope::ZoneReturned(Zone* zone) {
55  size_t current_total = GetCurrentAllocatedBytes();
56  // Update max.
57  max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
58  // Drop zone from initial value map.
59  InitialValues::iterator it = initial_values_.find(zone);
60  if (it != initial_values_.end()) {
61    initial_values_.erase(it);
62  }
63}
64
65ZoneStats::ZoneStats(AccountingAllocator* allocator)
66    : max_allocated_bytes_(0), total_deleted_bytes_(0), allocator_(allocator) {}
67
68ZoneStats::~ZoneStats() {
69  DCHECK(zones_.empty());
70  DCHECK(stats_.empty());
71}
72
73size_t ZoneStats::GetMaxAllocatedBytes() const {
74  return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
75}
76
77size_t ZoneStats::GetCurrentAllocatedBytes() const {
78  size_t total = 0;
79  for (Zone* zone : zones_) {
80    total += static_cast<size_t>(zone->allocation_size());
81  }
82  return total;
83}
84
85size_t ZoneStats::GetTotalAllocatedBytes() const {
86  return total_deleted_bytes_ + GetCurrentAllocatedBytes();
87}
88
89Zone* ZoneStats::NewEmptyZone(const char* zone_name,
90                              bool support_zone_compression) {
91  Zone* zone = new Zone(allocator_, zone_name, support_zone_compression);
92  zones_.push_back(zone);
93  return zone;
94}
95
96void ZoneStats::ReturnZone(Zone* zone) {
97  size_t current_total = GetCurrentAllocatedBytes();
98  // Update max.
99  max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
100  // Update stats.
101  for (StatsScope* stat_scope : stats_) {
102    stat_scope->ZoneReturned(zone);
103  }
104  // Remove from used.
105  Zones::iterator it = std::find(zones_.begin(), zones_.end(), zone);
106  DCHECK(it != zones_.end());
107  zones_.erase(it);
108  total_deleted_bytes_ += static_cast<size_t>(zone->allocation_size());
109  delete zone;
110}
111
112}  // namespace compiler
113}  // namespace internal
114}  // namespace v8
115