Skip to content

Commit 543dabb

Browse files
committed
timers: improve Timer.now() performance
Record the start time so we can make the return value of Timer.now() relative to it, increasing the chances that it fits in a tagged integer instead of a heap-allocated double, at least for the first one or two billion milliseconds. PR-URL: #2256 Reviewed-By: Trevor Norris <[email protected]>
1 parent 3663b12 commit 543dabb

File tree

4 files changed

+17
-0
lines changed

4 files changed

+17
-0
lines changed

src/env-inl.h

+5
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ inline Environment::Environment(v8::Local<v8::Context> context,
171171
uv_loop_t* loop)
172172
: isolate_(context->GetIsolate()),
173173
isolate_data_(IsolateData::GetOrCreate(context->GetIsolate(), loop)),
174+
timer_base_(uv_now(loop)),
174175
using_smalloc_alloc_cb_(false),
175176
using_domains_(false),
176177
using_abort_on_uncaught_exc_(false),
@@ -286,6 +287,10 @@ inline Environment::TickInfo* Environment::tick_info() {
286287
return &tick_info_;
287288
}
288289

290+
inline uint64_t Environment::timer_base() const {
291+
return timer_base_;
292+
}
293+
289294
inline bool Environment::using_smalloc_alloc_cb() const {
290295
return using_smalloc_alloc_cb_;
291296
}

src/env.h

+2
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class Environment {
398398
inline AsyncHooks* async_hooks();
399399
inline DomainFlag* domain_flag();
400400
inline TickInfo* tick_info();
401+
inline uint64_t timer_base() const;
401402

402403
static inline Environment* from_cares_timer_handle(uv_timer_t* handle);
403404
inline uv_timer_t* cares_timer_handle();
@@ -501,6 +502,7 @@ class Environment {
501502
AsyncHooks async_hooks_;
502503
DomainFlag domain_flag_;
503504
TickInfo tick_info_;
505+
const uint64_t timer_base_;
504506
uv_timer_t cares_timer_handle_;
505507
ares_channel cares_channel_;
506508
ares_task_list cares_task_list_;

src/timer_wrap.cc

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ class TimerWrap : public HandleWrap {
101101
Environment* env = Environment::GetCurrent(args);
102102
uv_update_time(env->event_loop());
103103
uint64_t now = uv_now(env->event_loop());
104+
CHECK(now >= env->timer_base());
105+
now -= env->timer_base();
104106
if (now <= 0xfffffff)
105107
args.GetReturnValue().Set(static_cast<uint32_t>(now));
106108
else

test/parallel/test-timers-now.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
6+
// Return value of Timer.now() should easily fit in a SMI right after start-up.
7+
const Timer = process.binding('timer_wrap').Timer;
8+
assert(Timer.now() < 0x3ffffff);

0 commit comments

Comments
 (0)