perf_hooks: fix histogram 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-09 22:29:43 +01:00 committed by Node.js GitHub Bot
parent f5e2ecc41b
commit e9a0912848
4 changed files with 77 additions and 58 deletions

View File

@ -2,6 +2,7 @@
#include "base_object-inl.h" #include "base_object-inl.h"
#include "histogram-inl.h" #include "histogram-inl.h"
#include "memory_tracker-inl.h" #include "memory_tracker-inl.h"
#include "node_debug.h"
#include "node_errors.h" #include "node_errors.h"
#include "node_external_reference.h" #include "node_external_reference.h"
#include "util.h" #include "util.h"
@ -11,10 +12,8 @@ namespace node {
using v8::BigInt; using v8::BigInt;
using v8::CFunction; using v8::CFunction;
using v8::Context; using v8::Context;
using v8::FastApiCallbackOptions;
using v8::FunctionCallbackInfo; using v8::FunctionCallbackInfo;
using v8::FunctionTemplate; using v8::FunctionTemplate;
using v8::HandleScope;
using v8::Integer; using v8::Integer;
using v8::Isolate; using v8::Isolate;
using v8::Local; using v8::Local;
@ -162,8 +161,8 @@ void HistogramBase::RecordDelta(const FunctionCallbackInfo<Value>& args) {
(*histogram)->RecordDelta(); (*histogram)->RecordDelta();
} }
void HistogramBase::FastRecordDelta(Local<Value> unused, void HistogramBase::FastRecordDelta(Local<Value> receiver) {
Local<Value> receiver) { TRACK_V8_FAST_API_CALL("histogram.recordDelta");
HistogramBase* histogram; HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver); ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
(*histogram)->RecordDelta(); (*histogram)->RecordDelta();
@ -183,15 +182,9 @@ void HistogramBase::Record(const FunctionCallbackInfo<Value>& args) {
(*histogram)->Record(value); (*histogram)->Record(value);
} }
void HistogramBase::FastRecord(Local<Value> unused, void HistogramBase::FastRecord(Local<Value> receiver, const int64_t value) {
Local<Value> receiver, CHECK_GE(value, 1);
const int64_t value, TRACK_V8_FAST_API_CALL("histogram.record");
FastApiCallbackOptions& options) {
if (value < 1) {
HandleScope scope(options.isolate);
THROW_ERR_OUT_OF_RANGE(options.isolate, "value is out of range");
return;
}
HistogramBase* histogram; HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver); ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
(*histogram)->Record(value); (*histogram)->Record(value);
@ -428,9 +421,8 @@ void IntervalHistogram::Start(const FunctionCallbackInfo<Value>& args) {
histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE); histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE);
} }
void IntervalHistogram::FastStart(Local<Value> unused, void IntervalHistogram::FastStart(Local<Value> receiver, bool reset) {
Local<Value> receiver, TRACK_V8_FAST_API_CALL("histogram.start");
bool reset) {
IntervalHistogram* histogram; IntervalHistogram* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver); ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
histogram->OnStart(reset ? StartFlags::RESET : StartFlags::NONE); histogram->OnStart(reset ? StartFlags::RESET : StartFlags::NONE);
@ -442,7 +434,8 @@ void IntervalHistogram::Stop(const FunctionCallbackInfo<Value>& args) {
histogram->OnStop(); histogram->OnStop();
} }
void IntervalHistogram::FastStop(Local<Value> unused, Local<Value> receiver) { void IntervalHistogram::FastStop(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("histogram.stop");
IntervalHistogram* histogram; IntervalHistogram* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver); ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
histogram->OnStop(); histogram->OnStop();
@ -555,46 +548,51 @@ void HistogramImpl::DoReset(const FunctionCallbackInfo<Value>& args) {
(*histogram)->Reset(); (*histogram)->Reset();
} }
void HistogramImpl::FastReset(Local<Value> unused, Local<Value> receiver) { void HistogramImpl::FastReset(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("histogram.reset");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
(*histogram)->Reset(); (*histogram)->Reset();
} }
double HistogramImpl::FastGetCount(Local<Value> unused, Local<Value> receiver) { double HistogramImpl::FastGetCount(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("histogram.count");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Count()); return static_cast<double>((*histogram)->Count());
} }
double HistogramImpl::FastGetMin(Local<Value> unused, Local<Value> receiver) { double HistogramImpl::FastGetMin(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("histogram.min");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Min()); return static_cast<double>((*histogram)->Min());
} }
double HistogramImpl::FastGetMax(Local<Value> unused, Local<Value> receiver) { double HistogramImpl::FastGetMax(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("histogram.max");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Max()); return static_cast<double>((*histogram)->Max());
} }
double HistogramImpl::FastGetMean(Local<Value> unused, Local<Value> receiver) { double HistogramImpl::FastGetMean(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("histogram.mean");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return (*histogram)->Mean(); return (*histogram)->Mean();
} }
double HistogramImpl::FastGetExceeds(Local<Value> unused, double HistogramImpl::FastGetExceeds(Local<Value> receiver) {
Local<Value> receiver) { TRACK_V8_FAST_API_CALL("histogram.exceeds");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Exceeds()); return static_cast<double>((*histogram)->Exceeds());
} }
double HistogramImpl::FastGetStddev(Local<Value> unused, double HistogramImpl::FastGetStddev(Local<Value> receiver) {
Local<Value> receiver) { TRACK_V8_FAST_API_CALL("histogram.stddev");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return (*histogram)->Stddev(); return (*histogram)->Stddev();
} }
double HistogramImpl::FastGetPercentile(Local<Value> unused, double HistogramImpl::FastGetPercentile(Local<Value> receiver,
Local<Value> receiver,
const double percentile) { const double percentile) {
TRACK_V8_FAST_API_CALL("histogram.percentile");
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver); HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Percentile(percentile)); return static_cast<double>((*histogram)->Percentile(percentile));
} }

View File

@ -101,22 +101,14 @@ class HistogramImpl {
static void GetPercentilesBigInt( static void GetPercentilesBigInt(
const v8::FunctionCallbackInfo<v8::Value>& args); const v8::FunctionCallbackInfo<v8::Value>& args);
static void FastReset(v8::Local<v8::Value> unused, static void FastReset(v8::Local<v8::Value> receiver);
v8::Local<v8::Value> receiver); static double FastGetCount(v8::Local<v8::Value> receiver);
static double FastGetCount(v8::Local<v8::Value> unused, static double FastGetMin(v8::Local<v8::Value> receiver);
v8::Local<v8::Value> receiver); static double FastGetMax(v8::Local<v8::Value> receiver);
static double FastGetMin(v8::Local<v8::Value> unused, static double FastGetMean(v8::Local<v8::Value> receiver);
v8::Local<v8::Value> receiver); static double FastGetExceeds(v8::Local<v8::Value> receiver);
static double FastGetMax(v8::Local<v8::Value> unused, static double FastGetStddev(v8::Local<v8::Value> receiver);
v8::Local<v8::Value> receiver); static double FastGetPercentile(v8::Local<v8::Value> receiver,
static double FastGetMean(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver);
static double FastGetExceeds(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver);
static double FastGetStddev(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver);
static double FastGetPercentile(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver,
const double percentile); const double percentile);
static void AddMethods(v8::Isolate* isolate, static void AddMethods(v8::Isolate* isolate,
@ -165,13 +157,8 @@ class HistogramBase final : public BaseObject, public HistogramImpl {
static void RecordDelta(const v8::FunctionCallbackInfo<v8::Value>& args); static void RecordDelta(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Add(const v8::FunctionCallbackInfo<v8::Value>& args); static void Add(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FastRecord( static void FastRecord(v8::Local<v8::Value> receiver, const int64_t value);
v8::Local<v8::Value> unused, static void FastRecordDelta(v8::Local<v8::Value> receiver);
v8::Local<v8::Value> receiver,
const int64_t value,
v8::FastApiCallbackOptions& options); // NOLINT(runtime/references)
static void FastRecordDelta(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver);
HistogramBase( HistogramBase(
Environment* env, Environment* env,
@ -243,11 +230,8 @@ class IntervalHistogram final : public HandleWrap, public HistogramImpl {
static void Start(const v8::FunctionCallbackInfo<v8::Value>& args); static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args); static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FastStart(v8::Local<v8::Value> unused, static void FastStart(v8::Local<v8::Value> receiver, bool reset);
v8::Local<v8::Value> receiver, static void FastStop(v8::Local<v8::Value> receiver);
bool reset);
static void FastStop(v8::Local<v8::Value> unused,
v8::Local<v8::Value> receiver);
BaseObject::TransferMode GetTransferMode() const override { BaseObject::TransferMode GetTransferMode() const override {
return TransferMode::kCloneable; return TransferMode::kCloneable;

View File

@ -0,0 +1,35 @@
// Flags: --expose-internals --no-warnings --allow-natives-syntax
'use strict';
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const histogram = require('perf_hooks').createHistogram();
function testFastMethods() {
histogram.record(1);
histogram.recordDelta();
histogram.percentile(50);
histogram.reset();
}
eval('%PrepareFunctionForOptimization(histogram.record)');
eval('%PrepareFunctionForOptimization(histogram.recordDelta)');
eval('%PrepareFunctionForOptimization(histogram.percentile)');
eval('%PrepareFunctionForOptimization(histogram.reset)');
testFastMethods();
eval('%OptimizeFunctionOnNextCall(histogram.record)');
eval('%OptimizeFunctionOnNextCall(histogram.recordDelta)');
eval('%OptimizeFunctionOnNextCall(histogram.percentile)');
eval('%OptimizeFunctionOnNextCall(histogram.reset)');
testFastMethods();
if (common.isDebug) {
const { getV8FastApiCallCount } = internalBinding('debug');
assert.strictEqual(getV8FastApiCallCount('histogram.record'), 1);
assert.strictEqual(getV8FastApiCallCount('histogram.recordDelta'), 1);
assert.strictEqual(getV8FastApiCallCount('histogram.percentile'), 1);
assert.strictEqual(getV8FastApiCallCount('histogram.reset'), 1);
}

View File

@ -41,8 +41,10 @@ const { inspect } = require('util');
code: 'ERR_INVALID_ARG_TYPE' code: 'ERR_INVALID_ARG_TYPE'
}); });
}); });
throws(() => h.record(0, Number.MAX_SAFE_INTEGER + 1), { [0, Number.MAX_SAFE_INTEGER + 1].forEach((i) => {
code: 'ERR_OUT_OF_RANGE' throws(() => h.record(i), {
code: 'ERR_OUT_OF_RANGE'
});
}); });
strictEqual(h.min, 1); strictEqual(h.min, 1);