diff --git a/benchmark/misc/bench-hrtime.js b/benchmark/misc/bench-hrtime.js new file mode 100644 index 00000000000000..661dff43b0103c --- /dev/null +++ b/benchmark/misc/bench-hrtime.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../common'); + +const bench = common.createBenchmark(main, { + n: [1e6] +}); + + +function main(conf) { + const n = conf.n >>> 0; + + bench.start(); + for (var i = 0; i < n; i++) { + process.hrtime(); + } + bench.end(n); +} diff --git a/src/node.cc b/src/node.cc index be80ab3124d716..e03d541f3ceb32 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2132,22 +2132,23 @@ void Hrtime(const FunctionCallbackInfo& args) { uint64_t t = uv_hrtime(); - if (args.Length() > 0) { - // return a time diff tuple - if (!args[0]->IsArray()) { + if (!args[1]->IsUndefined()) { + if (!args[1]->IsArray()) { return env->ThrowTypeError( - "process.hrtime() only accepts an Array tuple."); + "process.hrtime() only accepts an Array tuple"); } - Local inArray = Local::Cast(args[0]); - uint64_t seconds = inArray->Get(0)->Uint32Value(); - uint64_t nanos = inArray->Get(1)->Uint32Value(); - t -= (seconds * NANOS_PER_SEC) + nanos; + args.GetReturnValue().Set(true); } - Local tuple = Array::New(env->isolate(), 2); - tuple->Set(0, Integer::NewFromUnsigned(env->isolate(), t / NANOS_PER_SEC)); - tuple->Set(1, Integer::NewFromUnsigned(env->isolate(), t % NANOS_PER_SEC)); - args.GetReturnValue().Set(tuple); + Local ab = args[0].As()->Buffer(); + uint32_t* fields = static_cast(ab->GetContents().Data()); + + // These three indices will contain the values for the hrtime tuple. The + // seconds value is broken into the upper/lower 32 bits and stored in two + // uint32 fields to be converted back in JS. + fields[0] = (t / NANOS_PER_SEC) >> 32; + fields[1] = (t / NANOS_PER_SEC) & 0xffffffff; + fields[2] = t % NANOS_PER_SEC; } extern "C" void node_module_register(void* m) { diff --git a/src/node.js b/src/node.js index 8d77adc27c4102..f91b20ef60d28b 100644 --- a/src/node.js +++ b/src/node.js @@ -181,12 +181,27 @@ } startup.setupProcessObject = function() { + const _hrtime = process.hrtime; + const hrValues = new Uint32Array(3); + process._setupProcessObject(pushValueToArray); function pushValueToArray() { for (var i = 0; i < arguments.length; i++) this.push(arguments[i]); } + + process.hrtime = function hrtime(ar) { + const ret = [0, 0]; + if (_hrtime(hrValues, ar)) { + ret[0] = (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0]; + ret[1] = hrValues[2] - ar[1]; + } else { + ret[0] = hrValues[0] * 0x100000000 + hrValues[1]; + ret[1] = hrValues[2]; + } + return ret; + }; }; startup.globalVariables = function() {