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

Side by Side Diff: test/unittests/counters-unittest.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
« no previous file with comments | « src/profiler/profile-generator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 <vector> 5 #include <vector>
6 6
7 #include "src/counters-inl.h"
7 #include "src/counters.h" 8 #include "src/counters.h"
8 #include "src/handles-inl.h" 9 #include "src/handles-inl.h"
9 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
11 #include "src/tracing/tracing-category-observer.h"
10 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
11 13
12 namespace v8 { 14 namespace v8 {
13 namespace internal { 15 namespace internal {
14 16
15 namespace { 17 namespace {
16 18
17 class MockHistogram : public Histogram { 19 class MockHistogram : public Histogram {
18 public: 20 public:
19 void AddSample(int value) { samples_.push_back(value); } 21 void AddSample(int value) { samples_.push_back(value); }
(...skipping 15 matching lines...) Expand all
35 aggregated_.AddSample(current_ms, current_value); 37 aggregated_.AddSample(current_ms, current_value);
36 } 38 }
37 39
38 std::vector<int>* samples() { return mock_.samples(); } 40 std::vector<int>* samples() { return mock_.samples(); }
39 41
40 private: 42 private:
41 AggregatedMemoryHistogram<MockHistogram> aggregated_; 43 AggregatedMemoryHistogram<MockHistogram> aggregated_;
42 MockHistogram mock_; 44 MockHistogram mock_;
43 }; 45 };
44 46
47 class RuntimeCallStatsTest : public ::testing::Test {
48 public:
49 RuntimeCallStatsTest() {
50 FLAG_runtime_stats =
51 v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE;
52 }
53 virtual ~RuntimeCallStatsTest() {}
54
55 RuntimeCallStats* stats() { return &stats_; }
56 RuntimeCallStats::CounterId counter_id() {
57 return &RuntimeCallStats::TestCounter1;
58 }
59 RuntimeCallStats::CounterId counter_id2() {
60 return &RuntimeCallStats::TestCounter2;
61 }
62 RuntimeCallStats::CounterId counter_id3() {
63 return &RuntimeCallStats::TestCounter3;
64 }
65 RuntimeCallCounter* counter() { return &(stats()->*counter_id()); }
66 RuntimeCallCounter* counter2() { return &(stats()->*counter_id2()); }
67 RuntimeCallCounter* counter3() { return &(stats()->*counter_id3()); }
68 void Sleep(int32_t milliseconds) {
69 base::ElapsedTimer timer;
70 base::TimeDelta delta = base::TimeDelta::FromMilliseconds(milliseconds);
71 timer.Start();
72 while (!timer.HasExpired(delta)) {
73 base::OS::Sleep(base::TimeDelta::FromMicroseconds(0));
74 }
75 }
76
77 const uint32_t kEpsilonMs = 20;
Michael Achenbach 2016/11/24 09:48:46 Hmm, is that rock solid?
78
79 private:
80 RuntimeCallStats stats_;
81 };
82
45 } // namespace 83 } // namespace
46 84
47 85
48 TEST_F(AggregatedMemoryHistogramTest, OneSample1) { 86 TEST_F(AggregatedMemoryHistogramTest, OneSample1) {
49 FLAG_histogram_interval = 10; 87 FLAG_histogram_interval = 10;
50 AddSample(10, 1000); 88 AddSample(10, 1000);
51 AddSample(20, 1000); 89 AddSample(20, 1000);
52 EXPECT_EQ(1U, samples()->size()); 90 EXPECT_EQ(1U, samples()->size());
53 EXPECT_EQ(1000, (*samples())[0]); 91 EXPECT_EQ(1000, (*samples())[0]);
54 } 92 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 FLAG_histogram_interval = 10; 226 FLAG_histogram_interval = 10;
189 const int kMaxSamples = 1000; 227 const int kMaxSamples = 1000;
190 AddSample(0, 0); 228 AddSample(0, 0);
191 AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples)); 229 AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples));
192 EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size()); 230 EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size());
193 for (int i = 0; i < kMaxSamples; i++) { 231 for (int i = 0; i < kMaxSamples; i++) {
194 EXPECT_EQ(i * 10 + 5, (*samples())[i]); 232 EXPECT_EQ(i * 10 + 5, (*samples())[i]);
195 } 233 }
196 } 234 }
197 235
236 #define EXPECT_IN_RANGE(start, value, end) \
237 EXPECT_LE(start, value); \
238 EXPECT_GE(end, value)
239
240 TEST_F(RuntimeCallStatsTest, RuntimeCallTimer) {
241 RuntimeCallTimer timer;
242
243 Sleep(50);
244 RuntimeCallStats::Enter(stats(), &timer, counter_id());
245 EXPECT_EQ(counter(), timer.counter());
246 EXPECT_EQ(nullptr, timer.parent());
247 EXPECT_TRUE(timer.IsStarted());
248 EXPECT_EQ(&timer, stats()->current_timer());
249
250 Sleep(100);
251
252 RuntimeCallStats::Leave(stats(), &timer);
253 Sleep(50);
254 EXPECT_FALSE(timer.IsStarted());
255 EXPECT_EQ(1, counter()->count());
256 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(), 100 + kEpsilonMs);
257 }
258
259 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerSubTimer) {
260 RuntimeCallTimer timer;
261 RuntimeCallTimer timer2;
262
263 RuntimeCallStats::Enter(stats(), &timer, counter_id());
264 EXPECT_TRUE(timer.IsStarted());
265 EXPECT_FALSE(timer2.IsStarted());
266 EXPECT_EQ(counter(), timer.counter());
267 EXPECT_EQ(nullptr, timer.parent());
268 EXPECT_EQ(&timer, stats()->current_timer());
269
270 Sleep(50);
271
272 RuntimeCallStats::Enter(stats(), &timer2, counter_id2());
273 // timer 1 is paused, while timer 2 is active.
274 EXPECT_TRUE(timer2.IsStarted());
275 EXPECT_EQ(counter(), timer.counter());
276 EXPECT_EQ(counter2(), timer2.counter());
277 EXPECT_EQ(nullptr, timer.parent());
278 EXPECT_EQ(&timer, timer2.parent());
279 EXPECT_EQ(&timer2, stats()->current_timer());
280
281 Sleep(100);
282 RuntimeCallStats::Leave(stats(), &timer2);
283
284 // The subtimer subtracts its time from the parent timer.
285 EXPECT_TRUE(timer.IsStarted());
286 EXPECT_FALSE(timer2.IsStarted());
287 EXPECT_EQ(0, counter()->count());
288 EXPECT_EQ(1, counter2()->count());
289 EXPECT_EQ(0, counter()->time().InMilliseconds());
290 EXPECT_IN_RANGE(100, counter2()->time().InMilliseconds(), 100 + kEpsilonMs);
291 EXPECT_EQ(&timer, stats()->current_timer());
292
293 Sleep(100);
294
295 RuntimeCallStats::Leave(stats(), &timer);
296 EXPECT_FALSE(timer.IsStarted());
297 EXPECT_EQ(1, counter()->count());
298 EXPECT_EQ(1, counter2()->count());
299 EXPECT_IN_RANGE(150, counter()->time().InMilliseconds(), 150 + kEpsilonMs);
300 EXPECT_IN_RANGE(100, counter2()->time().InMilliseconds(), 100 + kEpsilonMs);
301 EXPECT_EQ(nullptr, stats()->current_timer());
302 }
303
304 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerRecursive) {
305 RuntimeCallTimer timer;
306 RuntimeCallTimer timer2;
307
308 RuntimeCallStats::Enter(stats(), &timer, counter_id());
309 EXPECT_EQ(counter(), timer.counter());
310 EXPECT_EQ(nullptr, timer.parent());
311 EXPECT_TRUE(timer.IsStarted());
312 EXPECT_EQ(&timer, stats()->current_timer());
313
314 RuntimeCallStats::Enter(stats(), &timer2, counter_id());
315 EXPECT_EQ(counter(), timer2.counter());
316 EXPECT_EQ(nullptr, timer.parent());
317 EXPECT_EQ(&timer, timer2.parent());
318 EXPECT_TRUE(timer2.IsStarted());
319 EXPECT_EQ(&timer2, stats()->current_timer());
320
321 Sleep(50);
322
323 RuntimeCallStats::Leave(stats(), &timer2);
324 EXPECT_EQ(nullptr, timer.parent());
325 EXPECT_FALSE(timer2.IsStarted());
326 EXPECT_TRUE(timer.IsStarted());
327 EXPECT_EQ(1, counter()->count());
328 EXPECT_IN_RANGE(50, counter()->time().InMilliseconds(), 50 + kEpsilonMs);
329
330 Sleep(100);
331
332 RuntimeCallStats::Leave(stats(), &timer);
333 EXPECT_FALSE(timer.IsStarted());
334 EXPECT_EQ(2, counter()->count());
335 EXPECT_IN_RANGE(150, counter()->time().InMilliseconds(),
336 150 + 2 * kEpsilonMs);
337 }
338
339 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScope) {
340 {
341 RuntimeCallTimerScope scope(stats(), counter_id());
342 Sleep(50);
343 }
344 Sleep(100);
345 EXPECT_EQ(1, counter()->count());
346 EXPECT_IN_RANGE(50, counter()->time().InMilliseconds(), 50 + kEpsilonMs);
347 {
348 RuntimeCallTimerScope scope(stats(), counter_id());
349 Sleep(50);
350 }
351 EXPECT_EQ(2, counter()->count());
352 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(),
353 100 + 2 * kEpsilonMs);
354 }
355
356 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScopeRecursive) {
357 {
358 RuntimeCallTimerScope scope(stats(), counter_id());
359 Sleep(50);
360 EXPECT_EQ(0, counter()->count());
361 EXPECT_EQ(0, counter()->time().InMilliseconds());
362 {
363 RuntimeCallTimerScope scope(stats(), counter_id());
364 Sleep(50);
365 }
366 EXPECT_EQ(1, counter()->count());
367 EXPECT_IN_RANGE(50, counter()->time().InMilliseconds(), 50 + kEpsilonMs);
368 }
369 EXPECT_EQ(2, counter()->count());
370 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(),
371 100 + 2 * kEpsilonMs);
372 }
373
374 TEST_F(RuntimeCallStatsTest, RenameTimer) {
375 {
376 RuntimeCallTimerScope scope(stats(), counter_id());
377 Sleep(50);
378 EXPECT_EQ(0, counter()->count());
379 EXPECT_EQ(0, counter2()->count());
380 EXPECT_EQ(0, counter()->time().InMilliseconds());
381 EXPECT_EQ(0, counter2()->time().InMilliseconds());
382 {
383 RuntimeCallTimerScope scope(stats(), counter_id());
384 Sleep(100);
385 }
386 CHANGE_CURRENT_RUNTIME_COUNTER(stats(), TestCounter2);
387 EXPECT_EQ(1, counter()->count());
388 EXPECT_EQ(0, counter2()->count());
389 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(), 100 + kEpsilonMs);
390 EXPECT_IN_RANGE(0, counter2()->time().InMilliseconds(), 0);
391 }
392 EXPECT_EQ(1, counter()->count());
393 EXPECT_EQ(1, counter2()->count());
394 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(), 100 + kEpsilonMs);
395 EXPECT_IN_RANGE(50, counter2()->time().InMilliseconds(), 50 + kEpsilonMs);
396 }
397
398 TEST_F(RuntimeCallStatsTest, BasicPrintAndSnapshot) {
399 std::ostringstream out;
400 stats()->Print(out);
401 EXPECT_EQ(0, counter()->count());
402 EXPECT_EQ(0, counter2()->count());
403 EXPECT_EQ(0, counter3()->count());
404 EXPECT_EQ(0, counter()->time().InMilliseconds());
405 EXPECT_EQ(0, counter2()->time().InMilliseconds());
406 EXPECT_EQ(0, counter3()->time().InMilliseconds());
407
408 {
409 RuntimeCallTimerScope scope(stats(), counter_id());
410 Sleep(50);
411 stats()->Print(out);
412 }
413 stats()->Print(out);
414 EXPECT_EQ(1, counter()->count());
415 EXPECT_EQ(0, counter2()->count());
416 EXPECT_EQ(0, counter3()->count());
417 EXPECT_IN_RANGE(50, counter()->time().InMilliseconds(), 50 + kEpsilonMs);
418 EXPECT_EQ(0, counter2()->time().InMilliseconds());
419 EXPECT_EQ(0, counter3()->time().InMilliseconds());
420 }
421
422 TEST_F(RuntimeCallStatsTest, PrintAndSnapshot) {
423 {
424 RuntimeCallTimerScope scope(stats(), counter_id());
425 Sleep(100);
426 EXPECT_EQ(0, counter()->count());
427 EXPECT_EQ(0, counter()->time().InMilliseconds());
428 {
429 RuntimeCallTimerScope scope(stats(), counter_id2());
430 EXPECT_EQ(0, counter2()->count());
431 EXPECT_EQ(0, counter2()->time().InMilliseconds());
432 Sleep(50);
433
434 // This calls Snapshot on the current active timer and sychronizes and
435 // commits the whole timer stack.
436 std::ostringstream out;
437 stats()->Print(out);
438 EXPECT_EQ(0, counter()->count());
439 EXPECT_EQ(0, counter2()->count());
440 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(),
441 100 + kEpsilonMs);
442 EXPECT_IN_RANGE(50, counter2()->time().InMilliseconds(), 50 + kEpsilonMs);
443 // Calling Print several times shouldn't have a (big) impact on the
444 // measured times.
445 stats()->Print(out);
446 EXPECT_EQ(0, counter()->count());
447 EXPECT_EQ(0, counter2()->count());
448 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(),
449 100 + kEpsilonMs);
450 EXPECT_IN_RANGE(50, counter2()->time().InMilliseconds(), 50 + kEpsilonMs);
451
452 Sleep(50);
453 stats()->Print(out);
454 EXPECT_EQ(0, counter()->count());
455 EXPECT_EQ(0, counter2()->count());
456 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(),
457 100 + kEpsilonMs);
458 EXPECT_IN_RANGE(100, counter2()->time().InMilliseconds(),
459 100 + kEpsilonMs);
460 Sleep(50);
461 }
462 Sleep(50);
463 EXPECT_EQ(0, counter()->count());
464 EXPECT_EQ(1, counter2()->count());
465 EXPECT_IN_RANGE(100, counter()->time().InMilliseconds(), 100 + kEpsilonMs);
466 EXPECT_IN_RANGE(150, counter2()->time().InMilliseconds(), 150 + kEpsilonMs);
467 Sleep(50);
468 }
469 EXPECT_EQ(1, counter()->count());
470 EXPECT_EQ(1, counter2()->count());
471 EXPECT_IN_RANGE(200, counter()->time().InMilliseconds(), 200 + kEpsilonMs);
472 EXPECT_IN_RANGE(150, counter2()->time().InMilliseconds(),
473 150 + 2 * kEpsilonMs);
474 }
475
476 TEST_F(RuntimeCallStatsTest, NestedScopes) {
477 {
478 RuntimeCallTimerScope scope(stats(), counter_id());
479 Sleep(100);
480 {
481 RuntimeCallTimerScope scope(stats(), counter_id2());
482 Sleep(100);
483 {
484 RuntimeCallTimerScope scope(stats(), counter_id3());
485 Sleep(50);
486 }
487 Sleep(50);
488 {
489 RuntimeCallTimerScope scope(stats(), counter_id3());
490 Sleep(50);
491 }
492 Sleep(50);
493 }
494 Sleep(100);
495 {
496 RuntimeCallTimerScope scope(stats(), counter_id2());
497 Sleep(100);
498 }
499 Sleep(50);
500 }
501 EXPECT_EQ(1, counter()->count());
502 EXPECT_EQ(2, counter2()->count());
503 EXPECT_EQ(2, counter3()->count());
504 EXPECT_IN_RANGE(250, counter()->time().InMilliseconds(), 250 + kEpsilonMs);
505 EXPECT_IN_RANGE(300, counter2()->time().InMilliseconds(), 300 + kEpsilonMs);
506 EXPECT_IN_RANGE(100, counter3()->time().InMilliseconds(), 100 + kEpsilonMs);
507 }
198 508
199 } // namespace internal 509 } // namespace internal
200 } // namespace v8 510 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/profile-generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698