GeezerVison is showing github.com — lib: flag to conditionally modify proto on deprecate · nodejs/node@d555db2
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 |
|---|
@@ -169,7 +169,7 @@ function pendingDeprecate(fn, msg, code) { | 169 | 169 | // Mark that a method should not be used. | 170 | 170 | // Returns a modified function which warns once by default. | 171 | 171 | // If --no-deprecation is set, then it is a no-op. | 172 | | -function deprecate(fn, msg, code, useEmitSync) { | | 172 | +function deprecate(fn, msg, code, useEmitSync, modifyPrototype = true) { | 173 | 173 | // Lazy-load to avoid a circular dependency. | 174 | 174 | if (validateString === undefined) | 175 | 175 | ({ validateString } = require('internal/validators')); | @@ -192,19 +192,23 @@ function deprecate(fn, msg, code, useEmitSync) { | 192 | 192 | return ReflectApply(fn, this, args); | 193 | 193 | } | 194 | 194 |
| 195 | | - // The wrapper will keep the same prototype as fn to maintain prototype chain | 196 | | - ObjectSetPrototypeOf(deprecated, fn); | 197 | | - if (fn.prototype) { | 198 | | - // Setting this (rather than using Object.setPrototype, as above) ensures | 199 | | - // that calling the unwrapped constructor gives an instanceof the wrapped | 200 | | - // constructor. | 201 | | - deprecated.prototype = fn.prototype; | 202 | | - } | | 195 | + if (modifyPrototype) { | | 196 | + // The wrapper will keep the same prototype as fn to maintain prototype chain | | 197 | + // Modifying the prototype does alter the object chains, and as observed in | | 198 | + // most cases, it slows the code. | | 199 | + ObjectSetPrototypeOf(deprecated, fn); | | 200 | + if (fn.prototype) { | | 201 | + // Setting this (rather than using Object.setPrototype, as above) ensures | | 202 | + // that calling the unwrapped constructor gives an instanceof the wrapped | | 203 | + // constructor. | | 204 | + deprecated.prototype = fn.prototype; | | 205 | + } | 203 | 206 |
| 204 | | - ObjectDefineProperty(deprecated, 'length', { | 205 | | - __proto__: null, | 206 | | - ...ObjectGetOwnPropertyDescriptor(fn, 'length'), | 207 | | - }); | | 207 | + ObjectDefineProperty(deprecated, 'length', { | | 208 | + __proto__: null, | | 209 | + ...ObjectGetOwnPropertyDescriptor(fn, 'length'), | | 210 | + }); | | 211 | + } | 208 | 212 |
| 209 | 213 | return deprecated; | 210 | 214 | } | |
|