LCOV - code coverage report
Current view: top level - src - basic-block-profiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 29 60 48.3 %
Date: 2019-04-17 Functions: 9 14 64.3 %

          Line data    Source code
       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/basic-block-profiler.h"
       6             : 
       7             : #include <algorithm>
       8             : #include <numeric>
       9             : #include <sstream>
      10             : 
      11             : #include "src/base/lazy-instance.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16          72 : DEFINE_LAZY_LEAKY_OBJECT_GETTER(BasicBlockProfiler, BasicBlockProfiler::Get)
      17             : 
      18           8 : BasicBlockProfiler::Data::Data(size_t n_blocks)
      19             :     : n_blocks_(n_blocks),
      20             :       block_rpo_numbers_(n_blocks_),
      21          16 :       counts_(n_blocks_, 0) {}
      22             : 
      23           8 : static void InsertIntoString(std::ostringstream* os, std::string* string) {
      24           8 :   string->insert(0, os->str());
      25           8 : }
      26             : 
      27             : static void InsertIntoString(const char* data, std::string* string) {
      28           8 :   string->insert(0, data);
      29             : }
      30             : 
      31           0 : void BasicBlockProfiler::Data::SetCode(std::ostringstream* os) {
      32           0 :   InsertIntoString(os, &code_);
      33           0 : }
      34             : 
      35           8 : void BasicBlockProfiler::Data::SetFunctionName(std::unique_ptr<char[]> name) {
      36           8 :   InsertIntoString(name.get(), &function_name_);
      37           8 : }
      38             : 
      39           8 : void BasicBlockProfiler::Data::SetSchedule(std::ostringstream* os) {
      40           8 :   InsertIntoString(os, &schedule_);
      41           8 : }
      42             : 
      43          48 : void BasicBlockProfiler::Data::SetBlockRpoNumber(size_t offset,
      44             :                                                  int32_t block_rpo) {
      45             :   DCHECK(offset < n_blocks_);
      46          48 :   block_rpo_numbers_[offset] = block_rpo;
      47          48 : }
      48             : 
      49          48 : intptr_t BasicBlockProfiler::Data::GetCounterAddress(size_t offset) {
      50             :   DCHECK(offset < n_blocks_);
      51          48 :   return reinterpret_cast<intptr_t>(&(counts_[offset]));
      52             : }
      53             : 
      54             : 
      55           0 : void BasicBlockProfiler::Data::ResetCounts() {
      56         260 :   for (size_t i = 0; i < n_blocks_; ++i) {
      57         120 :     counts_[i] = 0;
      58             :   }
      59           0 : }
      60             : 
      61           8 : BasicBlockProfiler::Data* BasicBlockProfiler::NewData(size_t n_blocks) {
      62           8 :   base::MutexGuard lock(&data_list_mutex_);
      63           8 :   Data* data = new Data(n_blocks);
      64           8 :   data_list_.push_back(data);
      65          16 :   return data;
      66             : }
      67             : 
      68             : 
      69           0 : BasicBlockProfiler::~BasicBlockProfiler() {
      70           0 :   for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
      71           0 :     delete (*i);
      72             :   }
      73           0 : }
      74             : 
      75             : 
      76          20 : void BasicBlockProfiler::ResetCounts() {
      77          40 :   for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
      78          20 :     (*i)->ResetCounts();
      79             :   }
      80          20 : }
      81             : 
      82             : 
      83           0 : std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler& p) {
      84             :   os << "---- Start Profiling Data ----" << std::endl;
      85             :   typedef BasicBlockProfiler::DataList::const_iterator iterator;
      86           0 :   for (iterator i = p.data_list_.begin(); i != p.data_list_.end(); ++i) {
      87           0 :     os << **i;
      88             :   }
      89             :   os << "---- End Profiling Data ----" << std::endl;
      90           0 :   return os;
      91             : }
      92             : 
      93             : 
      94           0 : std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler::Data& d) {
      95             :   int block_count_sum = std::accumulate(d.counts_.begin(), d.counts_.end(), 0);
      96           0 :   if (block_count_sum == 0) return os;
      97             :   const char* name = "unknown function";
      98           0 :   if (!d.function_name_.empty()) {
      99             :     name = d.function_name_.c_str();
     100             :   }
     101           0 :   if (!d.schedule_.empty()) {
     102           0 :     os << "schedule for " << name << " (B0 entered " << d.counts_[0]
     103             :        << " times)" << std::endl;
     104           0 :     os << d.schedule_.c_str() << std::endl;
     105             :   }
     106           0 :   os << "block counts for " << name << ":" << std::endl;
     107             :   std::vector<std::pair<int32_t, uint32_t>> pairs;
     108           0 :   pairs.reserve(d.n_blocks_);
     109           0 :   for (size_t i = 0; i < d.n_blocks_; ++i) {
     110           0 :     pairs.push_back(std::make_pair(d.block_rpo_numbers_[i], d.counts_[i]));
     111             :   }
     112             :   std::sort(pairs.begin(), pairs.end(),
     113             :             [=](std::pair<int32_t, uint32_t> left,
     114             :                 std::pair<int32_t, uint32_t> right) {
     115           0 :               if (right.second == left.second)
     116           0 :                 return left.first < right.first;
     117           0 :               return right.second < left.second;
     118             :             });
     119           0 :   for (auto it : pairs) {
     120           0 :     if (it.second == 0) break;
     121           0 :     os << "block B" << it.first << " : " << it.second << std::endl;
     122             :   }
     123             :   os << std::endl;
     124           0 :   if (!d.code_.empty()) {
     125           0 :     os << d.code_.c_str() << std::endl;
     126             :   }
     127             :   return os;
     128             : }
     129             : 
     130             : }  // namespace internal
     131             : }  // namespace v8

Generated by: LCOV version 1.10