| Index: src/counters.cc
|
| diff --git a/src/counters.cc b/src/counters.cc
|
| index d8061f5f3341a2917480713596c6c536f1e8d77e..9b73877d9fe45c9d0cfe2aefbb496a3c47a72d35 100644
|
| --- a/src/counters.cc
|
| +++ b/src/counters.cc
|
| @@ -301,7 +301,8 @@ void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) {
|
| // buried one that's leaving. We don't care about keeping nested timings
|
| // accurate, just avoid crashing by keeping the chain intact.
|
| RuntimeCallTimer* next = stats->current_timer_.Value();
|
| - while (next->parent() != timer) next = next->parent();
|
| + while (next && next->parent() != timer) next = next->parent();
|
| + if (next == nullptr) return;
|
| next->parent_.SetValue(timer->Stop());
|
| }
|
| }
|
| @@ -346,6 +347,14 @@ void RuntimeCallStats::Print(std::ostream& os) {
|
| void RuntimeCallStats::Reset() {
|
| if (V8_LIKELY(FLAG_runtime_stats == 0)) return;
|
|
|
| + // In tracing, we only what to trace the time spent on top level trace events,
|
| + // if runtime counter stack is not empty, we should clear the whole runtime
|
| + // counter stack, and then reset counters so that we can dump counters into
|
| + // top level trace events accurately.
|
| + while (current_timer_.Value()) {
|
| + current_timer_.SetValue(current_timer_.Value()->Stop());
|
| + }
|
| +
|
| #define RESET_COUNTER(name) this->name.Reset();
|
| FOR_EACH_MANUAL_COUNTER(RESET_COUNTER)
|
| #undef RESET_COUNTER
|
| @@ -370,9 +379,6 @@ void RuntimeCallStats::Reset() {
|
| }
|
|
|
| void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) {
|
| - if (current_timer_.Value() != nullptr) {
|
| - current_timer_.Value()->Elapsed();
|
| - }
|
| #define DUMP_COUNTER(name) \
|
| if (this->name.count > 0) this->name.Dump(value);
|
| FOR_EACH_MANUAL_COUNTER(DUMP_COUNTER)
|
|
|