OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/counters.h" | 5 #include "src/counters.h" |
6 | 6 |
7 #include <iomanip> | 7 #include <iomanip> |
8 | 8 |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 entry.Print(os); | 209 entry.Print(os); |
210 } | 210 } |
211 os << std::string(88, '-') << std::endl; | 211 os << std::string(88, '-') << std::endl; |
212 Entry("Total", total_time, total_call_count).Print(os); | 212 Entry("Total", total_time, total_call_count).Print(os); |
213 } | 213 } |
214 | 214 |
215 // By default, the compiler will usually inline this, which results in a large | 215 // By default, the compiler will usually inline this, which results in a large |
216 // binary size increase: std::vector::push_back expands to a large amount of | 216 // binary size increase: std::vector::push_back expands to a large amount of |
217 // instructions, and this function is invoked repeatedly by macros. | 217 // instructions, and this function is invoked repeatedly by macros. |
218 V8_NOINLINE void Add(RuntimeCallCounter* counter) { | 218 V8_NOINLINE void Add(RuntimeCallCounter* counter) { |
219 if (counter->count() == 0) return; | 219 if (counter->count == 0) return; |
220 entries.push_back( | 220 entries.push_back(Entry(counter->name, counter->time, counter->count)); |
221 Entry(counter->name(), counter->time(), counter->count())); | 221 total_time += counter->time; |
222 total_time += counter->time(); | 222 total_call_count += counter->count; |
223 total_call_count += counter->count(); | |
224 } | 223 } |
225 | 224 |
226 private: | 225 private: |
227 class Entry { | 226 class Entry { |
228 public: | 227 public: |
229 Entry(const char* name, base::TimeDelta time, uint64_t count) | 228 Entry(const char* name, base::TimeDelta time, uint64_t count) |
230 : name_(name), | 229 : name_(name), |
231 time_(time.InMicroseconds()), | 230 time_(time.InMicroseconds()), |
232 count_(count), | 231 count_(count), |
233 time_percent_(100), | 232 time_percent_(100), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 double time_percent_; | 266 double time_percent_; |
268 double count_percent_; | 267 double count_percent_; |
269 }; | 268 }; |
270 | 269 |
271 uint64_t total_call_count = 0; | 270 uint64_t total_call_count = 0; |
272 base::TimeDelta total_time; | 271 base::TimeDelta total_time; |
273 std::vector<Entry> entries; | 272 std::vector<Entry> entries; |
274 }; | 273 }; |
275 | 274 |
276 void RuntimeCallCounter::Reset() { | 275 void RuntimeCallCounter::Reset() { |
277 count_ = 0; | 276 count = 0; |
278 time_ = base::TimeDelta(); | 277 time = base::TimeDelta(); |
279 } | 278 } |
280 | 279 |
281 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { | 280 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { |
282 value->BeginArray(name_); | 281 value->BeginArray(name); |
283 value->AppendLongInteger(count_); | 282 value->AppendLongInteger(count); |
284 value->AppendLongInteger(time_.InMicroseconds()); | 283 value->AppendLongInteger(time.InMicroseconds()); |
285 value->EndArray(); | 284 value->EndArray(); |
286 } | 285 } |
287 | 286 |
288 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { | 287 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { |
289 count_ += other->count(); | 288 count += other->count; |
290 time_ += other->time(); | 289 time += other->time; |
291 } | |
292 | |
293 void RuntimeCallTimer::Snapshot() { | |
294 base::TimeTicks now = Now(); | |
295 // Pause only / topmost timer in the timer stack. | |
296 Pause(now); | |
297 // Commit all the timer's elapsed time to the counters. | |
298 RuntimeCallTimer* timer = this; | |
299 while (timer != nullptr) { | |
300 timer->CommitTimeToCounter(); | |
301 timer = timer->parent(); | |
302 } | |
303 Resume(now); | |
304 } | 290 } |
305 | 291 |
306 // static | 292 // static |
307 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { | 293 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { |
308 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, | 294 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, |
309 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // | 295 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // |
310 #undef CALL_RUNTIME_COUNTER | 296 #undef CALL_RUNTIME_COUNTER |
311 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | 297 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ |
312 &RuntimeCallStats::Runtime_##name, // | 298 &RuntimeCallStats::Runtime_##name, // |
313 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // | 299 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // |
314 #undef CALL_RUNTIME_COUNTER | 300 #undef CALL_RUNTIME_COUNTER |
315 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, | 301 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, |
316 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) // | 302 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) // |
317 #undef CALL_BUILTIN_COUNTER | 303 #undef CALL_BUILTIN_COUNTER |
318 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name, | 304 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name, |
319 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) // | 305 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) // |
320 #undef CALL_BUILTIN_COUNTER | 306 #undef CALL_BUILTIN_COUNTER |
321 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name, | 307 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name, |
322 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) | 308 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) |
323 #undef CALL_BUILTIN_COUNTER | 309 #undef CALL_BUILTIN_COUNTER |
324 }; | 310 }; |
325 | 311 |
326 // static | 312 // static |
327 void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, | 313 void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, |
328 CounterId counter_id) { | 314 CounterId counter_id) { |
329 RuntimeCallCounter* counter = &(stats->*counter_id); | 315 RuntimeCallCounter* counter = &(stats->*counter_id); |
330 DCHECK(counter->name() != nullptr); | 316 DCHECK(counter->name != nullptr); |
331 timer->Start(counter, stats->current_timer_.Value()); | 317 timer->Start(counter, stats->current_timer_.Value()); |
332 stats->current_timer_.SetValue(timer); | 318 stats->current_timer_.SetValue(timer); |
333 } | 319 } |
334 | 320 |
335 // static | 321 // static |
336 void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) { | 322 void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) { |
337 if (stats->current_timer_.Value() == timer) { | 323 if (stats->current_timer_.Value() == timer) { |
338 stats->current_timer_.SetValue(timer->Stop()); | 324 stats->current_timer_.SetValue(timer->Stop()); |
339 } else { | 325 } else { |
340 // Must be a Threading cctest. Walk the chain of Timers to find the | 326 // Must be a Threading cctest. Walk the chain of Timers to find the |
341 // buried one that's leaving. We don't care about keeping nested timings | 327 // buried one that's leaving. We don't care about keeping nested timings |
342 // accurate, just avoid crashing by keeping the chain intact. | 328 // accurate, just avoid crashing by keeping the chain intact. |
343 RuntimeCallTimer* next = stats->current_timer_.Value(); | 329 RuntimeCallTimer* next = stats->current_timer_.Value(); |
344 while (next && next->parent() != timer) next = next->parent(); | 330 while (next && next->parent() != timer) next = next->parent(); |
345 if (next == nullptr) return; | 331 if (next == nullptr) return; |
346 next->set_parent(timer->Stop()); | 332 next->parent_.SetValue(timer->Stop()); |
347 } | 333 } |
348 } | 334 } |
349 | 335 |
350 void RuntimeCallStats::Add(RuntimeCallStats* other) { | 336 void RuntimeCallStats::Add(RuntimeCallStats* other) { |
351 for (const RuntimeCallStats::CounterId counter_id : | 337 for (const RuntimeCallStats::CounterId counter_id : |
352 RuntimeCallStats::counters) { | 338 RuntimeCallStats::counters) { |
353 RuntimeCallCounter* counter = &(this->*counter_id); | 339 RuntimeCallCounter* counter = &(this->*counter_id); |
354 RuntimeCallCounter* other_counter = &(other->*counter_id); | 340 RuntimeCallCounter* other_counter = &(other->*counter_id); |
355 counter->Add(other_counter); | 341 counter->Add(other_counter); |
356 } | 342 } |
357 } | 343 } |
358 | 344 |
359 // static | 345 // static |
360 void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats, | 346 void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats, |
361 CounterId counter_id) { | 347 CounterId counter_id) { |
362 RuntimeCallTimer* timer = stats->current_timer_.Value(); | 348 RuntimeCallTimer* timer = stats->current_timer_.Value(); |
363 // When RCS are enabled dynamically there might be no current timer set up. | 349 // When RCS are enabled dynamically there might be no current timer set up. |
364 if (timer == nullptr) return; | 350 if (timer == nullptr) return; |
365 timer->set_counter(&(stats->*counter_id)); | 351 timer->counter_ = &(stats->*counter_id); |
366 } | 352 } |
367 | 353 |
368 void RuntimeCallStats::Print(std::ostream& os) { | 354 void RuntimeCallStats::Print(std::ostream& os) { |
369 RuntimeCallStatEntries entries; | 355 RuntimeCallStatEntries entries; |
370 if (current_timer_.Value() != nullptr) { | 356 if (current_timer_.Value() != nullptr) { |
371 current_timer_.Value()->Snapshot(); | 357 current_timer_.Value()->Elapsed(); |
372 } | 358 } |
373 for (const RuntimeCallStats::CounterId counter_id : | 359 for (const RuntimeCallStats::CounterId counter_id : |
374 RuntimeCallStats::counters) { | 360 RuntimeCallStats::counters) { |
375 RuntimeCallCounter* counter = &(this->*counter_id); | 361 RuntimeCallCounter* counter = &(this->*counter_id); |
376 entries.Add(counter); | 362 entries.Add(counter); |
377 } | 363 } |
378 entries.Print(os); | 364 entries.Print(os); |
379 } | 365 } |
380 | 366 |
381 void RuntimeCallStats::Reset() { | 367 void RuntimeCallStats::Reset() { |
(...skipping 13 matching lines...) Expand all Loading... |
395 counter->Reset(); | 381 counter->Reset(); |
396 } | 382 } |
397 | 383 |
398 in_use_ = true; | 384 in_use_ = true; |
399 } | 385 } |
400 | 386 |
401 void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) { | 387 void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) { |
402 for (const RuntimeCallStats::CounterId counter_id : | 388 for (const RuntimeCallStats::CounterId counter_id : |
403 RuntimeCallStats::counters) { | 389 RuntimeCallStats::counters) { |
404 RuntimeCallCounter* counter = &(this->*counter_id); | 390 RuntimeCallCounter* counter = &(this->*counter_id); |
405 if (counter->count() > 0) counter->Dump(value); | 391 if (counter->count > 0) counter->Dump(value); |
406 } | 392 } |
407 | 393 |
408 in_use_ = false; | 394 in_use_ = false; |
409 } | 395 } |
410 | 396 |
411 } // namespace internal | 397 } // namespace internal |
412 } // namespace v8 | 398 } // namespace v8 |
OLD | NEW |