Commit 9cda0abd authored by ishell's avatar ishell Committed by Commit bot

[runtime] Minimize runtime call stats overhead when it is disabled.

... by
1) avoiding accessing RuntimeCallStats instance,
2) avoiding calculating address of a counter field,
3) and using statically known pointer to a member counter instead.

And in addition some code cleanup.

BUG=chromium:596055
LOG=N

Review-Url: https://codereview.chromium.org/1965133002
Cr-Commit-Position: refs/heads/master@{#36162}
parent 3cc12b4a
...@@ -86,8 +86,7 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4); ...@@ -86,8 +86,7 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
\ \
V8_NOINLINE static Type Stats_##Name(int args_length, Object** args_object, \ V8_NOINLINE static Type Stats_##Name(int args_length, Object** args_object, \
Isolate* isolate) { \ Isolate* isolate) { \
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); \ RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Name); \
RuntimeCallTimerScope timer(isolate, &stats->Name); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Runtime_" #Name); \ "V8.Runtime_" #Name); \
Arguments args(args_length, args_object); \ Arguments args(args_length, args_object); \
......
...@@ -147,8 +147,7 @@ BUILTIN_LIST_C(DEF_ARG_TYPE) ...@@ -147,8 +147,7 @@ BUILTIN_LIST_C(DEF_ARG_TYPE)
V8_NOINLINE static Object* Builtin_Impl_Stats_##name( \ V8_NOINLINE static Object* Builtin_Impl_Stats_##name( \
int args_length, Object** args_object, Isolate* isolate) { \ int args_length, Object** args_object, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \ name##ArgumentsType args(args_length, args_object); \
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); \ RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Builtin_##name); \
RuntimeCallTimerScope timer(isolate, &stats->Builtin_##name); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Builtin_" #name); \ "V8.Builtin_" #name); \
return Builtin_Impl_##name(args, isolate); \ return Builtin_Impl_##name(args, isolate); \
......
...@@ -272,25 +272,20 @@ void RuntimeCallCounter::Reset() { ...@@ -272,25 +272,20 @@ void RuntimeCallCounter::Reset() {
time = base::TimeDelta(); time = base::TimeDelta();
} }
void RuntimeCallStats::Enter(RuntimeCallCounter* counter) { // static
RuntimeCallTimer* timer = new RuntimeCallTimer(); void RuntimeCallStats::Enter(Isolate* isolate, RuntimeCallTimer* timer,
timer->Initialize(counter, current_timer_); CounterId counter_id) {
Enter(timer); RuntimeCallStats* stats = isolate->counters()->runtime_call_stats();
} RuntimeCallCounter* counter = &(stats->*counter_id);
timer->Start(counter, stats->current_timer_);
void RuntimeCallStats::Enter(RuntimeCallTimer* timer_) { stats->current_timer_ = timer;
current_timer_ = timer_;
current_timer_->Start();
}
void RuntimeCallStats::Leave() {
RuntimeCallTimer* timer = current_timer_;
Leave(timer);
delete timer;
} }
void RuntimeCallStats::Leave(RuntimeCallTimer* timer) { // static
current_timer_ = timer->Stop(); void RuntimeCallStats::Leave(Isolate* isolate, RuntimeCallTimer* timer) {
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats();
DCHECK_EQ(stats->current_timer_, timer);
stats->current_timer_ = timer->Stop();
} }
void RuntimeCallStats::Print(std::ostream& os) { void RuntimeCallStats::Print(std::ostream& os) {
...@@ -324,17 +319,5 @@ void RuntimeCallStats::Reset() { ...@@ -324,17 +319,5 @@ void RuntimeCallStats::Reset() {
this->UnexpectedStubMiss.Reset(); this->UnexpectedStubMiss.Reset();
} }
void RuntimeCallTimerScope::Enter(Isolate* isolate,
RuntimeCallCounter* counter) {
isolate_ = isolate;
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats();
timer_.Initialize(counter, stats->current_timer());
stats->Enter(&timer_);
}
void RuntimeCallTimerScope::Leave() {
isolate_->counters()->runtime_call_stats()->Leave(&timer_);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -492,13 +492,14 @@ struct RuntimeCallCounter { ...@@ -492,13 +492,14 @@ struct RuntimeCallCounter {
// timers used for properly measuring the own time of a RuntimeCallCounter. // timers used for properly measuring the own time of a RuntimeCallCounter.
class RuntimeCallTimer { class RuntimeCallTimer {
public: public:
inline void Initialize(RuntimeCallCounter* counter, RuntimeCallTimer() {}
RuntimeCallTimer* parent) {
private:
friend class RuntimeCallStats;
inline void Start(RuntimeCallCounter* counter, RuntimeCallTimer* parent) {
counter_ = counter; counter_ = counter;
parent_ = parent; parent_ = parent;
}
inline void Start() {
timer_.Start(); timer_.Start();
counter_->count++; counter_->count++;
} }
...@@ -508,22 +509,21 @@ class RuntimeCallTimer { ...@@ -508,22 +509,21 @@ class RuntimeCallTimer {
timer_.Stop(); timer_.Stop();
counter_->time += delta; counter_->time += delta;
if (parent_ != NULL) { if (parent_ != NULL) {
parent_->AdjustForSubTimer(delta); // Adjust parent timer so that it does not include sub timer's time.
parent_->counter_->time -= delta;
} }
return parent_; return parent_;
} }
inline void AdjustForSubTimer(base::TimeDelta delta) { RuntimeCallCounter* counter_ = nullptr;
counter_->time -= delta; RuntimeCallTimer* parent_ = nullptr;
}
private:
RuntimeCallCounter* counter_;
RuntimeCallTimer* parent_;
base::ElapsedTimer timer_; base::ElapsedTimer timer_;
}; };
struct RuntimeCallStats { class RuntimeCallStats {
public:
typedef RuntimeCallCounter RuntimeCallStats::*CounterId;
// Dummy counter for the unexpected stub miss. // Dummy counter for the unexpected stub miss.
RuntimeCallCounter UnexpectedStubMiss = RuntimeCallCounter UnexpectedStubMiss =
RuntimeCallCounter("UnexpectedStubMiss"); RuntimeCallCounter("UnexpectedStubMiss");
...@@ -539,42 +539,43 @@ struct RuntimeCallStats { ...@@ -539,42 +539,43 @@ struct RuntimeCallStats {
BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) BUILTIN_LIST_C(CALL_BUILTIN_COUNTER)
#undef CALL_BUILTIN_COUNTER #undef CALL_BUILTIN_COUNTER
// Counter to track recursive time events.
RuntimeCallTimer* current_timer_ = NULL;
// Starting measuring the time for a function. This will establish the // Starting measuring the time for a function. This will establish the
// connection to the parent counter for properly calculating the own times. // connection to the parent counter for properly calculating the own times.
void Enter(RuntimeCallCounter* counter); static void Enter(Isolate* isolate, RuntimeCallTimer* timer,
void Enter(RuntimeCallTimer* timer); CounterId counter_id);
// Leave a scope for a measured runtime function. This will properly add // Leave a scope for a measured runtime function. This will properly add
// the time delta to the current_counter and subtract the delta from its // the time delta to the current_counter and subtract the delta from its
// parent. // parent.
void Leave(); static void Leave(Isolate* isolate, RuntimeCallTimer* timer);
void Leave(RuntimeCallTimer* timer);
RuntimeCallTimer* current_timer() { return current_timer_; }
void Reset(); void Reset();
void Print(std::ostream& os); void Print(std::ostream& os);
RuntimeCallStats() { Reset(); } RuntimeCallStats() { Reset(); }
private:
// Counter to track recursive time events.
RuntimeCallTimer* current_timer_ = NULL;
}; };
// A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the
// the time of C++ scope. // the time of C++ scope.
class RuntimeCallTimerScope { class RuntimeCallTimerScope {
public: public:
inline explicit RuntimeCallTimerScope(Isolate* isolate, inline explicit RuntimeCallTimerScope(
RuntimeCallCounter* counter) { Isolate* isolate, RuntimeCallStats::CounterId counter_id) {
if (FLAG_runtime_call_stats) Enter(isolate, counter); if (V8_UNLIKELY(FLAG_runtime_call_stats)) {
isolate_ = isolate;
RuntimeCallStats::Enter(isolate_, &timer_, counter_id);
}
} }
inline ~RuntimeCallTimerScope() { inline ~RuntimeCallTimerScope() {
if (FLAG_runtime_call_stats) Leave(); if (V8_UNLIKELY(FLAG_runtime_call_stats)) {
RuntimeCallStats::Leave(isolate_, &timer_);
}
} }
void Enter(Isolate* isolate, RuntimeCallCounter* counter);
void Leave();
private: private:
Isolate* isolate_; Isolate* isolate_;
RuntimeCallTimer timer_; RuntimeCallTimer timer_;
......
...@@ -26,10 +26,8 @@ GCTracer::Scope::Scope(GCTracer* tracer, ScopeId scope) ...@@ -26,10 +26,8 @@ GCTracer::Scope::Scope(GCTracer* tracer, ScopeId scope)
start_time_ = tracer_->heap_->MonotonicallyIncreasingTimeInMs(); start_time_ = tracer_->heap_->MonotonicallyIncreasingTimeInMs();
// TODO(cbruni): remove once we fully moved to a trace-based system. // TODO(cbruni): remove once we fully moved to a trace-based system.
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
RuntimeCallStats* stats = RuntimeCallStats::Enter(tracer_->heap_->isolate(), &timer_,
tracer_->heap_->isolate()->counters()->runtime_call_stats(); &RuntimeCallStats::GC);
timer_.Initialize(&stats->GC, stats->current_timer());
stats->Enter(&timer_);
} }
} }
...@@ -40,7 +38,7 @@ GCTracer::Scope::~Scope() { ...@@ -40,7 +38,7 @@ GCTracer::Scope::~Scope() {
tracer_->heap_->MonotonicallyIncreasingTimeInMs() - start_time_; tracer_->heap_->MonotonicallyIncreasingTimeInMs() - start_time_;
// TODO(cbruni): remove once we fully moved to a trace-based system. // TODO(cbruni): remove once we fully moved to a trace-based system.
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
tracer_->heap_->isolate()->counters()->runtime_call_stats()->Leave(&timer_); RuntimeCallStats::Leave(tracer_->heap_->isolate(), &timer_);
} }
} }
...@@ -190,10 +188,7 @@ void GCTracer::Start(GarbageCollector collector, const char* gc_reason, ...@@ -190,10 +188,7 @@ void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
start_time, used_memory); start_time, used_memory);
// TODO(cbruni): remove once we fully moved to a trace-based system. // TODO(cbruni): remove once we fully moved to a trace-based system.
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
RuntimeCallStats* stats = RuntimeCallStats::Enter(heap_->isolate(), &timer_, &RuntimeCallStats::GC);
heap_->isolate()->counters()->runtime_call_stats();
timer_.Initialize(&stats->GC, stats->current_timer());
stats->Enter(&timer_);
} }
} }
...@@ -303,7 +298,7 @@ void GCTracer::Stop(GarbageCollector collector) { ...@@ -303,7 +298,7 @@ void GCTracer::Stop(GarbageCollector collector) {
cumulative_incremental_marking_finalization_duration_ = 0.0; cumulative_incremental_marking_finalization_duration_ = 0.0;
// TODO(cbruni): remove once we fully moved to a trace-based system. // TODO(cbruni): remove once we fully moved to a trace-based system.
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
heap_->isolate()->counters()->runtime_call_stats()->Leave(&timer_); RuntimeCallStats::Leave(heap_->isolate(), &timer_);
} }
} }
......
...@@ -64,9 +64,8 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback) ...@@ -64,9 +64,8 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
#endif #endif
isolate_->set_external_callback_scope(this); isolate_->set_external_callback_scope(this);
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); RuntimeCallStats::Enter(isolate_, &timer_,
timer_.Initialize(&stats->ExternalCallback, stats->current_timer()); &RuntimeCallStats::ExternalCallback);
stats->Enter(&timer_);
} }
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"),
"V8.ExternalCallback"); "V8.ExternalCallback");
...@@ -74,7 +73,7 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback) ...@@ -74,7 +73,7 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
ExternalCallbackScope::~ExternalCallbackScope() { ExternalCallbackScope::~ExternalCallbackScope() {
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
isolate_->counters()->runtime_call_stats()->Leave(&timer_); RuntimeCallStats::Leave(isolate_, &timer_);
} }
isolate_->set_external_callback_scope(previous_scope_); isolate_->set_external_callback_scope(previous_scope_);
TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"),
......
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