[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/+/3320431
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78318}
This commit is contained in:
Camillo Bruni 2021-12-08 17:03:44 +01:00 committed by V8 LUCI CQ
parent bd2fce5773
commit ce02d2f452
6 changed files with 74 additions and 39 deletions

View File

@ -230,6 +230,8 @@ struct V8_EXPORT LongTaskStats {
int64_t gc_full_atomic_wall_clock_duration_us = 0;
int64_t gc_full_incremental_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

View File

@ -2088,8 +2088,8 @@ MaybeLocal<Value> Script::Run(Local<Context> context,
ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer(
isolate->counters()->execute_precise());
i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate);
i::AggregatingHistogramTimerScope histogram_timer(
isolate->counters()->compile_lazy());
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
@ -2455,8 +2455,8 @@ MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer(
isolate->counters()->execute_precise());
i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate);
i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
i::Handle<i::Module> self = Utils::OpenHandle(this);
@ -5181,8 +5181,8 @@ MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer(
isolate->counters()->execute_precise());
i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate);
auto self = Utils::OpenHandle(this);
auto recv_obj = Utils::OpenHandle(*recv);
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,
ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer(
isolate->counters()->execute_precise());
i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate);
auto self = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
@ -5240,8 +5240,8 @@ MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer(
isolate->counters()->execute_precise());
i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate);
auto self = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
bool should_set_has_no_side_effect =
@ -5291,8 +5291,8 @@ MaybeLocal<v8::Value> Function::Call(Local<Context> context,
ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
InternalEscapableScope);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
i::NestedTimedHistogramScope execute_timer(
isolate->counters()->execute_precise());
i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
isolate);
auto self = Utils::OpenHandle(this);
Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
"Function to be called is a null pointer");

View File

@ -56,7 +56,7 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
callback_(callback),
previous_scope_(isolate->external_callback_scope()),
vm_state_(isolate),
pause_timed_histogram_scope_(isolate->counters()->execute_precise()) {
pause_timed_histogram_scope_(isolate->counters()->execute()) {
#ifdef USE_SIMULATOR
scope_address_ = Simulator::current(isolate)->get_sp();
#endif

View File

@ -142,7 +142,7 @@ namespace internal {
#define NESTED_TIMED_HISTOGRAM_LIST_SLOW(HT) \
/* 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) \
/* Timer histograms, thread safe: HT(name, caption, max, unit) */ \

View File

@ -17,25 +17,31 @@ class BaseTimedHistogramScope {
explicit BaseTimedHistogramScope(TimedHistogram* histogram)
: histogram_(histogram) {}
void Start() {
if (!histogram_->Enabled()) return;
void StartInternal() {
DCHECK(histogram_->ToggleRunningState(true));
timer_.Start();
}
void Stop() {
if (!histogram_->Enabled()) return;
void StopInternal() {
DCHECK(histogram_->ToggleRunningState(false));
histogram_->AddTimedSample(timer_.Elapsed());
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(),
v8::LogEventStatus::kStart, true);
}
void LogEnd(Isolate* isolate) {
V8_INLINE void LogEnd(Isolate* isolate) {
Logger::CallEventLogger(isolate, histogram_->name(),
v8::LogEventStatus::kEnd, true);
}
@ -113,8 +119,9 @@ class V8_NODISCARD LazyTimedHistogramScope : public BaseTimedHistogramScope {
// Helper class for scoping a NestedHistogramTimer.
class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope {
public:
explicit NestedTimedHistogramScope(NestedTimedHistogram* histogram)
: BaseTimedHistogramScope(histogram) {
explicit NestedTimedHistogramScope(NestedTimedHistogram* histogram,
Isolate* isolate = nullptr)
: BaseTimedHistogramScope(histogram), isolate_(isolate) {
Start();
}
~NestedTimedHistogramScope() { Stop(); }
@ -123,24 +130,34 @@ class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope {
friend NestedTimedHistogram;
friend PauseNestedTimedHistogramScope;
void Start() {
void StartInteral() {
previous_scope_ = timed_histogram()->Enter(this);
if (histogram_->Enabled()) {
base::TimeTicks now = base::TimeTicks::HighResolutionNow();
if (previous_scope_) previous_scope_->Pause(now);
timer_.Start(now);
}
base::TimeTicks now = base::TimeTicks::HighResolutionNow();
if (previous_scope_) previous_scope_->Pause(now);
timer_.Start(now);
}
void StopInternal() {
timed_histogram()->Leave(previous_scope_);
base::TimeTicks now = base::TimeTicks::HighResolutionNow();
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();
#endif
if (previous_scope_) previous_scope_->Resume(now);
}
V8_INLINE void Start() {
if (histogram_->Enabled()) StartInteral();
LogStart(timed_histogram()->counters()->isolate());
}
void Stop() {
timed_histogram()->Leave(previous_scope_);
if (histogram_->Enabled()) {
base::TimeTicks now = base::TimeTicks::HighResolutionNow();
histogram_->AddTimedSample(timer_.Elapsed(now));
timer_.Stop();
if (previous_scope_) previous_scope_->Resume(now);
}
V8_INLINE void Stop() {
if (histogram_->Enabled()) StopInternal();
LogEnd(timed_histogram()->counters()->isolate());
}
@ -154,11 +171,19 @@ class V8_NODISCARD NestedTimedHistogramScope : public BaseTimedHistogramScope {
timer_.Resume(now);
}
void RecordLongTaskTime(base::TimeDelta elapsed) const {
if (histogram_ == isolate_->counters()->execute()) {
isolate_->GetCurrentLongTaskStats()->v8_execute_us +=
elapsed.InMicroseconds();
}
}
NestedTimedHistogram* timed_histogram() {
return static_cast<NestedTimedHistogram*>(histogram_);
}
NestedTimedHistogramScope* previous_scope_;
Isolate* isolate_;
};
// Temporarily pause a NestedTimedHistogram when for instance leaving V8 for

View File

@ -277,9 +277,10 @@ class Logger : public CodeEventListener {
static void DefaultEventLoggerSentinel(const char* name, int event) {}
static void CallEventLogger(Isolate* isolate, const char* name,
v8::LogEventStatus se, bool expose_to_api) {
if (!isolate->event_logger()) return;
V8_INLINE static void CallEventLoggerInternal(Isolate* isolate,
const char* name,
v8::LogEventStatus se,
bool expose_to_api) {
if (isolate->event_logger() == DefaultEventLoggerSentinel) {
LOG(isolate, TimerEvent(se, name));
} else if (expose_to_api) {
@ -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();
bool is_listening_to_code_events() override {