GeezerVison is showing github.com — lib: flag to conditionally modify proto on deprecate · nodejs/node@2fc25fd
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +36Lines changed: 36 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common'); | | 4 | +const assert = require('assert'); | | 5 | + | | 6 | +const bench = common.createBenchmark(main, { | | 7 | + n: [1e5], | | 8 | + modifyPrototype: [1, 0], | | 9 | + emitWarningSync: [1, 0], | | 10 | +}, { | | 11 | + flags: ['--expose-internals'], | | 12 | +}); | | 13 | + | | 14 | +function simpleFunction(x) { | | 15 | + return x * 2 + (new Array(1000)).fill(0).map((_, i) => i).reduce((a, b) => a + b, 0); | | 16 | +} | | 17 | + | | 18 | +function main({ n, modifyPrototype, emitWarningSync }) { | | 19 | + const { deprecate } = require('internal/util'); | | 20 | + | | 21 | + const fn = deprecate( | | 22 | + simpleFunction, | | 23 | + 'This function is deprecated', | | 24 | + 'DEP0000', | | 25 | + emitWarningSync, | | 26 | + !!modifyPrototype, | | 27 | + ); | | 28 | + | | 29 | + let sum = 0; | | 30 | + bench.start(); | | 31 | + for (let i = 0; i < n; ++i) { | | 32 | + sum += fn(i); | | 33 | + } | | 34 | + bench.end(n); | | 35 | + assert.ok(sum); | | 36 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/util.js +17-13Lines changed: 17 additions & 13 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -158,7 +158,7 @@ function pendingDeprecate(fn, msg, code) { | 158 | 158 | // Mark that a method should not be used. | 159 | 159 | // Returns a modified function which warns once by default. | 160 | 160 | // If --no-deprecation is set, then it is a no-op. | 161 | | -function deprecate(fn, msg, code, useEmitSync) { | | 161 | +function deprecate(fn, msg, code, useEmitSync, modifyPrototype = true) { | 162 | 162 | // Lazy-load to avoid a circular dependency. | 163 | 163 | if (validateString === undefined) | 164 | 164 | ({ validateString } = require('internal/validators')); | @@ -181,19 +181,23 @@ function deprecate(fn, msg, code, useEmitSync) { | 181 | 181 | return ReflectApply(fn, this, args); | 182 | 182 | } | 183 | 183 |
| 184 | | - // The wrapper will keep the same prototype as fn to maintain prototype chain | 185 | | - ObjectSetPrototypeOf(deprecated, fn); | 186 | | - if (fn.prototype) { | 187 | | - // Setting this (rather than using Object.setPrototype, as above) ensures | 188 | | - // that calling the unwrapped constructor gives an instanceof the wrapped | 189 | | - // constructor. | 190 | | - deprecated.prototype = fn.prototype; | 191 | | - } | | 184 | + if (modifyPrototype) { | | 185 | + // The wrapper will keep the same prototype as fn to maintain prototype chain | | 186 | + // Modifying the prototype does alter the object chains, and as observed in | | 187 | + // most cases, it slows the code. | | 188 | + ObjectSetPrototypeOf(deprecated, fn); | | 189 | + if (fn.prototype) { | | 190 | + // Setting this (rather than using Object.setPrototype, as above) ensures | | 191 | + // that calling the unwrapped constructor gives an instanceof the wrapped | | 192 | + // constructor. | | 193 | + deprecated.prototype = fn.prototype; | | 194 | + } | 192 | 195 |
| 193 | | - ObjectDefineProperty(deprecated, 'length', { | 194 | | - __proto__: null, | 195 | | - ...ObjectGetOwnPropertyDescriptor(fn, 'length'), | 196 | | - }); | | 196 | + ObjectDefineProperty(deprecated, 'length', { | | 197 | + __proto__: null, | | 198 | + ...ObjectGetOwnPropertyDescriptor(fn, 'length'), | | 199 | + }); | | 200 | + } | 197 | 201 |
| 198 | 202 | return deprecated; | 199 | 203 | } | |
|