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);
\
V8_NOINLINE static Type Stats_##Name(int args_length, Object** args_object, \
Isolate* isolate) { \
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); \
RuntimeCallTimerScope timer(isolate, &stats->Name); \
RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Name); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Runtime_" #Name); \
Arguments args(args_length, args_object); \
......
......@@ -147,8 +147,7 @@ BUILTIN_LIST_C(DEF_ARG_TYPE)
V8_NOINLINE static Object* Builtin_Impl_Stats_##name( \
int args_length, Object** args_object, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); \
RuntimeCallTimerScope timer(isolate, &stats->Builtin_##name); \
RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Builtin_##name); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Builtin_" #name); \
return Builtin_Impl_##name(args, isolate); \
......
......@@ -272,25 +272,20 @@ void RuntimeCallCounter::Reset() {
time = base::TimeDelta();
}
void RuntimeCallStats::Enter(RuntimeCallCounter* counter) {
RuntimeCallTimer* timer = new RuntimeCallTimer();
timer->Initialize(counter, current_timer_);
Enter(timer);
}
void RuntimeCallStats::Enter(RuntimeCallTimer* timer_) {
current_timer_ = timer_;
current_timer_->Start();
}
void RuntimeCallStats::Leave() {
RuntimeCallTimer* timer = current_timer_;
Leave(timer);
delete timer;
// static
void RuntimeCallStats::Enter(Isolate* isolate, RuntimeCallTimer* timer,
CounterId counter_id) {
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats();
RuntimeCallCounter* counter = &(stats->*counter_id);
timer->Start(counter, stats->current_timer_);
stats->current_timer_ = timer;
}
void RuntimeCallStats::Leave(RuntimeCallTimer* timer) {
current_timer_ = timer->Stop();
// static
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) {
......@@ -324,17 +319,5 @@ void RuntimeCallStats::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 v8
......@@ -492,13 +492,14 @@ struct RuntimeCallCounter {
// timers used for properly measuring the own time of a RuntimeCallCounter.
class RuntimeCallTimer {
public:
inline void Initialize(RuntimeCallCounter* counter,
RuntimeCallTimer* parent) {
RuntimeCallTimer() {}
private:
friend class RuntimeCallStats;
inline void Start(RuntimeCallCounter* counter, RuntimeCallTimer* parent) {
counter_ = counter;
parent_ = parent;
}
inline void Start() {
timer_.Start();
counter_->count++;
}
......@@ -508,22 +509,21 @@ class RuntimeCallTimer {
timer_.Stop();
counter_->time += delta;
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_;
}
inline void AdjustForSubTimer(base::TimeDelta delta) {
counter_->time -= delta;
}
private:
RuntimeCallCounter* counter_;
RuntimeCallTimer* parent_;
RuntimeCallCounter* counter_ = nullptr;
RuntimeCallTimer* parent_ = nullptr;
base::ElapsedTimer timer_;
};
struct RuntimeCallStats {
class RuntimeCallStats {
public:
typedef RuntimeCallCounter RuntimeCallStats::*CounterId;
// Dummy counter for the unexpected stub miss.
RuntimeCallCounter UnexpectedStubMiss =
RuntimeCallCounter("UnexpectedStubMiss");
......@@ -539,41 +539,42 @@ struct RuntimeCallStats {
BUILTIN_LIST_C(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
// connection to the parent counter for properly calculating the own times.
void Enter(RuntimeCallCounter* counter);
void Enter(RuntimeCallTimer* timer);
static void Enter(Isolate* isolate, RuntimeCallTimer* timer,
CounterId counter_id);
// 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
// parent.
void Leave();
void Leave(RuntimeCallTimer* timer);
RuntimeCallTimer* current_timer() { return current_timer_; }
static void Leave(Isolate* isolate, RuntimeCallTimer* timer);
void Reset();
void Print(std::ostream& os);
RuntimeCallStats() { Reset(); }
private:
// Counter to track recursive time events.
RuntimeCallTimer* current_timer_ = NULL;
};
// A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the
// the time of C++ scope.
class RuntimeCallTimerScope {
public:
inline explicit RuntimeCallTimerScope(Isolate* isolate,
RuntimeCallCounter* counter) {
if (FLAG_runtime_call_stats) Enter(isolate, counter);
inline explicit RuntimeCallTimerScope(
Isolate* isolate, RuntimeCallStats::CounterId counter_id) {
if (V8_UNLIKELY(FLAG_runtime_call_stats)) {
isolate_ = isolate;
RuntimeCallStats::Enter(isolate_, &timer_, counter_id);
}
}
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:
Isolate* isolate_;
......
......@@ -26,10 +26,8 @@ GCTracer::Scope::Scope(GCTracer* tracer, ScopeId scope)
start_time_ = tracer_->heap_->MonotonicallyIncreasingTimeInMs();
// TODO(cbruni): remove once we fully moved to a trace-based system.
if (FLAG_runtime_call_stats) {
RuntimeCallStats* stats =
tracer_->heap_->isolate()->counters()->runtime_call_stats();
timer_.Initialize(&stats->GC, stats->current_timer());
stats->Enter(&timer_);
RuntimeCallStats::Enter(tracer_->heap_->isolate(), &timer_,
&RuntimeCallStats::GC);
}
}
......@@ -40,7 +38,7 @@ GCTracer::Scope::~Scope() {
tracer_->heap_->MonotonicallyIncreasingTimeInMs() - start_time_;
// TODO(cbruni): remove once we fully moved to a trace-based system.
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,
start_time, used_memory);
// TODO(cbruni): remove once we fully moved to a trace-based system.
if (FLAG_runtime_call_stats) {
RuntimeCallStats* stats =
heap_->isolate()->counters()->runtime_call_stats();
timer_.Initialize(&stats->GC, stats->current_timer());
stats->Enter(&timer_);
RuntimeCallStats::Enter(heap_->isolate(), &timer_, &RuntimeCallStats::GC);
}
}
......@@ -303,7 +298,7 @@ void GCTracer::Stop(GarbageCollector collector) {
cumulative_incremental_marking_finalization_duration_ = 0.0;
// TODO(cbruni): remove once we fully moved to a trace-based system.
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)
#endif
isolate_->set_external_callback_scope(this);
if (FLAG_runtime_call_stats) {
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats();
timer_.Initialize(&stats->ExternalCallback, stats->current_timer());
stats->Enter(&timer_);
RuntimeCallStats::Enter(isolate_, &timer_,
&RuntimeCallStats::ExternalCallback);
}
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"),
"V8.ExternalCallback");
......@@ -74,7 +73,7 @@ ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
ExternalCallbackScope::~ExternalCallbackScope() {
if (FLAG_runtime_call_stats) {
isolate_->counters()->runtime_call_stats()->Leave(&timer_);
RuntimeCallStats::Leave(isolate_, &timer_);
}
isolate_->set_external_callback_scope(previous_scope_);
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