| Index: src/counters.cc | 
| diff --git a/src/counters.cc b/src/counters.cc | 
| index e8dea2e0736d58ef5db3b608e1dc1cdca09c70e6..709c6fb15d8b73b84c8980c677371977b095e440 100644 | 
| --- a/src/counters.cc | 
| +++ b/src/counters.cc | 
| @@ -3,6 +3,8 @@ | 
| // found in the LICENSE file. | 
|  | 
| #include "src/counters.h" | 
| + | 
| +#include <iomanip> | 
|  | 
| #include "src/base/platform/platform.h" | 
| #include "src/isolate.h" | 
| @@ -193,5 +195,104 @@ | 
| #undef HM | 
| } | 
|  | 
| +class RuntimeCallStatEntries { | 
| + public: | 
| +  void Print(std::ostream& os) { | 
| +    if (total_call_count > 0) { | 
| +      std::sort(entries.rbegin(), entries.rend()); | 
| +      os << std::setw(50) << "Runtime Function/C++ Builtin" << std::setw(10) | 
| +         << "Time" << std::setw(18) << "Count" << std::endl | 
| +         << std::string(86, '=') << std::endl; | 
| +      for (Entry& entry : entries) { | 
| +        entry.SetTotal(total_time, total_call_count); | 
| +        entry.Print(os); | 
| +      } | 
| +      os << std::string(86, '-') << std::endl; | 
| +      Entry("Total", total_time, total_call_count).Print(os); | 
| +    } | 
| +  } | 
| + | 
| +  void Add(const char* name, base::TimeDelta time, uint32_t count) { | 
| +    entries.push_back(Entry(name, time, count)); | 
| +    total_time += time; | 
| +    total_call_count += count; | 
| +  } | 
| + | 
| + private: | 
| +  class Entry { | 
| +   public: | 
| +    Entry(const char* name, base::TimeDelta time, uint64_t count) | 
| +        : name_(name), | 
| +          time_(time.InMilliseconds()), | 
| +          count_(count), | 
| +          time_percent_(100), | 
| +          count_percent_(100) {} | 
| + | 
| +    bool operator<(const Entry& other) const { | 
| +      if (time_ < other.time_) return true; | 
| +      if (time_ > other.time_) return false; | 
| +      return count_ < other.count_; | 
| +    } | 
| + | 
| +    void Print(std::ostream& os) { | 
| +      os.precision(2); | 
| +      os << std::fixed; | 
| +      os << std::setw(50) << name_; | 
| +      os << std::setw(8) << time_ << "ms "; | 
| +      os << std::setw(6) << time_percent_ << "%"; | 
| +      os << std::setw(10) << count_ << " "; | 
| +      os << std::setw(6) << count_percent_ << "%"; | 
| +      os << std::endl; | 
| +    } | 
| + | 
| +    void SetTotal(base::TimeDelta total_time, uint64_t total_count) { | 
| +      time_percent_ = 100.0 * time_ / total_time.InMilliseconds(); | 
| +      count_percent_ = 100.0 * count_ / total_count; | 
| +    } | 
| + | 
| +   private: | 
| +    const char* name_; | 
| +    int64_t time_; | 
| +    uint64_t count_; | 
| +    double time_percent_; | 
| +    double count_percent_; | 
| +  }; | 
| + | 
| +  uint64_t total_call_count = 0; | 
| +  base::TimeDelta total_time; | 
| +  std::vector<Entry> entries; | 
| +}; | 
| + | 
| +void RuntimeCallStats::Print(std::ostream& os) { | 
| +  RuntimeCallStatEntries entries; | 
| + | 
| +#define PRINT_COUNTER(name, nargs, ressize)                                    \ | 
| +  if (this->Count_Runtime_##name > 0) {                                        \ | 
| +    entries.Add(#name, this->Time_Runtime_##name, this->Count_Runtime_##name); \ | 
| +  } | 
| +  FOR_EACH_INTRINSIC(PRINT_COUNTER) | 
| +#undef PRINT_COUNTER | 
| +#define PRINT_COUNTER(name, type)                                              \ | 
| +  if (this->Count_Builtin_##name > 0) {                                        \ | 
| +    entries.Add(#name, this->Time_Builtin_##name, this->Count_Builtin_##name); \ | 
| +  } | 
| +  BUILTIN_LIST_C(PRINT_COUNTER) | 
| +#undef PRINT_COUNTER | 
| +  entries.Print(os); | 
| +} | 
| + | 
| +void RuntimeCallStats::Reset() { | 
| +#define RESET_COUNTER(name, nargs, ressize) \ | 
| +  Count_Runtime_##name = 0;                 \ | 
| +  Time_Runtime_##name = base::TimeDelta(); | 
| +  FOR_EACH_INTRINSIC(RESET_COUNTER) | 
| +#undef RESET_COUNTER | 
| +#define RESET_COUNTER(name, type) \ | 
| +  Count_Builtin_##name = 0;       \ | 
| +  Time_Builtin_##name = base::TimeDelta(); | 
| +  BUILTIN_LIST_C(RESET_COUNTER) | 
| +#undef RESET_COUNTER | 
| +} | 
| + | 
| }  // namespace internal | 
| }  // namespace v8 | 
|  |