From 123fa0c061047760cb9f23d25511a02e6ea1dc29 Mon Sep 17 00:00:00 2001 From: Himself65 Date: Sun, 24 Apr 2022 17:33:00 -0500 Subject: [PATCH] perf_hooks: return different timerified function in timerify Fixes: https://github.com/nodejs/node/issues/42742 --- deps/v8/src/logging/counters.h | 2 +- lib/internal/histogram.js | 25 +++++++++++++++++ lib/internal/perf/timerify.js | 27 ++++++++++++------- test/parallel/test-performance-function.js | 6 +++-- .../test-performance-histogram-timerify.js | 22 +++++++++++++++ 5 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 test/parallel/test-performance-histogram-timerify.js diff --git a/deps/v8/src/logging/counters.h b/deps/v8/src/logging/counters.h index 2c74a8ecd88a52b..6a5b073edaaa427 100644 --- a/deps/v8/src/logging/counters.h +++ b/deps/v8/src/logging/counters.h @@ -64,7 +64,7 @@ class StatsTable { return lookup_function_(name); } - // Create a histogram by name. If the create is successful, + // Create a histogram by name. If the creation is successful, // returns a non-nullptr pointer for use with AddHistogramSample // function. min and max define the expected minimum and maximum // sample values. buckets is the maximum number of buckets diff --git a/lib/internal/histogram.js b/lib/internal/histogram.js index 4237e716dc07e4b..3cdd0e3e5bcdea2 100644 --- a/lib/internal/histogram.js +++ b/lib/internal/histogram.js @@ -53,6 +53,30 @@ function isHistogram(object) { return object?.[kHandle] !== undefined; } +function* infinite() { + let id = 0; + + while (true) { + yield id++; + } +} + +const idWeakMap = new WeakMap(); +const gen = infinite() + +function getHistogramID(object) { + if (object == null) { + return -1; + } + if (idWeakMap.has(object)) { + return idWeakMap.get(object); + } else { + const id = gen.next().value; + idWeakMap.set(object, id); + return id + } +} + class Histogram { constructor() { throw new ERR_ILLEGAL_CONSTRUCTOR(); @@ -377,6 +401,7 @@ module.exports = { internalHistogram, internalRecordableHistogram, isHistogram, + getHistogramID, kDestroy, kHandle, kMap, diff --git a/lib/internal/perf/timerify.js b/lib/internal/perf/timerify.js index dae0b06bf80c8a4..a3cb123f307bfb8 100644 --- a/lib/internal/perf/timerify.js +++ b/lib/internal/perf/timerify.js @@ -18,7 +18,8 @@ const { } = require('internal/validators'); const { - isHistogram + isHistogram, + getHistogramID } = require('internal/histogram'); const { @@ -71,7 +72,9 @@ function timerify(fn, options = {}) { histogram); } - if (fn[kTimerified]) return fn[kTimerified]; + const id = getHistogramID(histogram) + + if (fn[kTimerified]?.[id]) return fn[kTimerified][id]; const constructor = isConstructor(fn); @@ -112,13 +115,19 @@ function timerify(fn, options = {}) { } }); - ObjectDefineProperties(fn, { - [kTimerified]: { - configurable: false, - enumerable: false, - value: timerified, - } - }); + if (fn[kTimerified]) { + fn[kTimerified][id] = timerified + } else { + ObjectDefineProperties(fn, { + [kTimerified]: { + configurable: false, + enumerable: false, + value: { + [id]: timerified + }, + } + }); + } return timerified; } diff --git a/test/parallel/test-performance-function.js b/test/parallel/test-performance-function.js index ea928028208e47c..30b1705b5a51fe1 100644 --- a/test/parallel/test-performance-function.js +++ b/test/parallel/test-performance-function.js @@ -81,9 +81,11 @@ const { const n = performance.timerify(m); const o = performance.timerify(m); const p = performance.timerify(n); - assert.strictEqual(n, o); - assert.strictEqual(n, p); + assert.notStrictEqual(n, o); + assert.notStrictEqual(n, p); assert.strictEqual(n.length, m.length); + assert.strictEqual(o.length, m.length); + assert.strictEqual(p.length, m.length); assert.strictEqual(n.name, 'timerified m'); } diff --git a/test/parallel/test-performance-histogram-timerify.js b/test/parallel/test-performance-histogram-timerify.js new file mode 100644 index 000000000000000..66a546f799220f9 --- /dev/null +++ b/test/parallel/test-performance-histogram-timerify.js @@ -0,0 +1,22 @@ +'use strict'; + +require('../common'); + +const { + createHistogram, + performance: { + timerify + } +} = require('perf_hooks'); + +const assert = require('assert'); + +let h1 = createHistogram(); +let h2 = createHistogram(); + +const fn = () => {}; + +const f1 = timerify(fn, { histogram: h1 }); +const f2 = timerify(fn, { histogram: h2 }); + +assert.notEqual(f1, f2);