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 #include "src/utils.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 namespace {
     14 
     15 double MonotonicallyIncreasingTimeInMs() {
     16   return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
     17          static_cast<double>(base::Time::kMillisecondsPerSecond);
     18 }
     19 
     20 const double kEstimatedRuntimeWithoutData = 1.0;
     21 
     22 }  // namespace
     23 
     24 CompilerDispatcherTracer::Scope::Scope(CompilerDispatcherTracer* tracer,
     25                                        ScopeID scope_id, size_t num)
     26     : tracer_(tracer), scope_id_(scope_id), num_(num) {
     27   start_time_ = MonotonicallyIncreasingTimeInMs();
     28 }
     29 
     30 CompilerDispatcherTracer::Scope::~Scope() {
     31   double elapsed = MonotonicallyIncreasingTimeInMs() - start_time_;
     32   switch (scope_id_) {
     33     case ScopeID::kPrepare:
     34       tracer_->RecordPrepare(elapsed);
     35       break;
     36     case ScopeID::kCompile:
     37       tracer_->RecordCompile(elapsed, num_);
     38       break;
     39     case ScopeID::kFinalize:
     40       tracer_->RecordFinalize(elapsed);
     41       break;
     42   }
     43 }
     44 
     45 // static
     46 const char* CompilerDispatcherTracer::Scope::Name(ScopeID scope_id) {
     47   switch (scope_id) {
     48     case ScopeID::kPrepare:
     49       return "V8.BackgroundCompile_Prepare";
     50     case ScopeID::kCompile:
     51       return "V8.BackgroundCompile_Compile";
     52     case ScopeID::kFinalize:
     53       return "V8.BackgroundCompile_Finalize";
     54   }
     55   UNREACHABLE();
     56 }
     57 
     58 CompilerDispatcherTracer::CompilerDispatcherTracer(Isolate* isolate)
     59     : runtime_call_stats_(nullptr) {
     60   // isolate might be nullptr during unittests.
     61   if (isolate) {
     62     runtime_call_stats_ = isolate->counters()->runtime_call_stats();
     63   }
     64 }
     65 
     66 CompilerDispatcherTracer::~CompilerDispatcherTracer() {}
     67 
     68 void CompilerDispatcherTracer::RecordPrepare(double duration_ms) {
     69   base::LockGuard<base::Mutex> lock(&mutex_);
     70   prepare_events_.Push(duration_ms);
     71 }
     72 
     73 void CompilerDispatcherTracer::RecordCompile(double duration_ms,
     74                                              size_t source_length) {
     75   base::LockGuard<base::Mutex> lock(&mutex_);
     76   compile_events_.Push(std::make_pair(source_length, duration_ms));
     77 }
     78 
     79 void CompilerDispatcherTracer::RecordFinalize(double duration_ms) {
     80   base::LockGuard<base::Mutex> lock(&mutex_);
     81   finalize_events_.Push(duration_ms);
     82 }
     83 
     84 double CompilerDispatcherTracer::EstimatePrepareInMs() const {
     85   base::LockGuard<base::Mutex> lock(&mutex_);
     86   return Average(prepare_events_);
     87 }
     88 
     89 double CompilerDispatcherTracer::EstimateCompileInMs(
     90     size_t source_length) const {
     91   base::LockGuard<base::Mutex> lock(&mutex_);
     92   return Estimate(compile_events_, source_length);
     93 }
     94 
     95 double CompilerDispatcherTracer::EstimateFinalizeInMs() const {
     96   base::LockGuard<base::Mutex> lock(&mutex_);
     97   return Average(finalize_events_);
     98 }
     99 
    100 void CompilerDispatcherTracer::DumpStatistics() const {
    101   PrintF(
    102       "CompilerDispatcherTracer: "
    103       "prepare=%.2lfms compiling=%.2lfms/kb finalize=%.2lfms\n",
    104       EstimatePrepareInMs(), EstimateCompileInMs(1 * KB),
    105       EstimateFinalizeInMs());
    106 }
    107 
    108 double CompilerDispatcherTracer::Average(
    109     const base::RingBuffer<double>& buffer) {
    110   if (buffer.Count() == 0) return 0.0;
    111   double sum = buffer.Sum([](double a, double b) { return a + b; }, 0.0);
    112   return sum / buffer.Count();
    113 }
    114 
    115 double CompilerDispatcherTracer::Estimate(
    116     const base::RingBuffer<std::pair<size_t, double>>& buffer, size_t num) {
    117   if (buffer.Count() == 0) return kEstimatedRuntimeWithoutData;
    118   std::pair<size_t, double> sum = buffer.Sum(
    119       [](std::pair<size_t, double> a, std::pair<size_t, double> b) {
    120         return std::make_pair(a.first + b.first, a.second + b.second);
    121       },
    122       std::make_pair(0, 0.0));
    123   return num * (sum.second / sum.first);
    124 }
    125 
    126 }  // namespace internal
    127 }  // namespace v8
    128