process: fix hrtime fast call signatures

PR-URL: https://github.com/nodejs/node/pull/59600
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
Renegade334 2025-07-13 21:10:18 +01:00 committed by Node.js GitHub Bot
parent e9a0912848
commit 5ac6ee7716
4 changed files with 55 additions and 28 deletions

View File

@ -3,6 +3,7 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "node_debug.h"
#include "node_snapshotable.h"
#include "v8-fast-api-calls.h"
#include "v8.h"
@ -72,23 +73,23 @@ class BindingData : public SnapshotableObject {
SET_SELF_SIZE(BindingData)
static BindingData* FromV8Value(v8::Local<v8::Value> receiver);
static void NumberImpl(BindingData* receiver);
static void HrtimeImpl(BindingData* receiver);
static void FastNumber(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver) {
NumberImpl(FromV8Value(receiver));
static void FastHrtime(v8::Local<v8::Value> receiver) {
TRACK_V8_FAST_API_CALL("process.hrtime");
HrtimeImpl(FromV8Value(receiver));
}
static void SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SlowHrtime(const v8::FunctionCallbackInfo<v8::Value>& args);
static void BigIntImpl(BindingData* receiver);
static void HrtimeBigIntImpl(BindingData* receiver);
static void FastBigInt(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver) {
BigIntImpl(FromV8Value(receiver));
static void FastHrtimeBigInt(v8::Local<v8::Value> receiver) {
TRACK_V8_FAST_API_CALL("process.hrtimeBigInt");
HrtimeBigIntImpl(FromV8Value(receiver));
}
static void SlowBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SlowHrtimeBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void LoadEnvFile(const v8::FunctionCallbackInfo<v8::Value>& args);
@ -101,8 +102,8 @@ class BindingData : public SnapshotableObject {
// These need to be static so that we have their addresses available to
// register as external references in the snapshot at environment creation
// time.
static v8::CFunction fast_number_;
static v8::CFunction fast_bigint_;
static v8::CFunction fast_hrtime_;
static v8::CFunction fast_hrtime_bigint_;
};
} // namespace process

View File

@ -652,22 +652,22 @@ BindingData::BindingData(Realm* realm,
hrtime_buffer_.MakeWeak();
}
v8::CFunction BindingData::fast_number_(v8::CFunction::Make(FastNumber));
v8::CFunction BindingData::fast_bigint_(v8::CFunction::Make(FastBigInt));
CFunction BindingData::fast_hrtime_(CFunction::Make(FastHrtime));
CFunction BindingData::fast_hrtime_bigint_(CFunction::Make(FastHrtimeBigInt));
void BindingData::AddMethods(Isolate* isolate, Local<ObjectTemplate> target) {
SetFastMethodNoSideEffect(
isolate, target, "hrtime", SlowNumber, &fast_number_);
isolate, target, "hrtime", SlowHrtime, &fast_hrtime_);
SetFastMethodNoSideEffect(
isolate, target, "hrtimeBigInt", SlowBigInt, &fast_bigint_);
isolate, target, "hrtimeBigInt", SlowHrtimeBigInt, &fast_hrtime_bigint_);
}
void BindingData::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
registry->Register(SlowNumber);
registry->Register(SlowBigInt);
registry->Register(fast_number_);
registry->Register(fast_bigint_);
registry->Register(SlowHrtime);
registry->Register(SlowHrtimeBigInt);
registry->Register(fast_hrtime_);
registry->Register(fast_hrtime_bigint_);
}
BindingData* BindingData::FromV8Value(Local<Value> value) {
@ -689,14 +689,14 @@ void BindingData::MemoryInfo(MemoryTracker* tracker) const {
// broken into the upper/lower 32 bits to be converted back in JS,
// because there is no Uint64Array in JS.
// The third entry contains the remaining nanosecond part of the value.
void BindingData::NumberImpl(BindingData* receiver) {
void BindingData::HrtimeImpl(BindingData* receiver) {
uint64_t t = uv_hrtime();
receiver->hrtime_buffer_[0] = (t / NANOS_PER_SEC) >> 32;
receiver->hrtime_buffer_[1] = (t / NANOS_PER_SEC) & 0xffffffff;
receiver->hrtime_buffer_[2] = t % NANOS_PER_SEC;
}
void BindingData::BigIntImpl(BindingData* receiver) {
void BindingData::HrtimeBigIntImpl(BindingData* receiver) {
uint64_t t = uv_hrtime();
// The buffer is a Uint32Array, so we need to reinterpret it as a
// Uint64Array to write the value. The buffer is valid at this scope so we
@ -706,12 +706,12 @@ void BindingData::BigIntImpl(BindingData* receiver) {
fields[0] = t;
}
void BindingData::SlowBigInt(const FunctionCallbackInfo<Value>& args) {
BigIntImpl(FromJSObject<BindingData>(args.This()));
void BindingData::SlowHrtimeBigInt(const FunctionCallbackInfo<Value>& args) {
HrtimeBigIntImpl(FromJSObject<BindingData>(args.This()));
}
void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
NumberImpl(FromJSObject<BindingData>(args.This()));
void BindingData::SlowHrtime(const FunctionCallbackInfo<Value>& args) {
HrtimeImpl(FromJSObject<BindingData>(args.This()));
}
bool BindingData::PrepareForSerialization(Local<Context> context,

View File

@ -1,10 +1,13 @@
// Flags: --allow-natives-syntax --expose-internals --no-warnings
'use strict';
// Tests that process.hrtime.bigint() works.
require('../common');
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const start = process.hrtime.bigint();
assert.strictEqual(typeof start, 'bigint');
@ -12,3 +15,13 @@ const end = process.hrtime.bigint();
assert.strictEqual(typeof end, 'bigint');
assert(end - start >= 0n);
eval('%PrepareFunctionForOptimization(process.hrtime.bigint)');
assert(process.hrtime.bigint());
eval('%OptimizeFunctionOnNextCall(process.hrtime.bigint)');
assert(process.hrtime.bigint());
if (common.isDebug) {
const { getV8FastApiCallCount } = internalBinding('debug');
assert.strictEqual(getV8FastApiCallCount('process.hrtimeBigInt'), 1);
}

View File

@ -19,10 +19,13 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// Flags: --allow-natives-syntax --expose-internals --no-warnings
'use strict';
require('../common');
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
// The default behavior, return an Array "tuple" of numbers
const tuple = process.hrtime();
@ -72,3 +75,13 @@ function validateTuple(tuple) {
const diff = process.hrtime([0, 1e9 - 1]);
assert(diff[1] >= 0); // https://github.com/nodejs/node/issues/4751
eval('%PrepareFunctionForOptimization(process.hrtime)');
assert(process.hrtime());
eval('%OptimizeFunctionOnNextCall(process.hrtime)');
assert(process.hrtime());
if (common.isDebug) {
const { getV8FastApiCallCount } = internalBinding('debug');
assert.strictEqual(getV8FastApiCallCount('process.hrtime'), 1);
}