diff --git a/src/env-inl.h b/src/env-inl.h index 0feefdb1e4..e31618536b 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -171,6 +171,7 @@ inline Environment::Environment(v8::Local context, uv_loop_t* loop) : isolate_(context->GetIsolate()), isolate_data_(IsolateData::GetOrCreate(context->GetIsolate(), loop)), + timer_base_(uv_now(loop)), using_smalloc_alloc_cb_(false), using_domains_(false), using_abort_on_uncaught_exc_(false), @@ -286,6 +287,10 @@ inline Environment::TickInfo* Environment::tick_info() { return &tick_info_; } +inline uint64_t Environment::timer_base() const { + return timer_base_; +} + inline bool Environment::using_smalloc_alloc_cb() const { return using_smalloc_alloc_cb_; } diff --git a/src/env.h b/src/env.h index b53ff87fb1..72895219a9 100644 --- a/src/env.h +++ b/src/env.h @@ -398,6 +398,7 @@ class Environment { inline AsyncHooks* async_hooks(); inline DomainFlag* domain_flag(); inline TickInfo* tick_info(); + inline uint64_t timer_base() const; static inline Environment* from_cares_timer_handle(uv_timer_t* handle); inline uv_timer_t* cares_timer_handle(); @@ -501,6 +502,7 @@ class Environment { AsyncHooks async_hooks_; DomainFlag domain_flag_; TickInfo tick_info_; + const uint64_t timer_base_; uv_timer_t cares_timer_handle_; ares_channel cares_channel_; ares_task_list cares_task_list_; diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc index 3f2fff1fac..f3d5d1fedb 100644 --- a/src/timer_wrap.cc +++ b/src/timer_wrap.cc @@ -101,6 +101,8 @@ class TimerWrap : public HandleWrap { Environment* env = Environment::GetCurrent(args); uv_update_time(env->event_loop()); uint64_t now = uv_now(env->event_loop()); + CHECK(now >= env->timer_base()); + now -= env->timer_base(); if (now <= 0xfffffff) args.GetReturnValue().Set(static_cast(now)); else diff --git a/test/parallel/test-timers-now.js b/test/parallel/test-timers-now.js new file mode 100644 index 0000000000..466bd064b8 --- /dev/null +++ b/test/parallel/test-timers-now.js @@ -0,0 +1,8 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +// Return value of Timer.now() should easily fit in a SMI right after start-up. +const Timer = process.binding('timer_wrap').Timer; +assert(Timer.now() < 0x3ffffff);