Home | History | Annotate | Download | only in compiler-dispatcher
      1 // Copyright 2016 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/compiler-dispatcher/compiler-dispatcher-tracer.h"
      6 
      7 #include "src/isolate.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 
     12 namespace {
     13 
     14 double MonotonicallyIncreasingTimeInMs() {
     15   return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
     16          static_cast<double>(base::Time::kMillisecondsPerSecond);
     17 }
     18 
     19 }  // namespace
     20 
     21 CompilerDispatcherTracer::Scope::Scope(CompilerDispatcherTracer* tracer,
     22                                        ScopeID scope_id, size_t num)
     23     : tracer_(tracer), scope_id_(scope_id), num_(num) {
     24   start_time_ = MonotonicallyIncreasingTimeInMs();
     25   // TODO(cbruni): remove once we fully moved to a trace-based system.
     26   if (V8_UNLIKELY(FLAG_runtime_stats)) {
     27     RuntimeCallStats::Enter(tracer_->runtime_call_stats_, &timer_,
     28                             &RuntimeCallStats::CompilerDispatcher);
     29   }
     30 }
     31 
     32 CompilerDispatcherTracer::Scope::~Scope() {
     33   double elapsed = MonotonicallyIncreasingTimeInMs() - start_time_;
     34   switch (scope_id_) {
     35     case ScopeID::kPrepareToParse:
     36       tracer_->RecordPrepareToParse(elapsed);
     37       break;
     38     case ScopeID::kParse:
     39       tracer_->RecordParse(elapsed, num_);
     40       break;
     41     case ScopeID::kFinalizeParsing:
     42       tracer_->RecordFinalizeParsing(elapsed);
     43       break;
     44     case ScopeID::kPrepareToCompile:
     45       tracer_->RecordPrepareToCompile(elapsed);
     46       break;
     47     case ScopeID::kCompile:
     48       tracer_->RecordCompile(elapsed, num_);
     49       break;
     50     case ScopeID::kFinalizeCompiling:
     51       tracer_->RecordFinalizeCompiling(elapsed);
     52       break;
     53   }
     54   // TODO(cbruni): remove once we fully moved to a trace-based system.
     55   if (V8_UNLIKELY(FLAG_runtime_stats)) {
     56     RuntimeCallStats::Leave(tracer_->runtime_call_stats_, &timer_);
     57   }
     58 }
     59 
     60 // static
     61 const char* CompilerDispatcherTracer::Scope::Name(ScopeID scope_id) {
     62   switch (scope_id) {
     63     case ScopeID::kPrepareToParse:
     64       return "V8.BackgroundCompile_PrepareToParse";
     65     case ScopeID::kParse:
     66       return "V8.BackgroundCompile_Parse";
     67     case ScopeID::kFinalizeParsing:
     68       return "V8.BackgroundCompile_FinalizeParsing";
     69     case ScopeID::kPrepareToCompile:
     70       return "V8.BackgroundCompile_PrepareToCompile";
     71     case ScopeID::kCompile:
     72       return "V8.BackgroundCompile_Compile";
     73     case ScopeID::kFinalizeCompiling:
     74       return "V8.BackgroundCompile_FinalizeCompiling";
     75   }
     76   UNREACHABLE();
     77   return nullptr;
     78 }
     79 
     80 CompilerDispatcherTracer::CompilerDispatcherTracer(Isolate* isolate)
     81     : runtime_call_stats_(nullptr) {
     82   // isolate might be nullptr during unittests.
     83   if (isolate) {
     84     runtime_call_stats_ = isolate->counters()->runtime_call_stats();
     85   }
     86 }
     87 
     88 CompilerDispatcherTracer::~CompilerDispatcherTracer() {}
     89 
     90 void CompilerDispatcherTracer::RecordPrepareToParse(double duration_ms) {
     91   base::LockGuard<base::Mutex> lock(&mutex_);
     92   prepare_parse_events_.Push(duration_ms);
     93 }
     94 
     95 void CompilerDispatcherTracer::RecordParse(double duration_ms,
     96                                            size_t source_length) {
     97   base::LockGuard<base::Mutex> lock(&mutex_);
     98   parse_events_.Push(std::make_pair(source_length, duration_ms));
     99 }
    100 
    101 void CompilerDispatcherTracer::RecordFinalizeParsing(double duration_ms) {
    102   base::LockGuard<base::Mutex> lock(&mutex_);
    103   finalize_parsing_events_.Push(duration_ms);
    104 }
    105 
    106 void CompilerDispatcherTracer::RecordPrepareToCompile(double duration_ms) {
    107   base::LockGuard<base::Mutex> lock(&mutex_);
    108   prepare_compile_events_.Push(duration_ms);
    109 }
    110 
    111 void CompilerDispatcherTracer::RecordCompile(double duration_ms,
    112                                              size_t ast_size_in_bytes) {
    113   base::LockGuard<base::Mutex> lock(&mutex_);
    114   compile_events_.Push(std::make_pair(ast_size_in_bytes, duration_ms));
    115 }
    116 
    117 void CompilerDispatcherTracer::RecordFinalizeCompiling(double duration_ms) {
    118   base::LockGuard<base::Mutex> lock(&mutex_);
    119   finalize_compiling_events_.Push(duration_ms);
    120 }
    121 
    122 double CompilerDispatcherTracer::EstimatePrepareToParseInMs() const {
    123   base::LockGuard<base::Mutex> lock(&mutex_);
    124   return Average(prepare_parse_events_);
    125 }
    126 
    127 double CompilerDispatcherTracer::EstimateParseInMs(size_t source_length) const {
    128   base::LockGuard<base::Mutex> lock(&mutex_);
    129   return Estimate(parse_events_, source_length);
    130 }
    131 
    132 double CompilerDispatcherTracer::EstimateFinalizeParsingInMs() {
    133   base::LockGuard<base::Mutex> lock(&mutex_);
    134   return Average(finalize_parsing_events_);
    135 }
    136 
    137 double CompilerDispatcherTracer::EstimatePrepareToCompileInMs() {
    138   base::LockGuard<base::Mutex> lock(&mutex_);
    139   return Average(prepare_compile_events_);
    140 }
    141 
    142 double CompilerDispatcherTracer::EstimateCompileInMs(size_t ast_size_in_bytes) {
    143   base::LockGuard<base::Mutex> lock(&mutex_);
    144   return Estimate(compile_events_, ast_size_in_bytes);
    145 }
    146 
    147 double CompilerDispatcherTracer::EstimateFinalizeCompilingInMs() {
    148   base::LockGuard<base::Mutex> lock(&mutex_);
    149   return Average(finalize_compiling_events_);
    150 }
    151 
    152 double CompilerDispatcherTracer::Average(
    153     const base::RingBuffer<double>& buffer) {
    154   if (buffer.Count() == 0) return 0.0;
    155   double sum = buffer.Sum([](double a, double b) { return a + b; }, 0.0);
    156   return sum / buffer.Count();
    157 }
    158 
    159 double CompilerDispatcherTracer::Estimate(
    160     const base::RingBuffer<std::pair<size_t, double>>& buffer, size_t num) {
    161   if (buffer.Count() == 0) return 0.0;
    162   std::pair<size_t, double> sum = buffer.Sum(
    163       [](std::pair<size_t, double> a, std::pair<size_t, double> b) {
    164         return std::make_pair(a.first + b.first, a.second + b.second);
    165       },
    166       std::make_pair(0, 0.0));
    167   return num * (sum.second / sum.first);
    168 }
    169 
    170 }  // namespace internal
    171 }  // namespace v8
    172