node/lib/internal/perf/timerify.js
legendecas 364c0e196c
perf_hooks: fix webperf idlharness
1. Enforce receiver checks on IDL interfaces.
2. Avoid prototype manipulation on constructing IDL interfaces with
   `ReflectConstruct`.
3. `defineReplaceableAttribute` should create IDL getter/setter.
4. Corrected `PerformanceResourceTiming` to inherit the public interface
   `PerformanceEntry` instead of the internal interface
   `InternalPerformanceResourceTiming`.
5. `detail` is not a specified attribute on `PerfomanceEntry`. Node.js
   specific extensions are moved to a subclass of `PerformanceEntry` as
   `PerformanceNodeEntry`.

PR-URL: https://github.com/nodejs/node/pull/44483
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2022-10-04 00:55:58 +08:00

110 lines
2.2 KiB
JavaScript

'use strict';
const {
FunctionPrototypeBind,
ObjectDefineProperties,
MathCeil,
ReflectApply,
ReflectConstruct,
} = primordials;
const { createPerformanceNodeEntry } = require('internal/perf/performance_entry');
const { now } = require('internal/perf/utils');
const {
validateFunction,
validateObject,
} = require('internal/validators');
const {
isHistogram
} = require('internal/histogram');
const {
codes: {
ERR_INVALID_ARG_TYPE,
},
} = require('internal/errors');
const {
enqueue,
} = require('internal/perf/observe');
const {
kEmptyObject,
} = require('internal/util');
function processComplete(name, start, args, histogram) {
const duration = now() - start;
if (histogram !== undefined)
histogram.record(MathCeil(duration * 1e6));
const entry =
createPerformanceNodeEntry(
name,
'function',
start,
duration,
args);
for (let n = 0; n < args.length; n++)
entry[n] = args[n];
enqueue(entry);
}
function timerify(fn, options = kEmptyObject) {
validateFunction(fn, 'fn');
validateObject(options, 'options');
const {
histogram
} = options;
if (histogram !== undefined &&
(!isHistogram(histogram) || typeof histogram.record !== 'function')) {
throw new ERR_INVALID_ARG_TYPE(
'options.histogram',
'RecordableHistogram',
histogram);
}
function timerified(...args) {
const isConstructorCall = new.target !== undefined;
const start = now();
const result = isConstructorCall ?
ReflectConstruct(fn, args, fn) :
ReflectApply(fn, this, args);
if (!isConstructorCall && typeof result?.finally === 'function') {
return result.finally(
FunctionPrototypeBind(
processComplete,
result,
fn.name,
start,
args,
histogram));
}
processComplete(fn.name, start, args, histogram);
return result;
}
ObjectDefineProperties(timerified, {
length: {
__proto__: null,
configurable: false,
enumerable: true,
value: fn.length,
},
name: {
__proto__: null,
configurable: false,
enumerable: true,
value: `timerified ${fn.name}`
}
});
return timerified;
}
module.exports = timerify;