11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_LOGGING_METRICS_H_ 61cb0ef41Sopenharmony_ci#define V8_LOGGING_METRICS_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <memory> 91cb0ef41Sopenharmony_ci#include <queue> 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include "include/v8-metrics.h" 121cb0ef41Sopenharmony_ci#include "src/base/platform/mutex.h" 131cb0ef41Sopenharmony_ci#include "src/base/platform/time.h" 141cb0ef41Sopenharmony_ci#include "src/init/v8.h" 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cinamespace v8 { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciclass TaskRunner; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cinamespace internal { 211cb0ef41Sopenharmony_cinamespace metrics { 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciclass Recorder : public std::enable_shared_from_this<Recorder> { 241cb0ef41Sopenharmony_ci public: 251cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void SetEmbedderRecorder( 261cb0ef41Sopenharmony_ci Isolate* isolate, 271cb0ef41Sopenharmony_ci const std::shared_ptr<v8::metrics::Recorder>& embedder_recorder); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE bool HasEmbedderRecorder() const; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void NotifyIsolateDisposal(); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci template <class T> 341cb0ef41Sopenharmony_ci void AddMainThreadEvent(const T& event, 351cb0ef41Sopenharmony_ci v8::metrics::Recorder::ContextId id) { 361cb0ef41Sopenharmony_ci if (embedder_recorder_) 371cb0ef41Sopenharmony_ci embedder_recorder_->AddMainThreadEvent(event, id); 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci template <class T> 411cb0ef41Sopenharmony_ci void DelayMainThreadEvent(const T& event, 421cb0ef41Sopenharmony_ci v8::metrics::Recorder::ContextId id) { 431cb0ef41Sopenharmony_ci if (!embedder_recorder_) return; 441cb0ef41Sopenharmony_ci Delay(std::make_unique<DelayedEvent<T>>(event, id)); 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci template <class T> 481cb0ef41Sopenharmony_ci void AddThreadSafeEvent(const T& event) { 491cb0ef41Sopenharmony_ci if (embedder_recorder_) embedder_recorder_->AddThreadSafeEvent(event); 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci private: 531cb0ef41Sopenharmony_ci class DelayedEventBase { 541cb0ef41Sopenharmony_ci public: 551cb0ef41Sopenharmony_ci virtual ~DelayedEventBase() = default; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci virtual void Run(const std::shared_ptr<Recorder>& recorder) = 0; 581cb0ef41Sopenharmony_ci }; 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci template <class T> 611cb0ef41Sopenharmony_ci class DelayedEvent : public DelayedEventBase { 621cb0ef41Sopenharmony_ci public: 631cb0ef41Sopenharmony_ci DelayedEvent(const T& event, v8::metrics::Recorder::ContextId id) 641cb0ef41Sopenharmony_ci : event_(event), id_(id) {} 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci void Run(const std::shared_ptr<Recorder>& recorder) override { 671cb0ef41Sopenharmony_ci recorder->AddMainThreadEvent(event_, id_); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci protected: 711cb0ef41Sopenharmony_ci T event_; 721cb0ef41Sopenharmony_ci v8::metrics::Recorder::ContextId id_; 731cb0ef41Sopenharmony_ci }; 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci class Task; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void Delay( 781cb0ef41Sopenharmony_ci std::unique_ptr<Recorder::DelayedEventBase>&& event); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci base::Mutex lock_; 811cb0ef41Sopenharmony_ci std::shared_ptr<v8::TaskRunner> foreground_task_runner_; 821cb0ef41Sopenharmony_ci std::shared_ptr<v8::metrics::Recorder> embedder_recorder_; 831cb0ef41Sopenharmony_ci std::queue<std::unique_ptr<DelayedEventBase>> delayed_events_; 841cb0ef41Sopenharmony_ci}; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_citemplate <class T, int64_t (base::TimeDelta::*precision)() const = 871cb0ef41Sopenharmony_ci &base::TimeDelta::InMicroseconds> 881cb0ef41Sopenharmony_ciclass V8_NODISCARD TimedScope { 891cb0ef41Sopenharmony_ci public: 901cb0ef41Sopenharmony_ci explicit TimedScope(T* event) : event_(event) { Start(); } 911cb0ef41Sopenharmony_ci ~TimedScope() { Stop(); } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci void Start() { start_time_ = base::TimeTicks::Now(); } 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci void Stop() { 961cb0ef41Sopenharmony_ci if (start_time_.IsMin()) return; 971cb0ef41Sopenharmony_ci base::TimeDelta duration = base::TimeTicks::Now() - start_time_; 981cb0ef41Sopenharmony_ci event_->wall_clock_duration_in_us = (duration.*precision)(); 991cb0ef41Sopenharmony_ci start_time_ = base::TimeTicks::Min(); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci private: 1031cb0ef41Sopenharmony_ci T* event_; 1041cb0ef41Sopenharmony_ci base::TimeTicks start_time_; 1051cb0ef41Sopenharmony_ci}; 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci} // namespace metrics 1081cb0ef41Sopenharmony_ci} // namespace internal 1091cb0ef41Sopenharmony_ci} // namespace v8 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci#endif // V8_LOGGING_METRICS_H_ 112