Commit ce02d2f4 authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[api] Add LongTaskStats::v8_execute_us

The execute_us is now tied to the --slow-histograms flag.
This currently enabled on a small population as a persistent finch study
which should give us enough coverage for now.

Drive-by-fixes:
- Rename counter: execute_precise() to execute()
- Avoid Leave/Enter overhead in NestedTimedHistogramScope if the
  histogram is not enabled
- Only stop timers in debug mode for NestedTimedHistogramScope

Bug: chromium:1275056
Change-Id: Id6a492bdd68edb5194cb191c7083829a9f90283f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3320431Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78318}
parent bd2fce57
...@@ -230,6 +230,8 @@ struct V8_EXPORT LongTaskStats { ...@@ -230,6 +230,8 @@ struct V8_EXPORT LongTaskStats {
int64_t gc_full_atomic_wall_clock_duration_us = 0; int64_t gc_full_atomic_wall_clock_duration_us = 0;
int64_t gc_full_incremental_wall_clock_duration_us = 0; int64_t gc_full_incremental_wall_clock_duration_us = 0;
int64_t gc_young_wall_clock_duration_us = 0; int64_t gc_young_wall_clock_duration_us = 0;
// Only collected with --slow-histograms
int64_t v8_execute_us = 0;
}; };
} // namespace metrics } // namespace metrics
......
...@@ -2088,8 +2088,8 @@ MaybeLocal<Value> Script::Run(Local<Context> context, ...@@ -2088,8 +2088,8 @@ MaybeLocal<Value> Script::Run(Local<Context> context,
ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(), ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
InternalEscapableScope); InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer( i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate->counters()->execute_precise()); isolate);
i::AggregatingHistogramTimerScope histogram_timer( i::AggregatingHistogramTimerScope histogram_timer(
isolate->counters()->compile_lazy()); isolate->counters()->compile_lazy());
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this)); auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
...@@ -2455,8 +2455,8 @@ MaybeLocal<Value> Module::Evaluate(Local<Context> context) { ...@@ -2455,8 +2455,8 @@ MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(), ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
InternalEscapableScope); InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer( i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate->counters()->execute_precise()); isolate);
i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy()); i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
i::Handle<i::Module> self = Utils::OpenHandle(this); i::Handle<i::Module> self = Utils::OpenHandle(this);
...@@ -5181,8 +5181,8 @@ MaybeLocal<Value> Object::CallAsFunction(Local<Context> context, ...@@ -5181,8 +5181,8 @@ MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(), ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
InternalEscapableScope); InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer( i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate->counters()->execute_precise()); isolate);
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
auto recv_obj = Utils::OpenHandle(*recv); auto recv_obj = Utils::OpenHandle(*recv);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>)); STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
...@@ -5201,8 +5201,8 @@ MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc, ...@@ -5201,8 +5201,8 @@ MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(), ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
InternalEscapableScope); InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer( i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate->counters()->execute_precise()); isolate);
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>)); STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
...@@ -5240,8 +5240,8 @@ MaybeLocal<Object> Function::NewInstanceWithSideEffectType( ...@@ -5240,8 +5240,8 @@ MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(), ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
InternalEscapableScope); InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer( i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate->counters()->execute_precise()); isolate);
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>)); STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
bool should_set_has_no_side_effect = bool should_set_has_no_side_effect =
...@@ -5291,8 +5291,8 @@ MaybeLocal<v8::Value> Function::Call(Local<Context> context, ...@@ -5291,8 +5291,8 @@ MaybeLocal<v8::Value> Function::Call(Local<Context> context,
ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(), ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
InternalEscapableScope); InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer( i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate->counters()->execute_precise()); isolate);
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
Utils::ApiCheck(!self.is_null(), "v8::Function::Call", Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
"Function to be called is a null pointer"); "Function to be called is a null pointer");
......
...@@ -56,7 +56,7 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback) ...@@ -56,7 +56,7 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
callback_(callback), callback_(callback),
previous_scope_(isolate->external_callback_scope()), previous_scope_(isolate->external_callback_scope()),
vm_state_(isolate), vm_state_(isolate),
pause_timed_histogram_scope_(isolate->counters()->execute_precise()) { pause_timed_histogram_scope_(isolate->counters()->execute()) {
#ifdef USE_SIMULATOR #ifdef USE_SIMULATOR
scope_address_ = Simulator::current(isolate)->get_sp(); scope_address_ = Simulator::current(isolate)->get_sp();
#endif #endif
......
...@@ -142,7 +142,7 @@ namespace internal { ...@@ -142,7 +142,7 @@ namespace internal {
#define NESTED_TIMED_HISTOGRAM_LIST_SLOW(HT) \ #define NESTED_TIMED_HISTOGRAM_LIST_SLOW(HT) \
/* Total V8 time (including JS and runtime calls, exluding callbacks) */ \ /* Total V8 time (including JS and runtime calls, exluding callbacks) */ \
HT(execute_precise, V8.ExecuteMicroSeconds, 1000000, MICROSECOND) HT(execute, V8.ExecuteMicroSeconds, 1000000, MICROSECOND)
#define TIMED_HISTOGRAM_LIST(HT) \ #define TIMED_HISTOGRAM_LIST(HT) \
/* Timer histograms, thread safe: HT(name, caption, max, unit) */ \ /* Timer histograms, thread safe: HT(name, caption, max, unit) */ \
......
...@@ -17,25 +17,31 @@ class BaseTimedHistogramScope { ...@@ -17,25 +17,31 @@ class BaseTimedHistogramScope {
explicit BaseTimedHistogramScope(TimedHistogram* histogram) explicit BaseTimedHistogramScope(TimedHistogram* histogram)
: histogram_(histogram) {} : histogram_(histogram) {}
void Start() { void StartInternal() {
if (!histogram_->Enabled()) return;
DCHECK(histogram_->ToggleRunningState(true)); DCHECK(histogram_->ToggleRunningState(true));
timer_.Start(); timer_.Start();
} }
void Stop() { void StopInternal() {
if (!histogram_->Enabled()) return;
DCHECK(histogram_->ToggleRunningState(false)); DCHECK(histogram_->ToggleRunningState(false));
histogram_->AddTimedSample(timer_.Elapsed()); histogram_->AddTimedSample(timer_.Elapsed());
timer_.Stop(); timer_.Stop();
} }
void LogStart(Isolate* isolate) { V8_INLINE void Start() {
if (histogram_->Enabled()) StartInternal();
}
V8_INLINE void Stop() {
if (histogram_->Enabled()) StopInternal();
}
V8_INLINE void LogStart(Isolate* isolate) {
Logger::CallEventLogger(isolate, histogram_->name(), Logger::CallEventLogger(isolate, histogram_->name(),
v8::LogEventStatus::kStart, true); v8::LogEventStatus::kStart, true);
} }
void LogEnd(Isolate* isolate) { V8_INLINE void LogEnd(Isolate* isolate) {
Logger::CallEventLogger(isolate, histogram_->name(), Logger::CallEventLogger(isolate, histogram_->name(),
v8::LogEventStatus::kEnd, true); v8::LogEventStatus::kEnd, true);
} }
...@@ -113,8 +119,9 @@ class V8_NODISCARD LazyTimedHistogramScope : public BaseTimedHistogramScope { ...@@ -113,8 +119,9 @@ class V8_NODISCARD LazyTimedHistogramScope : public BaseTimedHistogramScope {
// Helper class for scoping a NestedHistogramTimer. // Helper class for scoping a NestedHistogramTimer.
class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope { class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope {
public: public:
explicit NestedTimedHistogramScope(NestedTimedHistogram* histogram) explicit NestedTimedHistogramScope(NestedTimedHistogram* histogram,
: BaseTimedHistogramScope(histogram) { Isolate* isolate = nullptr)
: BaseTimedHistogramScope(histogram), isolate_(isolate) {
Start(); Start();
} }
~NestedTimedHistogramScope() { Stop(); } ~NestedTimedHistogramScope() { Stop(); }
...@@ -123,24 +130,34 @@ class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope { ...@@ -123,24 +130,34 @@ class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope {
friend NestedTimedHistogram; friend NestedTimedHistogram;
friend PauseNestedTimedHistogramScope; friend PauseNestedTimedHistogramScope;
void Start() { void StartInteral() {
previous_scope_ = timed_histogram()->Enter(this); previous_scope_ = timed_histogram()->Enter(this);
if (histogram_->Enabled()) {
base::TimeTicks now = base::TimeTicks::HighResolutionNow(); base::TimeTicks now = base::TimeTicks::HighResolutionNow();
if (previous_scope_) previous_scope_->Pause(now); if (previous_scope_) previous_scope_->Pause(now);
timer_.Start(now); timer_.Start(now);
} }
LogStart(timed_histogram()->counters()->isolate());
}
void Stop() { void StopInternal() {
timed_histogram()->Leave(previous_scope_); timed_histogram()->Leave(previous_scope_);
if (histogram_->Enabled()) {
base::TimeTicks now = base::TimeTicks::HighResolutionNow(); base::TimeTicks now = base::TimeTicks::HighResolutionNow();
histogram_->AddTimedSample(timer_.Elapsed(now)); base::TimeDelta elapsed = timer_.Elapsed(now);
histogram_->AddTimedSample(elapsed);
if (isolate_) RecordLongTaskTime(elapsed);
#ifdef DEBUG
// StopInternal() is called in the destructor and don't access timer_
// after that.
timer_.Stop(); timer_.Stop();
#endif
if (previous_scope_) previous_scope_->Resume(now); if (previous_scope_) previous_scope_->Resume(now);
} }
V8_INLINE void Start() {
if (histogram_->Enabled()) StartInteral();
LogStart(timed_histogram()->counters()->isolate());
}
V8_INLINE void Stop() {
if (histogram_->Enabled()) StopInternal();
LogEnd(timed_histogram()->counters()->isolate()); LogEnd(timed_histogram()->counters()->isolate());
} }
...@@ -154,11 +171,19 @@ class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope { ...@@ -154,11 +171,19 @@ class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope {
timer_.Resume(now); timer_.Resume(now);
} }
void RecordLongTaskTime(base::TimeDelta elapsed) const {
if (histogram_ == isolate_->counters()->execute()) {
isolate_->GetCurrentLongTaskStats()->v8_execute_us +=
elapsed.InMicroseconds();
}
}
NestedTimedHistogram* timed_histogram() { NestedTimedHistogram* timed_histogram() {
return static_cast<NestedTimedHistogram*>(histogram_); return static_cast<NestedTimedHistogram*>(histogram_);
} }
NestedTimedHistogramScope* previous_scope_; NestedTimedHistogramScope* previous_scope_;
Isolate* isolate_;
}; };
// Temporarily pause a NestedTimedHistogram when for instance leaving V8 for // Temporarily pause a NestedTimedHistogram when for instance leaving V8 for
......
...@@ -277,9 +277,10 @@ class Logger : public CodeEventListener { ...@@ -277,9 +277,10 @@ class Logger : public CodeEventListener {
static void DefaultEventLoggerSentinel(const char* name, int event) {} static void DefaultEventLoggerSentinel(const char* name, int event) {}
static void CallEventLogger(Isolate* isolate, const char* name, V8_INLINE static void CallEventLoggerInternal(Isolate* isolate,
v8::LogEventStatus se, bool expose_to_api) { const char* name,
if (!isolate->event_logger()) return; v8::LogEventStatus se,
bool expose_to_api) {
if (isolate->event_logger() == DefaultEventLoggerSentinel) { if (isolate->event_logger() == DefaultEventLoggerSentinel) {
LOG(isolate, TimerEvent(se, name)); LOG(isolate, TimerEvent(se, name));
} else if (expose_to_api) { } else if (expose_to_api) {
...@@ -287,6 +288,13 @@ class Logger : public CodeEventListener { ...@@ -287,6 +288,13 @@ class Logger : public CodeEventListener {
} }
} }
V8_INLINE static void CallEventLogger(Isolate* isolate, const char* name,
v8::LogEventStatus se,
bool expose_to_api) {
if (!isolate->event_logger()) return;
CallEventLoggerInternal(isolate, name, se, expose_to_api);
}
V8_EXPORT_PRIVATE bool is_logging(); V8_EXPORT_PRIVATE bool is_logging();
bool is_listening_to_code_events() override { bool is_listening_to_code_events() override {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment