process: implement process.hrtime.bigint()

PR-URL: https://github.com/nodejs/node/pull/21256
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
This commit is contained in:
Joyee Cheung 2018-06-11 17:37:09 +08:00
parent 54ee8cb5dd
commit 1d8a231733
No known key found for this signature in database
GPG Key ID: 92B78A53C8303B8D
7 changed files with 71 additions and 3 deletions

View File

@ -1159,6 +1159,9 @@ added: v0.7.6
* `time` {integer[]} The result of a previous call to `process.hrtime()` * `time` {integer[]} The result of a previous call to `process.hrtime()`
* Returns: {integer[]} * Returns: {integer[]}
This is the legacy version of [`process.hrtime.bigint()`][]
before `bigint` was introduced in JavaScript.
The `process.hrtime()` method returns the current high-resolution real time The `process.hrtime()` method returns the current high-resolution real time
in a `[seconds, nanoseconds]` tuple `Array`, where `nanoseconds` is the in a `[seconds, nanoseconds]` tuple `Array`, where `nanoseconds` is the
remaining part of the real time that can't be represented in second precision. remaining part of the real time that can't be represented in second precision.
@ -1187,6 +1190,33 @@ setTimeout(() => {
}, 1000); }, 1000);
``` ```
## process.hrtime.bigint()
<!-- YAML
added: REPLACEME
-->
* Returns: {bigint}
The `bigint` version of the [`process.hrtime()`][] method returning the
current high-resolution real time in a `bigint`.
Unlike [`process.hrtime()`][], it does not support an additional `time`
argument since the difference can just be computed directly
by subtraction of the two `bigint`s.
```js
const start = process.hrtime.bigint();
// 191051479007711n
setTimeout(() => {
const end = process.hrtime.bigint();
// 191052633396993n
console.log(`Benchmark took ${end - start} nanoseconds`);
// Benchmark took 1154389282 nanoseconds
}, 1000);
```
## process.initgroups(user, extraGroup) ## process.initgroups(user, extraGroup)
<!-- YAML <!-- YAML
added: v0.9.4 added: v0.9.4
@ -2030,6 +2060,8 @@ cases:
[`process.execPath`]: #process_process_execpath [`process.execPath`]: #process_process_execpath
[`process.exit()`]: #process_process_exit_code [`process.exit()`]: #process_process_exit_code
[`process.exitCode`]: #process_process_exitcode [`process.exitCode`]: #process_process_exitcode
[`process.hrtime()`]: #process_process_hrtime_time
[`process.hrtime.bigint()`]: #process_process_hrtime_bigint
[`process.kill()`]: #process_process_kill_pid_signal [`process.kill()`]: #process_process_kill_pid_signal
[`process.setUncaughtExceptionCaptureCallback()`]: process.html#process_process_setuncaughtexceptioncapturecallback_fn [`process.setUncaughtExceptionCaptureCallback()`]: process.html#process_process_setuncaughtexceptioncapturecallback_fn
[`promise.catch()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch [`promise.catch()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch

View File

@ -18,7 +18,8 @@
// object. // object.
{ _setupProcessObject, _setupNextTick, { _setupProcessObject, _setupNextTick,
_setupPromises, _chdir, _cpuUsage, _setupPromises, _chdir, _cpuUsage,
_hrtime, _memoryUsage, _rawDebug, _hrtime, _hrtimeBigInt,
_memoryUsage, _rawDebug,
_umask, _initgroups, _setegid, _seteuid, _umask, _initgroups, _setegid, _seteuid,
_setgid, _setuid, _setgroups, _setgid, _setuid, _setgroups,
_shouldAbortOnUncaughtToggle }, _shouldAbortOnUncaughtToggle },
@ -70,7 +71,7 @@
NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE, NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE,
} = perf.constants; } = perf.constants;
_process.setup_hrtime(_hrtime); _process.setup_hrtime(_hrtime, _hrtimeBigInt);
_process.setup_cpuUsage(_cpuUsage); _process.setup_cpuUsage(_cpuUsage);
_process.setupMemoryUsage(_memoryUsage); _process.setupMemoryUsage(_memoryUsage);
_process.setupKillAndExit(); _process.setupKillAndExit();

View File

@ -90,7 +90,7 @@ function setup_cpuUsage(_cpuUsage) {
// The 3 entries filled in by the original process.hrtime contains // The 3 entries filled in by the original process.hrtime contains
// the upper/lower 32 bits of the second part of the value, // the upper/lower 32 bits of the second part of the value,
// and the remaining nanoseconds of the value. // and the remaining nanoseconds of the value.
function setup_hrtime(_hrtime) { function setup_hrtime(_hrtime, _hrtimeBigInt) {
const hrValues = new Uint32Array(3); const hrValues = new Uint32Array(3);
process.hrtime = function hrtime(time) { process.hrtime = function hrtime(time) {
@ -115,6 +115,14 @@ function setup_hrtime(_hrtime) {
hrValues[2] hrValues[2]
]; ];
}; };
// Use a BigUint64Array in the closure because V8 does not have an API for
// creating a BigInt out of a uint64_t yet.
const hrBigintValues = new BigUint64Array(1);
process.hrtime.bigint = function() {
_hrtimeBigInt(hrBigintValues);
return hrBigintValues[0];
};
} }
function setupMemoryUsage(_memoryUsage) { function setupMemoryUsage(_memoryUsage) {

View File

@ -109,6 +109,7 @@ void SetupBootstrapObject(Environment* env,
BOOTSTRAP_METHOD(_chdir, Chdir); BOOTSTRAP_METHOD(_chdir, Chdir);
BOOTSTRAP_METHOD(_cpuUsage, CPUUsage); BOOTSTRAP_METHOD(_cpuUsage, CPUUsage);
BOOTSTRAP_METHOD(_hrtime, Hrtime); BOOTSTRAP_METHOD(_hrtime, Hrtime);
BOOTSTRAP_METHOD(_hrtimeBigInt, HrtimeBigInt);
BOOTSTRAP_METHOD(_memoryUsage, MemoryUsage); BOOTSTRAP_METHOD(_memoryUsage, MemoryUsage);
BOOTSTRAP_METHOD(_rawDebug, RawDebug); BOOTSTRAP_METHOD(_rawDebug, RawDebug);
BOOTSTRAP_METHOD(_umask, Umask); BOOTSTRAP_METHOD(_umask, Umask);

View File

@ -905,6 +905,7 @@ void Chdir(const v8::FunctionCallbackInfo<v8::Value>& args);
void CPUUsage(const v8::FunctionCallbackInfo<v8::Value>& args); void CPUUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
void Cwd(const v8::FunctionCallbackInfo<v8::Value>& args); void Cwd(const v8::FunctionCallbackInfo<v8::Value>& args);
void Hrtime(const v8::FunctionCallbackInfo<v8::Value>& args); void Hrtime(const v8::FunctionCallbackInfo<v8::Value>& args);
void HrtimeBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
void Kill(const v8::FunctionCallbackInfo<v8::Value>& args); void Kill(const v8::FunctionCallbackInfo<v8::Value>& args);
void MemoryUsage(const v8::FunctionCallbackInfo<v8::Value>& args); void MemoryUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
void RawDebug(const v8::FunctionCallbackInfo<v8::Value>& args); void RawDebug(const v8::FunctionCallbackInfo<v8::Value>& args);

View File

@ -31,6 +31,7 @@ namespace node {
using v8::Array; using v8::Array;
using v8::ArrayBuffer; using v8::ArrayBuffer;
using v8::BigUint64Array;
using v8::Float64Array; using v8::Float64Array;
using v8::FunctionCallbackInfo; using v8::FunctionCallbackInfo;
using v8::HeapStatistics; using v8::HeapStatistics;
@ -113,7 +114,11 @@ void Cwd(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(cwd); args.GetReturnValue().Set(cwd);
} }
// Hrtime exposes libuv's uv_hrtime() high-resolution timer. // Hrtime exposes libuv's uv_hrtime() high-resolution timer.
// This is the legacy version of hrtime before BigInt was introduced in
// JavaScript.
// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds, // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
// so this function instead fills in an Uint32Array with 3 entries, // so this function instead fills in an Uint32Array with 3 entries,
// to avoid any integer overflow possibility. // to avoid any integer overflow possibility.
@ -132,6 +137,12 @@ void Hrtime(const FunctionCallbackInfo<Value>& args) {
fields[2] = t % NANOS_PER_SEC; fields[2] = t % NANOS_PER_SEC;
} }
void HrtimeBigInt(const FunctionCallbackInfo<Value>& args) {
Local<ArrayBuffer> ab = args[0].As<BigUint64Array>()->Buffer();
uint64_t* fields = static_cast<uint64_t*>(ab->GetContents().Data());
fields[0] = uv_hrtime();
}
void Kill(const FunctionCallbackInfo<Value>& args) { void Kill(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);

View File

@ -0,0 +1,14 @@
'use strict';
// Tests that process.hrtime.bigint() works.
require('../common');
const assert = require('assert');
const start = process.hrtime.bigint();
assert.strictEqual(typeof start, 'bigint');
const end = process.hrtime.bigint();
assert.strictEqual(typeof end, 'bigint');
assert(end - start >= 0n);