Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: src/counters.cc

Issue 2511093002: [counters] RuntimeStats: fix wrong bookkeeping when dynamically changing counters. (Closed)
Patch Set: merge with master Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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(Entry(counter->name, counter->time, counter->count)); 220 entries.push_back(
221 total_time += counter->time; 221 Entry(counter->name(), counter->time(), counter->count()));
222 total_call_count += counter->count; 222 total_time += counter->time();
223 total_call_count += counter->count();
223 } 224 }
224 225
225 private: 226 private:
226 class Entry { 227 class Entry {
227 public: 228 public:
228 Entry(const char* name, base::TimeDelta time, uint64_t count) 229 Entry(const char* name, base::TimeDelta time, uint64_t count)
229 : name_(name), 230 : name_(name),
230 time_(time.InMicroseconds()), 231 time_(time.InMicroseconds()),
231 count_(count), 232 count_(count),
232 time_percent_(100), 233 time_percent_(100),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 double time_percent_; 267 double time_percent_;
267 double count_percent_; 268 double count_percent_;
268 }; 269 };
269 270
270 uint64_t total_call_count = 0; 271 uint64_t total_call_count = 0;
271 base::TimeDelta total_time; 272 base::TimeDelta total_time;
272 std::vector<Entry> entries; 273 std::vector<Entry> entries;
273 }; 274 };
274 275
275 void RuntimeCallCounter::Reset() { 276 void RuntimeCallCounter::Reset() {
276 count = 0; 277 count_ = 0;
277 time = base::TimeDelta(); 278 time_ = base::TimeDelta();
278 } 279 }
279 280
280 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { 281 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) {
281 value->BeginArray(name); 282 value->BeginArray(name_);
282 value->AppendLongInteger(count); 283 value->AppendLongInteger(count_);
283 value->AppendLongInteger(time.InMicroseconds()); 284 value->AppendLongInteger(time_.InMicroseconds());
284 value->EndArray(); 285 value->EndArray();
285 } 286 }
286 287
287 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { 288 void RuntimeCallCounter::Add(RuntimeCallCounter* other) {
288 count += other->count; 289 count_ += other->count();
289 time += other->time; 290 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);
290 } 304 }
291 305
292 // static 306 // static
293 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { 307 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = {
294 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, 308 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name,
295 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // 309 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) //
296 #undef CALL_RUNTIME_COUNTER 310 #undef CALL_RUNTIME_COUNTER
297 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ 311 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \
298 &RuntimeCallStats::Runtime_##name, // 312 &RuntimeCallStats::Runtime_##name, //
299 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // 313 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) //
300 #undef CALL_RUNTIME_COUNTER 314 #undef CALL_RUNTIME_COUNTER
301 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, 315 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name,
302 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) // 316 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) //
303 #undef CALL_BUILTIN_COUNTER 317 #undef CALL_BUILTIN_COUNTER
304 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name, 318 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name,
305 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) // 319 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) //
306 #undef CALL_BUILTIN_COUNTER 320 #undef CALL_BUILTIN_COUNTER
307 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name, 321 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name,
308 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) 322 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER)
309 #undef CALL_BUILTIN_COUNTER 323 #undef CALL_BUILTIN_COUNTER
310 }; 324 };
311 325
312 // static 326 // static
313 void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, 327 void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer,
314 CounterId counter_id) { 328 CounterId counter_id) {
315 RuntimeCallCounter* counter = &(stats->*counter_id); 329 RuntimeCallCounter* counter = &(stats->*counter_id);
316 DCHECK(counter->name != nullptr); 330 DCHECK(counter->name() != nullptr);
317 timer->Start(counter, stats->current_timer_.Value()); 331 timer->Start(counter, stats->current_timer_.Value());
318 stats->current_timer_.SetValue(timer); 332 stats->current_timer_.SetValue(timer);
319 } 333 }
320 334
321 // static 335 // static
322 void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) { 336 void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) {
323 if (stats->current_timer_.Value() == timer) { 337 if (stats->current_timer_.Value() == timer) {
324 stats->current_timer_.SetValue(timer->Stop()); 338 stats->current_timer_.SetValue(timer->Stop());
325 } else { 339 } else {
326 // Must be a Threading cctest. Walk the chain of Timers to find the 340 // Must be a Threading cctest. Walk the chain of Timers to find the
327 // buried one that's leaving. We don't care about keeping nested timings 341 // buried one that's leaving. We don't care about keeping nested timings
328 // accurate, just avoid crashing by keeping the chain intact. 342 // accurate, just avoid crashing by keeping the chain intact.
329 RuntimeCallTimer* next = stats->current_timer_.Value(); 343 RuntimeCallTimer* next = stats->current_timer_.Value();
330 while (next && next->parent() != timer) next = next->parent(); 344 while (next && next->parent() != timer) next = next->parent();
331 if (next == nullptr) return; 345 if (next == nullptr) return;
332 next->parent_.SetValue(timer->Stop()); 346 next->set_parent(timer->Stop());
333 } 347 }
334 } 348 }
335 349
336 void RuntimeCallStats::Add(RuntimeCallStats* other) { 350 void RuntimeCallStats::Add(RuntimeCallStats* other) {
337 for (const RuntimeCallStats::CounterId counter_id : 351 for (const RuntimeCallStats::CounterId counter_id :
338 RuntimeCallStats::counters) { 352 RuntimeCallStats::counters) {
339 RuntimeCallCounter* counter = &(this->*counter_id); 353 RuntimeCallCounter* counter = &(this->*counter_id);
340 RuntimeCallCounter* other_counter = &(other->*counter_id); 354 RuntimeCallCounter* other_counter = &(other->*counter_id);
341 counter->Add(other_counter); 355 counter->Add(other_counter);
342 } 356 }
343 } 357 }
344 358
345 // static 359 // static
346 void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats, 360 void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats,
347 CounterId counter_id) { 361 CounterId counter_id) {
348 RuntimeCallTimer* timer = stats->current_timer_.Value(); 362 RuntimeCallTimer* timer = stats->current_timer_.Value();
349 // When RCS are enabled dynamically there might be no current timer set up. 363 // When RCS are enabled dynamically there might be no current timer set up.
350 if (timer == nullptr) return; 364 if (timer == nullptr) return;
351 timer->counter_ = &(stats->*counter_id); 365 timer->set_counter(&(stats->*counter_id));
352 } 366 }
353 367
354 void RuntimeCallStats::Print(std::ostream& os) { 368 void RuntimeCallStats::Print(std::ostream& os) {
355 RuntimeCallStatEntries entries; 369 RuntimeCallStatEntries entries;
356 if (current_timer_.Value() != nullptr) { 370 if (current_timer_.Value() != nullptr) {
357 current_timer_.Value()->Elapsed(); 371 current_timer_.Value()->Snapshot();
358 } 372 }
359 for (const RuntimeCallStats::CounterId counter_id : 373 for (const RuntimeCallStats::CounterId counter_id :
360 RuntimeCallStats::counters) { 374 RuntimeCallStats::counters) {
361 RuntimeCallCounter* counter = &(this->*counter_id); 375 RuntimeCallCounter* counter = &(this->*counter_id);
362 entries.Add(counter); 376 entries.Add(counter);
363 } 377 }
364 entries.Print(os); 378 entries.Print(os);
365 } 379 }
366 380
367 void RuntimeCallStats::Reset() { 381 void RuntimeCallStats::Reset() {
(...skipping 13 matching lines...) Expand all
381 counter->Reset(); 395 counter->Reset();
382 } 396 }
383 397
384 in_use_ = true; 398 in_use_ = true;
385 } 399 }
386 400
387 void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) { 401 void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) {
388 for (const RuntimeCallStats::CounterId counter_id : 402 for (const RuntimeCallStats::CounterId counter_id :
389 RuntimeCallStats::counters) { 403 RuntimeCallStats::counters) {
390 RuntimeCallCounter* counter = &(this->*counter_id); 404 RuntimeCallCounter* counter = &(this->*counter_id);
391 if (counter->count > 0) counter->Dump(value); 405 if (counter->count() > 0) counter->Dump(value);
392 } 406 }
393 407
394 in_use_ = false; 408 in_use_ = false;
395 } 409 }
396 410
397 } // namespace internal 411 } // namespace internal
398 } // namespace v8 412 } // namespace v8
OLDNEW
« no previous file with comments | « src/counters.h ('k') | src/counters-inl.h » ('j') | test/unittests/counters-unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698