OLD | NEW |
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" | |
8 #include "src/counters.h" | 7 #include "src/counters.h" |
9 #include "src/handles-inl.h" | 8 #include "src/handles-inl.h" |
10 #include "src/objects-inl.h" | 9 #include "src/objects-inl.h" |
11 #include "src/tracing/tracing-category-observer.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
13 | 11 |
14 namespace v8 { | 12 namespace v8 { |
15 namespace internal { | 13 namespace internal { |
16 | 14 |
17 namespace { | 15 namespace { |
18 | 16 |
19 class MockHistogram : public Histogram { | 17 class MockHistogram : public Histogram { |
20 public: | 18 public: |
21 void AddSample(int value) { samples_.push_back(value); } | 19 void AddSample(int value) { samples_.push_back(value); } |
(...skipping 15 matching lines...) Expand all Loading... |
37 aggregated_.AddSample(current_ms, current_value); | 35 aggregated_.AddSample(current_ms, current_value); |
38 } | 36 } |
39 | 37 |
40 std::vector<int>* samples() { return mock_.samples(); } | 38 std::vector<int>* samples() { return mock_.samples(); } |
41 | 39 |
42 private: | 40 private: |
43 AggregatedMemoryHistogram<MockHistogram> aggregated_; | 41 AggregatedMemoryHistogram<MockHistogram> aggregated_; |
44 MockHistogram mock_; | 42 MockHistogram mock_; |
45 }; | 43 }; |
46 | 44 |
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 RuntimeCallCounter* counter() { return &(stats()->*counter_id()); } | |
63 RuntimeCallCounter* counter2() { return &(stats()->*counter_id2()); } | |
64 void Sleep(int32_t milliseconds) { | |
65 base::ElapsedTimer timer; | |
66 base::TimeDelta delta = base::TimeDelta::FromMilliseconds(milliseconds); | |
67 timer.Start(); | |
68 while (!timer.HasExpired(delta)) { | |
69 base::OS::Sleep(base::TimeDelta::FromMicroseconds(0)); | |
70 } | |
71 } | |
72 | |
73 const uint32_t kEpsilonMs = 10; | |
74 | |
75 private: | |
76 RuntimeCallStats stats_; | |
77 }; | |
78 | |
79 } // namespace | 45 } // namespace |
80 | 46 |
81 | 47 |
82 TEST_F(AggregatedMemoryHistogramTest, OneSample1) { | 48 TEST_F(AggregatedMemoryHistogramTest, OneSample1) { |
83 FLAG_histogram_interval = 10; | 49 FLAG_histogram_interval = 10; |
84 AddSample(10, 1000); | 50 AddSample(10, 1000); |
85 AddSample(20, 1000); | 51 AddSample(20, 1000); |
86 EXPECT_EQ(1U, samples()->size()); | 52 EXPECT_EQ(1U, samples()->size()); |
87 EXPECT_EQ(1000, (*samples())[0]); | 53 EXPECT_EQ(1000, (*samples())[0]); |
88 } | 54 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 FLAG_histogram_interval = 10; | 188 FLAG_histogram_interval = 10; |
223 const int kMaxSamples = 1000; | 189 const int kMaxSamples = 1000; |
224 AddSample(0, 0); | 190 AddSample(0, 0); |
225 AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples)); | 191 AddSample(10 * (2 * kMaxSamples), 10 * (2 * kMaxSamples)); |
226 EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size()); | 192 EXPECT_EQ(static_cast<unsigned>(kMaxSamples), samples()->size()); |
227 for (int i = 0; i < kMaxSamples; i++) { | 193 for (int i = 0; i < kMaxSamples; i++) { |
228 EXPECT_EQ(i * 10 + 5, (*samples())[i]); | 194 EXPECT_EQ(i * 10 + 5, (*samples())[i]); |
229 } | 195 } |
230 } | 196 } |
231 | 197 |
232 #define EXPECT_IN_RANGE(start, value, end) \ | |
233 EXPECT_LE(start, value); \ | |
234 EXPECT_GE(end, value) | |
235 | |
236 TEST_F(RuntimeCallStatsTest, RuntimeCallTimer) { | |
237 RuntimeCallTimer timer; | |
238 | |
239 RuntimeCallStats::Enter(stats(), &timer, counter_id()); | |
240 EXPECT_EQ(counter(), timer.counter()); | |
241 EXPECT_EQ(nullptr, timer.parent()); | |
242 EXPECT_TRUE(timer.timer().IsStarted()); | |
243 EXPECT_EQ(&timer, stats()->current_timer()); | |
244 | |
245 Sleep(100); | |
246 | |
247 RuntimeCallStats::Leave(stats(), &timer); | |
248 EXPECT_FALSE(timer.timer().IsStarted()); | |
249 EXPECT_EQ(1, counter()->count); | |
250 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
251 } | |
252 | |
253 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerSubTimer) { | |
254 RuntimeCallTimer timer; | |
255 RuntimeCallTimer timer2; | |
256 | |
257 RuntimeCallStats::Enter(stats(), &timer, counter_id()); | |
258 EXPECT_TRUE(timer.timer().IsStarted()); | |
259 EXPECT_FALSE(timer2.timer().IsStarted()); | |
260 EXPECT_EQ(counter(), timer.counter()); | |
261 EXPECT_EQ(nullptr, timer.parent()); | |
262 EXPECT_EQ(&timer, stats()->current_timer()); | |
263 | |
264 Sleep(50); | |
265 | |
266 RuntimeCallStats::Enter(stats(), &timer2, counter_id2()); | |
267 EXPECT_TRUE(timer.timer().IsStarted()); | |
268 EXPECT_TRUE(timer2.timer().IsStarted()); | |
269 EXPECT_EQ(counter(), timer.counter()); | |
270 EXPECT_EQ(counter2(), timer2.counter()); | |
271 EXPECT_EQ(nullptr, timer.parent()); | |
272 EXPECT_EQ(&timer, timer2.parent()); | |
273 EXPECT_EQ(&timer2, stats()->current_timer()); | |
274 | |
275 Sleep(100); | |
276 RuntimeCallStats::Leave(stats(), &timer2); | |
277 | |
278 // The subtimer subtracts its time from the parent timer. | |
279 EXPECT_TRUE(timer.timer().IsStarted()); | |
280 EXPECT_FALSE(timer2.timer().IsStarted()); | |
281 EXPECT_EQ(0, counter()->count); | |
282 EXPECT_EQ(1, counter2()->count); | |
283 EXPECT_EQ(0, counter()->time.InMilliseconds()); | |
284 EXPECT_IN_RANGE(100, counter2()->time.InMilliseconds(), 100 + kEpsilonMs); | |
285 EXPECT_EQ(&timer, stats()->current_timer()); | |
286 | |
287 Sleep(100); | |
288 | |
289 RuntimeCallStats::Leave(stats(), &timer); | |
290 EXPECT_FALSE(timer.timer().IsStarted()); | |
291 EXPECT_EQ(1, counter()->count); | |
292 EXPECT_EQ(1, counter2()->count); | |
293 EXPECT_IN_RANGE(150, counter()->time.InMilliseconds(), 150 + kEpsilonMs); | |
294 EXPECT_IN_RANGE(100, counter2()->time.InMilliseconds(), 100 + kEpsilonMs); | |
295 EXPECT_EQ(nullptr, stats()->current_timer()); | |
296 } | |
297 | |
298 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerRecursive) { | |
299 RuntimeCallTimer timer; | |
300 RuntimeCallTimer timer2; | |
301 | |
302 RuntimeCallStats::Enter(stats(), &timer, counter_id()); | |
303 EXPECT_EQ(counter(), timer.counter()); | |
304 EXPECT_EQ(nullptr, timer.parent()); | |
305 EXPECT_TRUE(timer.timer().IsStarted()); | |
306 EXPECT_EQ(&timer, stats()->current_timer()); | |
307 | |
308 RuntimeCallStats::Enter(stats(), &timer2, counter_id()); | |
309 EXPECT_EQ(counter(), timer2.counter()); | |
310 EXPECT_EQ(&timer, timer2.parent()); | |
311 EXPECT_TRUE(timer2.timer().IsStarted()); | |
312 EXPECT_EQ(&timer2, stats()->current_timer()); | |
313 | |
314 Sleep(50); | |
315 | |
316 RuntimeCallStats::Leave(stats(), &timer2); | |
317 EXPECT_FALSE(timer2.timer().IsStarted()); | |
318 EXPECT_TRUE(timer.timer().IsStarted()); | |
319 EXPECT_EQ(1, counter()->count); | |
320 EXPECT_IN_RANGE(50, counter()->time.InMilliseconds(), 50 + kEpsilonMs); | |
321 | |
322 Sleep(100); | |
323 | |
324 RuntimeCallStats::Leave(stats(), &timer); | |
325 EXPECT_FALSE(timer.timer().IsStarted()); | |
326 EXPECT_EQ(2, counter()->count); | |
327 EXPECT_IN_RANGE(150, counter()->time.InMilliseconds(), 150 + 2 * kEpsilonMs); | |
328 } | |
329 | |
330 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScope) { | |
331 { | |
332 RuntimeCallTimerScope scope(stats(), counter_id()); | |
333 Sleep(50); | |
334 } | |
335 Sleep(100); | |
336 EXPECT_EQ(1, counter()->count); | |
337 EXPECT_IN_RANGE(50, counter()->time.InMilliseconds(), 50 + kEpsilonMs); | |
338 { | |
339 RuntimeCallTimerScope scope(stats(), counter_id()); | |
340 Sleep(50); | |
341 } | |
342 EXPECT_EQ(2, counter()->count); | |
343 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + 2 * kEpsilonMs); | |
344 } | |
345 | |
346 TEST_F(RuntimeCallStatsTest, RuntimeCallTimerScopeRecursive) { | |
347 { | |
348 RuntimeCallTimerScope scope(stats(), counter_id()); | |
349 Sleep(50); | |
350 EXPECT_EQ(0, counter()->count); | |
351 EXPECT_EQ(0, counter()->time.InMilliseconds()); | |
352 { | |
353 RuntimeCallTimerScope scope(stats(), counter_id()); | |
354 Sleep(50); | |
355 } | |
356 EXPECT_EQ(1, counter()->count); | |
357 EXPECT_IN_RANGE(50, counter()->time.InMilliseconds(), 50 + kEpsilonMs); | |
358 } | |
359 EXPECT_EQ(2, counter()->count); | |
360 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + 2 * kEpsilonMs); | |
361 } | |
362 | |
363 TEST_F(RuntimeCallStatsTest, RenameTimer) { | |
364 { | |
365 RuntimeCallTimerScope scope(stats(), counter_id()); | |
366 Sleep(50); | |
367 EXPECT_EQ(0, counter()->count); | |
368 EXPECT_EQ(0, counter2()->count); | |
369 EXPECT_EQ(0, counter()->time.InMilliseconds()); | |
370 EXPECT_EQ(0, counter2()->time.InMilliseconds()); | |
371 { | |
372 RuntimeCallTimerScope scope(stats(), counter_id()); | |
373 Sleep(100); | |
374 } | |
375 CHANGE_CURRENT_RUNTIME_COUNTER(stats(), TestCounter2); | |
376 EXPECT_EQ(1, counter()->count); | |
377 EXPECT_EQ(0, counter2()->count); | |
378 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
379 EXPECT_IN_RANGE(0, counter2()->time.InMilliseconds(), 0); | |
380 } | |
381 EXPECT_EQ(1, counter()->count); | |
382 EXPECT_EQ(1, counter2()->count); | |
383 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
384 EXPECT_IN_RANGE(50, counter2()->time.InMilliseconds(), 50 + kEpsilonMs); | |
385 } | |
386 | |
387 TEST_F(RuntimeCallStatsTest, PrintAndSnapshot) { | |
388 { | |
389 RuntimeCallTimerScope scope(stats(), counter_id()); | |
390 Sleep(100); | |
391 EXPECT_EQ(0, counter()->count); | |
392 EXPECT_EQ(0, counter()->time.InMilliseconds()); | |
393 { | |
394 RuntimeCallTimerScope scope(stats(), counter_id2()); | |
395 EXPECT_EQ(0, counter2()->count); | |
396 EXPECT_EQ(0, counter2()->time.InMilliseconds()); | |
397 Sleep(50); | |
398 | |
399 // This calls Snapshot on the current active timer and sychronizes and | |
400 // commits the whole timer stack. | |
401 std::ostringstream out; | |
402 stats()->Print(out); | |
403 EXPECT_EQ(0, counter()->count); | |
404 EXPECT_EQ(0, counter2()->count); | |
405 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
406 EXPECT_IN_RANGE(50, counter2()->time.InMilliseconds(), 50 + kEpsilonMs); | |
407 // Calling Print several times shouldn't have a (big) impact on the | |
408 // measured times. | |
409 stats()->Print(out); | |
410 EXPECT_EQ(0, counter()->count); | |
411 EXPECT_EQ(0, counter2()->count); | |
412 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
413 EXPECT_IN_RANGE(50, counter2()->time.InMilliseconds(), 50 + kEpsilonMs); | |
414 | |
415 Sleep(50); | |
416 stats()->Print(out); | |
417 EXPECT_EQ(0, counter()->count); | |
418 EXPECT_EQ(0, counter2()->count); | |
419 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
420 EXPECT_IN_RANGE(100, counter2()->time.InMilliseconds(), 100 + kEpsilonMs); | |
421 Sleep(50); | |
422 } | |
423 Sleep(50); | |
424 EXPECT_EQ(0, counter()->count); | |
425 EXPECT_EQ(1, counter2()->count); | |
426 EXPECT_IN_RANGE(100, counter()->time.InMilliseconds(), 100 + kEpsilonMs); | |
427 EXPECT_IN_RANGE(150, counter2()->time.InMilliseconds(), 150 + kEpsilonMs); | |
428 Sleep(50); | |
429 } | |
430 EXPECT_EQ(1, counter()->count); | |
431 EXPECT_EQ(1, counter2()->count); | |
432 EXPECT_IN_RANGE(200, counter()->time.InMilliseconds(), 200 + kEpsilonMs); | |
433 EXPECT_IN_RANGE(150, counter2()->time.InMilliseconds(), 150 + 2 * kEpsilonMs); | |
434 } | |
435 | 198 |
436 } // namespace internal | 199 } // namespace internal |
437 } // namespace v8 | 200 } // namespace v8 |
OLD | NEW |