1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <ostream> // NOLINT(readability/streams) 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <vector> 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/base/platform/platform.h" 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compilation-statistics.h" 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CompilationStatistics::RecordPhaseStats(const char* phase_kind_name, 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const char* phase_name, 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const BasicStats& stats) { 1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch base::LockGuard<base::Mutex> guard(&record_mutex_); 1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::string phase_name_str(phase_name); 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto it = phase_map_.find(phase_name_str); 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (it == phase_map_.end()) { 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PhaseStats phase_stats(phase_map_.size(), phase_kind_name); 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first; 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier it->second.Accumulate(stats); 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name, 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const BasicStats& stats) { 3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch base::LockGuard<base::Mutex> guard(&record_mutex_); 3262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::string phase_kind_name_str(phase_kind_name); 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto it = phase_kind_map_.find(phase_kind_name_str); 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (it == phase_kind_map_.end()) { 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PhaseKindStats phase_kind_stats(phase_kind_map_.size()); 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier it = phase_kind_map_.insert(std::make_pair(phase_kind_name_str, 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier phase_kind_stats)).first; 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier it->second.Accumulate(stats); 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CompilationStatistics::RecordTotalStats(size_t source_size, 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const BasicStats& stats) { 4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch base::LockGuard<base::Mutex> guard(&record_mutex_); 4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier source_size += source_size; 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier total_stats_.Accumulate(stats); 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) { 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier delta_ += stats.delta_; 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier total_allocated_bytes_ += stats.total_allocated_bytes_; 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (stats.absolute_max_allocated_bytes_ > absolute_max_allocated_bytes_) { 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier absolute_max_allocated_bytes_ = stats.absolute_max_allocated_bytes_; 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier max_allocated_bytes_ = stats.max_allocated_bytes_; 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function_name_ = stats.function_name_; 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 6313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic void WriteLine(std::ostream& os, bool machine_format, const char* name, 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const CompilationStatistics::BasicStats& stats, 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const CompilationStatistics::BasicStats& total_stats) { 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const size_t kBufferSize = 128; 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char buffer[kBufferSize]; 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double ms = stats.delta_.InMillisecondsF(); 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double percent = stats.delta_.PercentOf(total_stats.delta_); 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double size_percent = 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<double>(stats.total_allocated_bytes_ * 100) / 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<double>(total_stats.total_allocated_bytes_); 7413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (machine_format) { 7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::OS::SNPrintF(buffer, kBufferSize, 7613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch "\"%s_time\"=%.3f\n\"%s_space\"=%" PRIuS, name, ms, name, 7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stats.total_allocated_bytes_); 7813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch os << buffer; 7913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 8013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::OS::SNPrintF(buffer, kBufferSize, "%28s %10.3f (%5.1f%%) %10" PRIuS 8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch " (%5.1f%%) %10" PRIuS " %10" PRIuS, 8213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch name, ms, percent, stats.total_allocated_bytes_, 8313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch size_percent, stats.max_allocated_bytes_, 8413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stats.absolute_max_allocated_bytes_); 8513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 8613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch os << buffer; 8713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (stats.function_name_.size() > 0) { 8813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch os << " " << stats.function_name_.c_str(); 8913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 9013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch os << std::endl; 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void WriteFullLine(std::ostream& os) { 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << "--------------------------------------------------------" 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "--------------------------------------------------------\n"; 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void WriteHeader(std::ostream& os) { 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteFullLine(os); 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch os << " Turbonfan phase Time (ms) " 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch << " Space (bytes) Function\n" 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch << " " 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch << " Total Max. Abs. max.\n"; 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier WriteFullLine(os); 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void WritePhaseKindBreak(std::ostream& os) { 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << " ---------------------------" 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "--------------------------------------------------------\n"; 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstd::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& ps) { 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // pointers into them. 11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const CompilationStatistics& s = ps.s; 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator> 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SortedPhaseKinds; 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size()); 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end(); 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ++it) { 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sorted_phase_kinds[it->second.insert_order_] = it; 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier typedef std::vector<CompilationStatistics::PhaseMap::const_iterator> 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SortedPhases; 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SortedPhases sorted_phases(s.phase_map_.size()); 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) { 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sorted_phases[it->second.insert_order_] = it; 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!ps.machine_output) WriteHeader(os); 13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (const auto& phase_kind_it : sorted_phase_kinds) { 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const auto& phase_kind_name = phase_kind_it->first; 13913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!ps.machine_output) { 14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (const auto& phase_it : sorted_phases) { 14113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const auto& phase_stats = phase_it->second; 14213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (phase_stats.phase_kind_name_ != phase_kind_name) continue; 14313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const auto& phase_name = phase_it->first; 14413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch WriteLine(os, ps.machine_output, phase_name.c_str(), phase_stats, 14513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch s.total_stats_); 14613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 14713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch WritePhaseKindBreak(os); 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const auto& phase_kind_stats = phase_kind_it->second; 15013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch WriteLine(os, ps.machine_output, phase_kind_name.c_str(), phase_kind_stats, 15113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch s.total_stats_); 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << std::endl; 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 15513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!ps.machine_output) WriteFullLine(os); 15613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch WriteLine(os, ps.machine_output, "totals", s.total_stats_, s.total_stats_); 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return os; 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 163