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) |