compilation-statistics.cc 5.77 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
#include <ostream>  // NOLINT(readability/streams)
6 7 8 9 10 11 12 13 14 15 16
#include <vector>

#include "src/base/platform/platform.h"
#include "src/compilation-statistics.h"

namespace v8 {
namespace internal {

void CompilationStatistics::RecordPhaseStats(const char* phase_kind_name,
                                             const char* phase_name,
                                             const BasicStats& stats) {
17
  base::MutexGuard guard(&record_mutex_);
18

19 20 21 22 23 24 25 26 27 28 29 30
  std::string phase_name_str(phase_name);
  auto it = phase_map_.find(phase_name_str);
  if (it == phase_map_.end()) {
    PhaseStats phase_stats(phase_map_.size(), phase_kind_name);
    it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first;
  }
  it->second.Accumulate(stats);
}


void CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name,
                                                 const BasicStats& stats) {
31
  base::MutexGuard guard(&record_mutex_);
32

33 34 35 36 37 38 39 40 41 42 43 44 45
  std::string phase_kind_name_str(phase_kind_name);
  auto it = phase_kind_map_.find(phase_kind_name_str);
  if (it == phase_kind_map_.end()) {
    PhaseKindStats phase_kind_stats(phase_kind_map_.size());
    it = phase_kind_map_.insert(std::make_pair(phase_kind_name_str,
                                               phase_kind_stats)).first;
  }
  it->second.Accumulate(stats);
}


void CompilationStatistics::RecordTotalStats(size_t source_size,
                                             const BasicStats& stats) {
46
  base::MutexGuard guard(&record_mutex_);
47

48 49 50 51 52 53 54 55
  source_size += source_size;
  total_stats_.Accumulate(stats);
}


void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
  delta_ += stats.delta_;
  total_allocated_bytes_ += stats.total_allocated_bytes_;
56 57
  if (stats.absolute_max_allocated_bytes_ > absolute_max_allocated_bytes_) {
    absolute_max_allocated_bytes_ = stats.absolute_max_allocated_bytes_;
58 59 60 61 62
    max_allocated_bytes_ = stats.max_allocated_bytes_;
    function_name_ = stats.function_name_;
  }
}

63
static void WriteLine(std::ostream& os, bool machine_format, const char* name,
64 65 66 67 68 69 70 71 72 73
                      const CompilationStatistics::BasicStats& stats,
                      const CompilationStatistics::BasicStats& total_stats) {
  const size_t kBufferSize = 128;
  char buffer[kBufferSize];

  double ms = stats.delta_.InMillisecondsF();
  double percent = stats.delta_.PercentOf(total_stats.delta_);
  double size_percent =
      static_cast<double>(stats.total_allocated_bytes_ * 100) /
      static_cast<double>(total_stats.total_allocated_bytes_);
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
  if (machine_format) {
    base::OS::SNPrintF(buffer, kBufferSize,
                       "\"%s_time\"=%.3f\n\"%s_space\"=%" PRIuS, name, ms, name,
                       stats.total_allocated_bytes_);
    os << buffer;
  } else {
    base::OS::SNPrintF(buffer, kBufferSize, "%28s %10.3f (%5.1f%%)  %10" PRIuS
                                            " (%5.1f%%) %10" PRIuS " %10" PRIuS,
                       name, ms, percent, stats.total_allocated_bytes_,
                       size_percent, stats.max_allocated_bytes_,
                       stats.absolute_max_allocated_bytes_);

    os << buffer;
    if (stats.function_name_.size() > 0) {
      os << "   " << stats.function_name_.c_str();
    }
    os << std::endl;
91 92 93 94 95
  }
}


static void WriteFullLine(std::ostream& os) {
96 97
  os << "--------------------------------------------------------"
        "--------------------------------------------------------\n";
98 99 100 101 102
}


static void WriteHeader(std::ostream& os) {
  WriteFullLine(os);
103
  os << "             Turbofan phase         Time (ms)             "
104 105 106
     << "          Space (bytes)             Function\n"
     << "                                                         "
     << "  Total          Max.     Abs. max.\n";
107 108 109 110 111
  WriteFullLine(os);
}


static void WritePhaseKindBreak(std::ostream& os) {
112 113
  os << "                             ---------------------------"
        "--------------------------------------------------------\n";
114 115
}

116
std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& ps) {
117 118
  // phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
  // pointers into them.
119
  const CompilationStatistics& s = ps.s;
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135

  typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator>
      SortedPhaseKinds;
  SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size());
  for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end();
       ++it) {
    sorted_phase_kinds[it->second.insert_order_] = it;
  }

  typedef std::vector<CompilationStatistics::PhaseMap::const_iterator>
      SortedPhases;
  SortedPhases sorted_phases(s.phase_map_.size());
  for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) {
    sorted_phases[it->second.insert_order_] = it;
  }

136
  if (!ps.machine_output) WriteHeader(os);
137
  for (const auto& phase_kind_it : sorted_phase_kinds) {
138
    const auto& phase_kind_name = phase_kind_it->first;
139
    if (!ps.machine_output) {
140
      for (const auto& phase_it : sorted_phases) {
141 142 143 144 145 146 147
        const auto& phase_stats = phase_it->second;
        if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
        const auto& phase_name = phase_it->first;
        WriteLine(os, ps.machine_output, phase_name.c_str(), phase_stats,
                  s.total_stats_);
      }
      WritePhaseKindBreak(os);
148 149
    }
    const auto& phase_kind_stats = phase_kind_it->second;
150 151
    WriteLine(os, ps.machine_output, phase_kind_name.c_str(), phase_kind_stats,
              s.total_stats_);
152 153
    os << std::endl;
  }
154 155 156

  if (!ps.machine_output) WriteFullLine(os);
  WriteLine(os, ps.machine_output, "totals", s.total_stats_, s.total_stats_);
157 158 159 160 161 162

  return os;
}

}  // namespace internal
}  // namespace v8