Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include "src/base/platform/time.h"
6 :
7 : #if V8_OS_MACOSX
8 : #include <mach/mach_time.h>
9 : #endif
10 : #if V8_OS_POSIX
11 : #include <sys/time.h>
12 : #endif
13 :
14 : #if V8_OS_WIN
15 : #include "src/base/win32-headers.h"
16 : #endif
17 :
18 : #include <vector>
19 :
20 : #include "src/base/platform/elapsed-timer.h"
21 : #include "src/base/platform/platform.h"
22 : #include "testing/gtest/include/gtest/gtest.h"
23 :
24 : namespace v8 {
25 : namespace base {
26 :
27 15443 : TEST(TimeDelta, ZeroMinMax) {
28 : constexpr TimeDelta kZero;
29 : static_assert(kZero.IsZero(), "");
30 :
31 1 : constexpr TimeDelta kMax = TimeDelta::Max();
32 : static_assert(kMax.IsMax(), "");
33 : static_assert(kMax == TimeDelta::Max(), "");
34 1 : EXPECT_GT(kMax, TimeDelta::FromDays(100 * 365));
35 : static_assert(kMax > kZero, "");
36 :
37 1 : constexpr TimeDelta kMin = TimeDelta::Min();
38 : static_assert(kMin.IsMin(), "");
39 : static_assert(kMin == TimeDelta::Min(), "");
40 1 : EXPECT_LT(kMin, TimeDelta::FromDays(-100 * 365));
41 : static_assert(kMin < kZero, "");
42 1 : }
43 :
44 15443 : TEST(TimeDelta, MaxConversions) {
45 : // static_assert also confirms constexpr works as intended.
46 1 : constexpr TimeDelta kMax = TimeDelta::Max();
47 2 : EXPECT_EQ(kMax.InDays(), std::numeric_limits<int>::max());
48 2 : EXPECT_EQ(kMax.InHours(), std::numeric_limits<int>::max());
49 2 : EXPECT_EQ(kMax.InMinutes(), std::numeric_limits<int>::max());
50 2 : EXPECT_EQ(kMax.InSecondsF(), std::numeric_limits<double>::infinity());
51 2 : EXPECT_EQ(kMax.InSeconds(), std::numeric_limits<int64_t>::max());
52 2 : EXPECT_EQ(kMax.InMillisecondsF(), std::numeric_limits<double>::infinity());
53 2 : EXPECT_EQ(kMax.InMilliseconds(), std::numeric_limits<int64_t>::max());
54 2 : EXPECT_EQ(kMax.InMillisecondsRoundedUp(),
55 0 : std::numeric_limits<int64_t>::max());
56 :
57 : // TODO(v8-team): Import overflow support from Chromium's base.
58 :
59 : // EXPECT_TRUE(TimeDelta::FromDays(std::numeric_limits<int>::max()).IsMax());
60 :
61 : // EXPECT_TRUE(
62 : // TimeDelta::FromHours(std::numeric_limits<int>::max()).IsMax());
63 :
64 : // EXPECT_TRUE(
65 : // TimeDelta::FromMinutes(std::numeric_limits<int>::max()).IsMax());
66 :
67 : // constexpr int64_t max_int = std::numeric_limits<int64_t>::max();
68 : // constexpr int64_t min_int = std::numeric_limits<int64_t>::min();
69 :
70 : // EXPECT_TRUE(
71 : // TimeDelta::FromSeconds(max_int / Time::kMicrosecondsPerSecond + 1)
72 : // .IsMax());
73 :
74 : // EXPECT_TRUE(TimeDelta::FromMilliseconds(
75 : // max_int / Time::kMillisecondsPerSecond + 1)
76 : // .IsMax());
77 :
78 : // EXPECT_TRUE(TimeDelta::FromMicroseconds(max_int).IsMax());
79 :
80 : // EXPECT_TRUE(
81 : // TimeDelta::FromSeconds(min_int / Time::kMicrosecondsPerSecond - 1)
82 : // .IsMin());
83 :
84 : // EXPECT_TRUE(TimeDelta::FromMilliseconds(
85 : // min_int / Time::kMillisecondsPerSecond - 1)
86 : // .IsMin());
87 :
88 : // EXPECT_TRUE(TimeDelta::FromMicroseconds(min_int).IsMin());
89 :
90 : // EXPECT_TRUE(
91 : // TimeDelta::FromMicroseconds(std::numeric_limits<int64_t>::min())
92 : // .IsMin());
93 1 : }
94 :
95 15443 : TEST(TimeDelta, NumericOperators) {
96 : constexpr int i = 2;
97 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
98 0 : (TimeDelta::FromMilliseconds(1000) * i));
99 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(500),
100 0 : (TimeDelta::FromMilliseconds(1000) / i));
101 3 : EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
102 0 : (TimeDelta::FromMilliseconds(1000) *= i));
103 3 : EXPECT_EQ(TimeDelta::FromMilliseconds(500),
104 0 : (TimeDelta::FromMilliseconds(1000) /= i));
105 :
106 : constexpr int64_t i64 = 2;
107 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
108 0 : (TimeDelta::FromMilliseconds(1000) * i64));
109 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(500),
110 0 : (TimeDelta::FromMilliseconds(1000) / i64));
111 3 : EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
112 0 : (TimeDelta::FromMilliseconds(1000) *= i64));
113 3 : EXPECT_EQ(TimeDelta::FromMilliseconds(500),
114 0 : (TimeDelta::FromMilliseconds(1000) /= i64));
115 :
116 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
117 0 : (TimeDelta::FromMilliseconds(1000) * 2));
118 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(500),
119 0 : (TimeDelta::FromMilliseconds(1000) / 2));
120 3 : EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
121 0 : (TimeDelta::FromMilliseconds(1000) *= 2));
122 3 : EXPECT_EQ(TimeDelta::FromMilliseconds(500),
123 0 : (TimeDelta::FromMilliseconds(1000) /= 2));
124 1 : }
125 :
126 : // TODO(v8-team): Import support for overflow from Chromium's base.
127 15440 : TEST(TimeDelta, DISABLED_Overflows) {
128 : // Some sanity checks. static_assert's used were possible to verify constexpr
129 : // evaluation at the same time.
130 : static_assert(TimeDelta::Max().IsMax(), "");
131 : static_assert(-TimeDelta::Max() < TimeDelta(), "");
132 : static_assert(-TimeDelta::Max() > TimeDelta::Min(), "");
133 : static_assert(TimeDelta() > -TimeDelta::Max(), "");
134 :
135 : TimeDelta large_delta = TimeDelta::Max() - TimeDelta::FromMilliseconds(1);
136 0 : TimeDelta large_negative = -large_delta;
137 0 : EXPECT_GT(TimeDelta(), large_negative);
138 : EXPECT_FALSE(large_delta.IsMax());
139 0 : EXPECT_FALSE((-large_negative).IsMin());
140 0 : const TimeDelta kOneSecond = TimeDelta::FromSeconds(1);
141 :
142 : // Test +, -, * and / operators.
143 0 : EXPECT_TRUE((large_delta + kOneSecond).IsMax());
144 0 : EXPECT_TRUE((large_negative + (-kOneSecond)).IsMin());
145 0 : EXPECT_TRUE((large_negative - kOneSecond).IsMin());
146 0 : EXPECT_TRUE((large_delta - (-kOneSecond)).IsMax());
147 0 : EXPECT_TRUE((large_delta * 2).IsMax());
148 0 : EXPECT_TRUE((large_delta * -2).IsMin());
149 :
150 : // Test +=, -=, *= and /= operators.
151 : TimeDelta delta = large_delta;
152 : delta += kOneSecond;
153 0 : EXPECT_TRUE(delta.IsMax());
154 0 : delta = large_negative;
155 : delta += -kOneSecond;
156 0 : EXPECT_TRUE((delta).IsMin());
157 :
158 0 : delta = large_negative;
159 : delta -= kOneSecond;
160 0 : EXPECT_TRUE((delta).IsMin());
161 : delta = large_delta;
162 : delta -= -kOneSecond;
163 0 : EXPECT_TRUE(delta.IsMax());
164 :
165 : delta = large_delta;
166 : delta *= 2;
167 0 : EXPECT_TRUE(delta.IsMax());
168 :
169 : // Test operations with Time and TimeTicks.
170 0 : EXPECT_TRUE((large_delta + Time::Now()).IsMax());
171 0 : EXPECT_TRUE((large_delta + TimeTicks::Now()).IsMax());
172 0 : EXPECT_TRUE((Time::Now() + large_delta).IsMax());
173 0 : EXPECT_TRUE((TimeTicks::Now() + large_delta).IsMax());
174 :
175 0 : Time time_now = Time::Now();
176 0 : EXPECT_EQ(kOneSecond, (time_now + kOneSecond) - time_now);
177 0 : EXPECT_EQ(-kOneSecond, (time_now - kOneSecond) - time_now);
178 :
179 0 : TimeTicks ticks_now = TimeTicks::Now();
180 0 : EXPECT_EQ(-kOneSecond, (ticks_now - kOneSecond) - ticks_now);
181 0 : EXPECT_EQ(kOneSecond, (ticks_now + kOneSecond) - ticks_now);
182 0 : }
183 :
184 15443 : TEST(TimeDelta, FromAndIn) {
185 2 : EXPECT_EQ(TimeDelta::FromDays(2), TimeDelta::FromHours(48));
186 2 : EXPECT_EQ(TimeDelta::FromHours(3), TimeDelta::FromMinutes(180));
187 2 : EXPECT_EQ(TimeDelta::FromMinutes(2), TimeDelta::FromSeconds(120));
188 2 : EXPECT_EQ(TimeDelta::FromSeconds(2), TimeDelta::FromMilliseconds(2000));
189 2 : EXPECT_EQ(TimeDelta::FromMilliseconds(2), TimeDelta::FromMicroseconds(2000));
190 2 : EXPECT_EQ(static_cast<int>(13), TimeDelta::FromDays(13).InDays());
191 2 : EXPECT_EQ(static_cast<int>(13), TimeDelta::FromHours(13).InHours());
192 2 : EXPECT_EQ(static_cast<int>(13), TimeDelta::FromMinutes(13).InMinutes());
193 2 : EXPECT_EQ(static_cast<int64_t>(13), TimeDelta::FromSeconds(13).InSeconds());
194 1 : EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF());
195 2 : EXPECT_EQ(static_cast<int64_t>(13),
196 0 : TimeDelta::FromMilliseconds(13).InMilliseconds());
197 1 : EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF());
198 2 : EXPECT_EQ(static_cast<int64_t>(13),
199 0 : TimeDelta::FromMicroseconds(13).InMicroseconds());
200 1 : }
201 :
202 :
203 : #if V8_OS_MACOSX
204 : TEST(TimeDelta, MachTimespec) {
205 : TimeDelta null = TimeDelta();
206 : EXPECT_EQ(null, TimeDelta::FromMachTimespec(null.ToMachTimespec()));
207 : TimeDelta delta1 = TimeDelta::FromMilliseconds(42);
208 : EXPECT_EQ(delta1, TimeDelta::FromMachTimespec(delta1.ToMachTimespec()));
209 : TimeDelta delta2 = TimeDelta::FromDays(42);
210 : EXPECT_EQ(delta2, TimeDelta::FromMachTimespec(delta2.ToMachTimespec()));
211 : }
212 : #endif
213 :
214 15443 : TEST(Time, Max) {
215 1 : Time max = Time::Max();
216 : EXPECT_TRUE(max.IsMax());
217 2 : EXPECT_EQ(max, Time::Max());
218 1 : EXPECT_GT(max, Time::Now());
219 1 : EXPECT_GT(max, Time());
220 1 : }
221 :
222 15443 : TEST(Time, MaxConversions) {
223 : Time t = Time::Max();
224 2 : EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.ToInternalValue());
225 :
226 : // TODO(v8-team): Time::FromJsTime() overflows with infinity. Import support
227 : // from Chromium's base.
228 : // t = Time::FromJsTime(std::numeric_limits<double>::infinity());
229 : // EXPECT_TRUE(t.IsMax());
230 : // EXPECT_EQ(std::numeric_limits<double>::infinity(), t.ToJsTime());
231 :
232 : #if defined(OS_POSIX)
233 : struct timeval tval;
234 : tval.tv_sec = std::numeric_limits<time_t>::max();
235 : tval.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
236 : t = Time::FromTimeVal(tval);
237 : EXPECT_TRUE(t.IsMax());
238 : tval = t.ToTimeVal();
239 : EXPECT_EQ(std::numeric_limits<time_t>::max(), tval.tv_sec);
240 : EXPECT_EQ(static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1,
241 : tval.tv_usec);
242 : #endif
243 :
244 : #if defined(OS_WIN)
245 : FILETIME ftime;
246 : ftime.dwHighDateTime = std::numeric_limits<DWORD>::max();
247 : ftime.dwLowDateTime = std::numeric_limits<DWORD>::max();
248 : t = Time::FromFileTime(ftime);
249 : EXPECT_TRUE(t.IsMax());
250 : ftime = t.ToFileTime();
251 : EXPECT_EQ(std::numeric_limits<DWORD>::max(), ftime.dwHighDateTime);
252 : EXPECT_EQ(std::numeric_limits<DWORD>::max(), ftime.dwLowDateTime);
253 : #endif
254 1 : }
255 :
256 15443 : TEST(Time, JsTime) {
257 1 : Time t = Time::FromJsTime(700000.3);
258 1 : EXPECT_DOUBLE_EQ(700000.3, t.ToJsTime());
259 1 : }
260 :
261 :
262 : #if V8_OS_POSIX
263 15443 : TEST(Time, Timespec) {
264 1 : Time null;
265 : EXPECT_TRUE(null.IsNull());
266 2 : EXPECT_EQ(null, Time::FromTimespec(null.ToTimespec()));
267 1 : Time now = Time::Now();
268 2 : EXPECT_EQ(now, Time::FromTimespec(now.ToTimespec()));
269 1 : Time now_sys = Time::NowFromSystemTime();
270 2 : EXPECT_EQ(now_sys, Time::FromTimespec(now_sys.ToTimespec()));
271 1 : Time unix_epoch = Time::UnixEpoch();
272 2 : EXPECT_EQ(unix_epoch, Time::FromTimespec(unix_epoch.ToTimespec()));
273 1 : Time max = Time::Max();
274 : EXPECT_TRUE(max.IsMax());
275 1 : EXPECT_EQ(max, Time::FromTimespec(max.ToTimespec()));
276 1 : }
277 :
278 :
279 15443 : TEST(Time, Timeval) {
280 1 : Time null;
281 : EXPECT_TRUE(null.IsNull());
282 2 : EXPECT_EQ(null, Time::FromTimeval(null.ToTimeval()));
283 1 : Time now = Time::Now();
284 2 : EXPECT_EQ(now, Time::FromTimeval(now.ToTimeval()));
285 1 : Time now_sys = Time::NowFromSystemTime();
286 2 : EXPECT_EQ(now_sys, Time::FromTimeval(now_sys.ToTimeval()));
287 1 : Time unix_epoch = Time::UnixEpoch();
288 2 : EXPECT_EQ(unix_epoch, Time::FromTimeval(unix_epoch.ToTimeval()));
289 1 : Time max = Time::Max();
290 : EXPECT_TRUE(max.IsMax());
291 2 : EXPECT_EQ(max, Time::FromTimeval(max.ToTimeval()));
292 1 : }
293 : #endif
294 :
295 :
296 : #if V8_OS_WIN
297 : TEST(Time, Filetime) {
298 : Time null;
299 : EXPECT_TRUE(null.IsNull());
300 : EXPECT_EQ(null, Time::FromFiletime(null.ToFiletime()));
301 : Time now = Time::Now();
302 : EXPECT_EQ(now, Time::FromFiletime(now.ToFiletime()));
303 : Time now_sys = Time::NowFromSystemTime();
304 : EXPECT_EQ(now_sys, Time::FromFiletime(now_sys.ToFiletime()));
305 : Time unix_epoch = Time::UnixEpoch();
306 : EXPECT_EQ(unix_epoch, Time::FromFiletime(unix_epoch.ToFiletime()));
307 : Time max = Time::Max();
308 : EXPECT_TRUE(max.IsMax());
309 : EXPECT_EQ(max, Time::FromFiletime(max.ToFiletime()));
310 : }
311 : #endif
312 :
313 :
314 : namespace {
315 :
316 : template <typename T>
317 2 : static void ResolutionTest(T (*Now)(), TimeDelta target_granularity) {
318 : // We're trying to measure that intervals increment in a VERY small amount
319 : // of time -- according to the specified target granularity. Unfortunately,
320 : // if we happen to have a context switch in the middle of our test, the
321 : // context switch could easily exceed our limit. So, we iterate on this
322 : // several times. As long as we're able to detect the fine-granularity
323 : // timers at least once, then the test has succeeded.
324 : static const TimeDelta kExpirationTimeout = TimeDelta::FromSeconds(1);
325 : ElapsedTimer timer;
326 : timer.Start();
327 2 : TimeDelta delta;
328 2 : do {
329 2 : T start = Now();
330 : T now = start;
331 : // Loop until we can detect that the clock has changed. Non-HighRes timers
332 : // will increment in chunks, i.e. 15ms. By spinning until we see a clock
333 : // change, we detect the minimum time between measurements.
334 24 : do {
335 24 : now = Now();
336 24 : delta = now - start;
337 : } while (now <= start);
338 2 : EXPECT_NE(static_cast<int64_t>(0), delta.InMicroseconds());
339 : } while (delta > target_granularity && !timer.HasExpired(kExpirationTimeout));
340 2 : EXPECT_LE(delta, target_granularity);
341 2 : }
342 :
343 : } // namespace
344 :
345 :
346 15443 : TEST(Time, NowResolution) {
347 : // We assume that Time::Now() has at least 16ms resolution.
348 : static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16);
349 1 : ResolutionTest<Time>(&Time::Now, kTargetGranularity);
350 1 : }
351 :
352 :
353 15443 : TEST(TimeTicks, NowResolution) {
354 : // TimeTicks::Now() is documented as having "no worse than one microsecond"
355 : // resolution. Unless !TimeTicks::IsHighResolution() in which case the clock
356 : // could be as coarse as ~15.6ms.
357 1 : const TimeDelta kTargetGranularity = TimeTicks::IsHighResolution()
358 : ? TimeDelta::FromMicroseconds(1)
359 1 : : TimeDelta::FromMilliseconds(16);
360 1 : ResolutionTest<TimeTicks>(&TimeTicks::Now, kTargetGranularity);
361 1 : }
362 :
363 15443 : TEST(TimeTicks, IsMonotonic) {
364 1 : TimeTicks previous_normal_ticks;
365 1 : TimeTicks previous_highres_ticks;
366 : ElapsedTimer timer;
367 : timer.Start();
368 1153547 : while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) {
369 576773 : TimeTicks normal_ticks = TimeTicks::Now();
370 576773 : TimeTicks highres_ticks = TimeTicks::HighResolutionNow();
371 576773 : EXPECT_GE(normal_ticks, previous_normal_ticks);
372 1153546 : EXPECT_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0);
373 576773 : EXPECT_GE(highres_ticks, previous_highres_ticks);
374 1153546 : EXPECT_GE((highres_ticks - previous_highres_ticks).InMicroseconds(), 0);
375 576773 : previous_normal_ticks = normal_ticks;
376 576773 : previous_highres_ticks = highres_ticks;
377 : }
378 1 : }
379 :
380 :
381 : #if V8_OS_ANDROID
382 : #define MAYBE_ThreadNow DISABLED_ThreadNow
383 : #else
384 : #define MAYBE_ThreadNow ThreadNow
385 : #endif
386 15443 : TEST(ThreadTicks, MAYBE_ThreadNow) {
387 1 : if (ThreadTicks::IsSupported()) {
388 : ThreadTicks::WaitUntilInitialized();
389 1 : TimeTicks end, begin = TimeTicks::Now();
390 1 : ThreadTicks end_thread, begin_thread = ThreadTicks::Now();
391 1 : TimeDelta delta;
392 : // Make sure that ThreadNow value is non-zero.
393 1 : EXPECT_GT(begin_thread, ThreadTicks());
394 1 : int iterations_count = 0;
395 :
396 : // Some systems have low resolution thread timers, this code makes sure
397 : // that thread time has progressed by at least one tick.
398 : // Limit waiting to 10ms to prevent infinite loops.
399 3 : while (ThreadTicks::Now() == begin_thread &&
400 1 : ((TimeTicks::Now() - begin).InMicroseconds() < 10000)) {
401 : }
402 1 : EXPECT_GT(ThreadTicks::Now(), begin_thread);
403 :
404 1 : do {
405 : // Sleep for 10 milliseconds to get the thread de-scheduled.
406 1 : OS::Sleep(base::TimeDelta::FromMilliseconds(10));
407 1 : end_thread = ThreadTicks::Now();
408 1 : end = TimeTicks::Now();
409 1 : delta = end - begin;
410 1 : EXPECT_LE(++iterations_count, 2); // fail after 2 attempts.
411 1 : } while (delta.InMicroseconds() <
412 : 10000); // Make sure that the OS did sleep for at least 10 ms.
413 1 : TimeDelta delta_thread = end_thread - begin_thread;
414 : // Make sure that some thread time have elapsed.
415 1 : EXPECT_GT(delta_thread.InMicroseconds(), 0);
416 : // But the thread time is at least 9ms less than clock time.
417 1 : TimeDelta difference = delta - delta_thread;
418 1 : EXPECT_GE(difference.InMicroseconds(), 9000);
419 : }
420 1 : }
421 :
422 :
423 : #if V8_OS_WIN
424 : TEST(TimeTicks, TimerPerformance) {
425 : // Verify that various timer mechanisms can always complete quickly.
426 : // Note: This is a somewhat arbitrary test.
427 : const int kLoops = 10000;
428 :
429 : typedef TimeTicks (*TestFunc)();
430 : struct TestCase {
431 : TestFunc func;
432 : const char *description;
433 : };
434 : // Cheating a bit here: assumes sizeof(TimeTicks) == sizeof(Time)
435 : // in order to create a single test case list.
436 : static_assert(sizeof(TimeTicks) == sizeof(Time),
437 : "TimeTicks and Time must be the same size");
438 : std::vector<TestCase> cases;
439 : cases.push_back({reinterpret_cast<TestFunc>(&Time::Now), "Time::Now"});
440 : cases.push_back({&TimeTicks::Now, "TimeTicks::Now"});
441 :
442 : if (ThreadTicks::IsSupported()) {
443 : ThreadTicks::WaitUntilInitialized();
444 : cases.push_back(
445 : {reinterpret_cast<TestFunc>(&ThreadTicks::Now), "ThreadTicks::Now"});
446 : }
447 :
448 : for (const auto& test_case : cases) {
449 : TimeTicks start = TimeTicks::Now();
450 : for (int index = 0; index < kLoops; index++)
451 : test_case.func();
452 : TimeTicks stop = TimeTicks::Now();
453 : // Turning off the check for acceptable delays. Without this check,
454 : // the test really doesn't do much other than measure. But the
455 : // measurements are still useful for testing timers on various platforms.
456 : // The reason to remove the check is because the tests run on many
457 : // buildbots, some of which are VMs. These machines can run horribly
458 : // slow, and there is really no value for checking against a max timer.
459 : // const int kMaxTime = 35; // Maximum acceptable milliseconds for test.
460 : // EXPECT_LT((stop - start).InMilliseconds(), kMaxTime);
461 : printf("%s: %1.2fus per call\n", test_case.description,
462 : (stop - start).InMillisecondsF() * 1000 / kLoops);
463 : }
464 : }
465 : #endif // V8_OS_WIN
466 :
467 : } // namespace base
468 9264 : } // namespace v8
|