Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ee9e2a2

Browse files
aduh95mcollina
authored andcommittedApr 19, 2021
lib: revert primordials in a hot path
Evidence has shown that use of primordials have sometimes an impact of performance. This commit reverts the changes who are most likely to be responsible for performance regression in the HTTP response path. PR-URL: #38248 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 4e9212b commit ee9e2a2

20 files changed

+182
-222
lines changed
 

‎lib/_http_common.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@
2222
'use strict';
2323

2424
const {
25-
ArrayPrototypePushApply,
2625
MathMin,
2726
Symbol,
2827
RegExpPrototypeTest,
29-
TypedArrayPrototypeSlice,
3028
} = primordials;
3129
const { setImmediate } = require('timers');
3230

@@ -66,7 +64,7 @@ function parserOnHeaders(headers, url) {
6664
// Once we exceeded headers limit - stop collecting them
6765
if (this.maxHeaderPairs <= 0 ||
6866
this._headers.length < this.maxHeaderPairs) {
69-
ArrayPrototypePushApply(this._headers, headers);
67+
this._headers.push(...headers);
7068
}
7169
this._url += url;
7270
}
@@ -138,7 +136,7 @@ function parserOnBody(b, start, len) {
138136

139137
// Pretend this was the result of a stream._read call.
140138
if (len > 0 && !stream._dumped) {
141-
const slice = TypedArrayPrototypeSlice(b, start, start + len);
139+
const slice = b.slice(start, start + len);
142140
const ret = stream.push(slice);
143141
if (!ret)
144142
readStop(this.socket);

‎lib/_http_incoming.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
'use strict';
2323

2424
const {
25-
ArrayPrototypePush,
26-
FunctionPrototypeCall,
2725
ObjectDefineProperty,
2826
ObjectSetPrototypeOf,
2927
StringPrototypeCharCodeAt,
@@ -59,7 +57,7 @@ function IncomingMessage(socket) {
5957
};
6058
}
6159

62-
FunctionPrototypeCall(Readable, this, streamOptions);
60+
Readable.call(this, streamOptions);
6361

6462
this._readableState.readingMore = true;
6563

@@ -350,7 +348,7 @@ function _addHeaderLine(field, value, dest) {
350348
} else if (flag === 1) {
351349
// Array header -- only Set-Cookie at the moment
352350
if (dest['set-cookie'] !== undefined) {
353-
ArrayPrototypePush(dest['set-cookie'], value);
351+
dest['set-cookie'].push(value);
354352
} else {
355353
dest['set-cookie'] = [value];
356354
}

‎lib/_http_outgoing.js

+9-14
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,7 @@
2424
const {
2525
Array,
2626
ArrayIsArray,
27-
ArrayPrototypeForEach,
2827
ArrayPrototypeJoin,
29-
ArrayPrototypePush,
30-
ArrayPrototypeUnshift,
31-
FunctionPrototype,
32-
FunctionPrototypeBind,
33-
FunctionPrototypeCall,
3428
MathFloor,
3529
NumberPrototypeToString,
3630
ObjectCreate,
@@ -88,7 +82,7 @@ const { CRLF } = common;
8882

8983
const kCorked = Symbol('corked');
9084

91-
const nop = FunctionPrototype;
85+
const nop = () => {};
9286

9387
const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i;
9488
const RE_TE_CHUNKED = common.chunkExpression;
@@ -101,7 +95,7 @@ function isCookieField(s) {
10195
}
10296

10397
function OutgoingMessage() {
104-
FunctionPrototypeCall(Stream, this);
98+
Stream.call(this);
10599

106100
// Queue that holds all currently pending data, until the response will be
107101
// assigned to the socket (until it will its turn in the HTTP pipeline).
@@ -331,7 +325,7 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) {
331325
data = this._header + data;
332326
} else {
333327
const header = this._header;
334-
ArrayPrototypeUnshift(this.outputData, {
328+
this.outputData.unshift({
335329
data: header,
336330
encoding: 'latin1',
337331
callback: null
@@ -368,7 +362,7 @@ function _writeRaw(data, encoding, callback) {
368362
return conn.write(data, encoding, callback);
369363
}
370364
// Buffer, as long as we're not destroyed.
371-
ArrayPrototypePush(this.outputData, { data, encoding, callback });
365+
this.outputData.push({ data, encoding, callback });
372366
this.outputSize += data.length;
373367
this._onPendingData(data.length);
374368
return this.outputSize < HIGH_WATER_MARK;
@@ -397,9 +391,10 @@ function _storeHeader(firstLine, headers) {
397391
}
398392
} else if (ArrayIsArray(headers)) {
399393
if (headers.length && ArrayIsArray(headers[0])) {
400-
ArrayPrototypeForEach(headers, (entry) =>
401-
processHeader(this, state, entry[0], entry[1], true)
402-
);
394+
for (let i = 0; i < headers.length; i++) {
395+
const entry = headers[i];
396+
processHeader(this, state, entry[0], entry[1], true);
397+
}
403398
} else {
404399
if (headers.length % 2 !== 0) {
405400
throw new ERR_INVALID_ARG_VALUE('headers', headers);
@@ -877,7 +872,7 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
877872
if (typeof callback === 'function')
878873
this.once('finish', callback);
879874

880-
const finish = FunctionPrototypeBind(onFinish, undefined, this);
875+
const finish = onFinish.bind(undefined, this);
881876

882877
if (this._hasBody && this.chunkedEncoding) {
883878
this._send('0\r\n' + this._trailer + '\r\n', 'latin1', finish);

‎lib/_http_server.js

+41-47
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,12 @@
2323

2424
const {
2525
ArrayIsArray,
26-
ArrayPrototypeForEach,
27-
ArrayPrototypePush,
28-
ArrayPrototypeShift,
2926
Error,
30-
FunctionPrototype,
31-
FunctionPrototypeBind,
32-
FunctionPrototypeCall,
3327
ObjectKeys,
3428
ObjectSetPrototypeOf,
35-
ReflectApply,
3629
RegExpPrototypeTest,
3730
Symbol,
3831
SymbolFor,
39-
TypedArrayPrototypeSlice,
4032
} = primordials;
4133

4234
const net = require('net');
@@ -185,7 +177,7 @@ class HTTPServerAsyncResource {
185177
}
186178

187179
function ServerResponse(req) {
188-
FunctionPrototypeCall(OutgoingMessage, this);
180+
OutgoingMessage.call(this);
189181

190182
if (req.method === 'HEAD') this._hasBody = false;
191183

@@ -212,7 +204,7 @@ ObjectSetPrototypeOf(ServerResponse, OutgoingMessage);
212204
ServerResponse.prototype._finish = function _finish() {
213205
DTRACE_HTTP_SERVER_RESPONSE(this.socket);
214206
emitStatistics(this[kServerResponseStatistics]);
215-
FunctionPrototypeCall(OutgoingMessage.prototype._finish, this);
207+
OutgoingMessage.prototype._finish.call(this);
216208
};
217209

218210

@@ -386,7 +378,7 @@ function Server(options, requestListener) {
386378
validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');
387379
this.insecureHTTPParser = insecureHTTPParser;
388380

389-
FunctionPrototypeCall(net.Server, this, { allowHalfOpen: true });
381+
net.Server.call(this, { allowHalfOpen: true });
390382

391383
if (requestListener) {
392384
this.on('request', requestListener);
@@ -422,17 +414,19 @@ Server.prototype[EE.captureRejectionSymbol] = function(err, event, ...args) {
422414
const { 1: res } = args;
423415
if (!res.headersSent && !res.writableEnded) {
424416
// Don't leak headers.
425-
ArrayPrototypeForEach(res.getHeaderNames(),
426-
(name) => res.removeHeader(name));
417+
const names = res.getHeaderNames();
418+
for (let i = 0; i < names.length; i++) {
419+
res.removeHeader(names[i]);
420+
}
427421
res.statusCode = 500;
428422
res.end(STATUS_CODES[500]);
429423
} else {
430424
res.destroy();
431425
}
432426
break;
433427
default:
434-
ReflectApply(net.Server.prototype[SymbolFor('nodejs.rejection')],
435-
this, arguments);
428+
net.Server.prototype[SymbolFor('nodejs.rejection')]
429+
.apply(this, arguments);
436430
}
437431
};
438432

@@ -493,20 +487,20 @@ function connectionListenerInternal(server, socket) {
493487
outgoingData: 0,
494488
keepAliveTimeoutSet: false
495489
};
496-
state.onData = FunctionPrototypeBind(socketOnData, undefined,
497-
server, socket, parser, state);
498-
state.onEnd = FunctionPrototypeBind(socketOnEnd, undefined,
499-
server, socket, parser, state);
500-
state.onClose = FunctionPrototypeBind(socketOnClose, undefined,
501-
socket, state);
502-
state.onDrain = FunctionPrototypeBind(socketOnDrain, undefined,
503-
socket, state);
490+
state.onData = socketOnData.bind(undefined,
491+
server, socket, parser, state);
492+
state.onEnd = socketOnEnd.bind(undefined,
493+
server, socket, parser, state);
494+
state.onClose = socketOnClose.bind(undefined,
495+
socket, state);
496+
state.onDrain = socketOnDrain.bind(undefined,
497+
socket, state);
504498
socket.on('data', state.onData);
505499
socket.on('error', socketOnError);
506500
socket.on('end', state.onEnd);
507501
socket.on('close', state.onClose);
508502
socket.on('drain', state.onDrain);
509-
parser.onIncoming = FunctionPrototypeBind(parserOnIncoming, undefined,
503+
parser.onIncoming = parserOnIncoming.bind(undefined,
510504
server, socket, state);
511505

512506
// We are consuming socket, so it won't get any actual data
@@ -527,18 +521,18 @@ function connectionListenerInternal(server, socket) {
527521
parser.consume(socket._handle);
528522
}
529523
parser[kOnExecute] =
530-
FunctionPrototypeBind(onParserExecute, undefined,
531-
server, socket, parser, state);
524+
onParserExecute.bind(undefined,
525+
server, socket, parser, state);
532526

533527
parser[kOnTimeout] =
534-
FunctionPrototypeBind(onParserTimeout, undefined,
535-
server, socket);
528+
onParserTimeout.bind(undefined,
529+
server, socket);
536530

537531
// When receiving new requests on the same socket (pipelining or keep alive)
538532
// make sure the requestTimeout is active.
539533
parser[kOnMessageBegin] =
540-
FunctionPrototypeBind(setRequestTimeout, undefined,
541-
server, socket);
534+
setRequestTimeout.bind(undefined,
535+
server, socket);
542536

543537
// This protects from DOS attack where an attacker establish the connection
544538
// without sending any data on applications where server.timeout is left to
@@ -594,7 +588,7 @@ function socketOnClose(socket, state) {
594588

595589
function abortIncoming(incoming) {
596590
while (incoming.length) {
597-
const req = ArrayPrototypeShift(incoming);
591+
const req = incoming.shift();
598592
req.destroy(connResetException('aborted'));
599593
}
600594
// Abort socket._httpMessage ?
@@ -606,7 +600,7 @@ function socketOnEnd(server, socket, parser, state) {
606600
if (ret instanceof Error) {
607601
debug('parse error');
608602
// socketOnError has additional logic and will call socket.destroy(err).
609-
FunctionPrototypeCall(socketOnError, socket, ret);
603+
socketOnError.call(socket, ret);
610604
} else if (!server.httpAllowHalfOpen) {
611605
socket.end();
612606
} else if (state.outgoing.length) {
@@ -629,7 +623,7 @@ function socketOnData(server, socket, parser, state, d) {
629623
function onRequestTimeout(socket) {
630624
socket[kRequestTimeout] = undefined;
631625
// socketOnError has additional logic and will call socket.destroy(err).
632-
ReflectApply(socketOnError, socket, [new ERR_HTTP_REQUEST_TIMEOUT()]);
626+
socketOnError.call(socket, new ERR_HTTP_REQUEST_TIMEOUT());
633627
}
634628

635629
function onParserExecute(server, socket, parser, state, ret) {
@@ -649,7 +643,7 @@ function onParserTimeout(server, socket) {
649643
socket.destroy();
650644
}
651645

652-
const noop = FunctionPrototype;
646+
const noop = () => {};
653647
const badRequestResponse = Buffer.from(
654648
`HTTP/1.1 400 ${STATUS_CODES[400]}${CRLF}` +
655649
`Connection: close${CRLF}${CRLF}`, 'ascii'
@@ -696,7 +690,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
696690
prepareError(ret, parser, d);
697691
ret.rawPacket = d || parser.getCurrentBuffer();
698692
debug('parse error', ret);
699-
FunctionPrototypeCall(socketOnError, socket, ret);
693+
socketOnError.call(socket, ret);
700694
} else if (parser.incoming && parser.incoming.upgrade) {
701695
// Upgrade or CONNECT
702696
const req = parser.incoming;
@@ -719,7 +713,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
719713
const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
720714
if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) {
721715
debug('SERVER have listener for %s', eventName);
722-
const bodyHead = TypedArrayPrototypeSlice(d, ret, d.length);
716+
const bodyHead = d.slice(ret, d.length);
723717

724718
socket.readableFlowing = null;
725719

@@ -738,7 +732,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
738732
// When receiving new requests on the same socket (pipelining or keep alive)
739733
// make sure the requestTimeout is active.
740734
parser[kOnMessageBegin] =
741-
FunctionPrototypeBind(setRequestTimeout, undefined, server, socket);
735+
setRequestTimeout.bind(undefined, server, socket);
742736
}
743737

744738
if (socket._paused && socket.parser) {
@@ -802,7 +796,7 @@ function resOnFinish(req, res, socket, state, server) {
802796
// array will be empty.
803797
assert(state.incoming.length === 0 || state.incoming[0] === req);
804798

805-
ArrayPrototypeShift(state.incoming);
799+
state.incoming.shift();
806800

807801
// If the user never called req.read(), and didn't pipe() or
808802
// .resume() or .on('data'), then we call req._dump() so that the
@@ -835,7 +829,7 @@ function resOnFinish(req, res, socket, state, server) {
835829
}
836830
} else {
837831
// Start sending the next message
838-
const m = ArrayPrototypeShift(state.outgoing);
832+
const m = state.outgoing.shift();
839833
if (m) {
840834
m.assignSocket(socket);
841835
}
@@ -861,7 +855,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
861855
return 2;
862856
}
863857

864-
ArrayPrototypePush(state.incoming, req);
858+
state.incoming.push(req);
865859

866860
// If the writable end isn't consuming, then stop reading
867861
// so that we don't become overwhelmed by a flood of
@@ -879,8 +873,8 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
879873

880874
const res = new server[kServerResponse](req);
881875
res._keepAliveTimeout = server.keepAliveTimeout;
882-
res._onPendingData = FunctionPrototypeBind(updateOutgoingData, undefined,
883-
socket, state);
876+
res._onPendingData = updateOutgoingData.bind(undefined,
877+
socket, state);
884878

885879
res.shouldKeepAlive = keepAlive;
886880
DTRACE_HTTP_SERVER_REQUEST(req, socket);
@@ -896,16 +890,16 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
896890

897891
if (socket._httpMessage) {
898892
// There are already pending outgoing res, append.
899-
ArrayPrototypePush(state.outgoing, res);
893+
state.outgoing.push(res);
900894
} else {
901895
res.assignSocket(socket);
902896
}
903897

904898
// When we're finished writing the response, check if this is the last
905899
// response, if so destroy the socket.
906900
res.on('finish',
907-
FunctionPrototypeBind(resOnFinish, undefined,
908-
req, res, socket, state, server));
901+
resOnFinish.bind(undefined,
902+
req, res, socket, state, server));
909903

910904
if (req.headers.expect !== undefined &&
911905
(req.httpVersionMajor === 1 && req.httpVersionMinor === 1)) {
@@ -977,8 +971,8 @@ function unconsume(parser, socket) {
977971

978972
function generateSocketListenerWrapper(originalFnName) {
979973
return function socketListenerWrap(ev, fn) {
980-
const res = ReflectApply(net.Socket.prototype[originalFnName], this,
981-
[ev, fn]);
974+
const res = net.Socket.prototype[originalFnName].call(this,
975+
ev, fn);
982976
if (!this.parser) {
983977
this.on = net.Socket.prototype.on;
984978
this.addListener = net.Socket.prototype.addListener;

‎lib/events.js

+10-14
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,10 @@
2222
'use strict';
2323

2424
const {
25-
ArrayPrototypeForEach,
26-
ArrayPrototypePush,
2725
ArrayPrototypeSlice,
2826
Boolean,
2927
Error,
3028
ErrorCaptureStackTrace,
31-
FunctionPrototypeCall,
3229
MathMin,
3330
NumberIsNaN,
3431
ObjectCreate,
@@ -39,7 +36,6 @@ const {
3936
Promise,
4037
PromiseReject,
4138
PromiseResolve,
42-
ReflectApply,
4339
ReflectOwnKeys,
4440
String,
4541
Symbol,
@@ -76,7 +72,7 @@ const kMaxEventTargetListenersWarned =
7672
Symbol('events.maxEventTargetListenersWarned');
7773

7874
function EventEmitter(opts) {
79-
FunctionPrototypeCall(EventEmitter.init, this, opts);
75+
EventEmitter.init.call(this, opts);
8076
}
8177
module.exports = EventEmitter;
8278
module.exports.once = once;
@@ -165,8 +161,8 @@ EventEmitter.setMaxListeners =
165161
if (isEventTarget === undefined)
166162
isEventTarget = require('internal/event_target').isEventTarget;
167163

168-
// Performance for forEach is now comparable with regular for-loop
169-
ArrayPrototypeForEach(eventTargets, (target) => {
164+
for (let i = 0; i < eventTargets.length; i++) {
165+
const target = eventTargets[i];
170166
if (isEventTarget(target)) {
171167
target[kMaxEventTargetListeners] = n;
172168
target[kMaxEventTargetListenersWarned] = false;
@@ -178,7 +174,7 @@ EventEmitter.setMaxListeners =
178174
['EventEmitter', 'EventTarget'],
179175
target);
180176
}
181-
});
177+
}
182178
}
183179
};
184180

@@ -217,7 +213,7 @@ function addCatch(that, promise, type, args) {
217213
const then = promise.then;
218214

219215
if (typeof then === 'function') {
220-
FunctionPrototypeCall(then, promise, undefined, function(err) {
216+
then.call(promise, undefined, function(err) {
221217
// The callback is called with nextTick to avoid a follow-up
222218
// rejection from this promise.
223219
process.nextTick(emitUnhandledRejectionOrErr, that, err, type, args);
@@ -366,7 +362,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
366362
return false;
367363

368364
if (typeof handler === 'function') {
369-
const result = ReflectApply(handler, this, args);
365+
const result = handler.apply(this, args);
370366

371367
// We check if result is undefined first because that
372368
// is the most common case so we do not pay any perf
@@ -378,7 +374,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
378374
const len = handler.length;
379375
const listeners = arrayClone(handler);
380376
for (let i = 0; i < len; ++i) {
381-
const result = ReflectApply(listeners[i], this, args);
377+
const result = listeners[i].apply(this, args);
382378

383379
// We check if result is undefined first because that
384380
// is the most common case so we do not pay any perf
@@ -690,7 +686,7 @@ function getEventListeners(emitterOrTarget, type) {
690686
while (handler?.listener !== undefined) {
691687
const listener = handler.listener?.deref ?
692688
handler.listener.deref() : handler.listener;
693-
ArrayPrototypePush(listeners, listener);
689+
listeners.push(listener);
694690
handler = handler.next;
695691
}
696692
return listeners;
@@ -807,7 +803,7 @@ function on(emitter, event, options) {
807803

808804
// Wait until an event happens
809805
return new Promise(function(resolve, reject) {
810-
ArrayPrototypePush(unconsumedPromises, { resolve, reject });
806+
unconsumedPromises.push({ resolve, reject });
811807
});
812808
},
813809

@@ -871,7 +867,7 @@ function on(emitter, event, options) {
871867
if (promise) {
872868
promise.resolve(createIterResult(args, false));
873869
} else {
874-
ArrayPrototypePush(unconsumedEvents, args);
870+
unconsumedEvents.push(args);
875871
}
876872
}
877873

‎lib/internal/async_hooks.js

+8-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypePop,
54
ArrayPrototypeSlice,
6-
ArrayPrototypeUnshift,
75
ErrorCaptureStackTrace,
8-
FunctionPrototypeBind,
96
ObjectPrototypeHasOwnProperty,
107
ObjectDefineProperty,
118
Promise,
12-
ReflectApply,
139
Symbol,
1410
} = primordials;
1511

@@ -129,16 +125,16 @@ function callbackTrampoline(asyncId, resource, cb, ...args) {
129125

130126
let result;
131127
if (asyncId === 0 && typeof domain_cb === 'function') {
132-
ArrayPrototypeUnshift(args, cb);
133-
result = ReflectApply(domain_cb, this, args);
128+
args.unshift(cb);
129+
result = domain_cb.apply(this, args);
134130
} else {
135-
result = ReflectApply(cb, this, args);
131+
result = cb.apply(this, args);
136132
}
137133

138134
if (asyncId !== 0 && hasHooks(kAfter))
139135
emitAfterNative(asyncId);
140136

141-
ArrayPrototypePop(execution_async_resources);
137+
execution_async_resources.pop();
142138
return result;
143139
}
144140

@@ -256,7 +252,7 @@ function emitHook(symbol, asyncId) {
256252
}
257253

258254
function emitHookFactory(symbol, name) {
259-
const fn = FunctionPrototypeBind(emitHook, undefined, symbol);
255+
const fn = emitHook.bind(undefined, symbol);
260256

261257
// Set the name property of the function as it looks good in the stack trace.
262258
ObjectDefineProperty(fn, 'name', {
@@ -429,14 +425,14 @@ function clearDefaultTriggerAsyncId() {
429425

430426
function defaultTriggerAsyncIdScope(triggerAsyncId, block, ...args) {
431427
if (triggerAsyncId === undefined)
432-
return ReflectApply(block, null, args);
428+
return block.apply(null, args);
433429
// CHECK(NumberIsSafeInteger(triggerAsyncId))
434430
// CHECK(triggerAsyncId > 0)
435431
const oldDefaultTriggerAsyncId = async_id_fields[kDefaultTriggerAsyncId];
436432
async_id_fields[kDefaultTriggerAsyncId] = triggerAsyncId;
437433

438434
try {
439-
return ReflectApply(block, null, args);
435+
return block.apply(null, args);
440436
} finally {
441437
async_id_fields[kDefaultTriggerAsyncId] = oldDefaultTriggerAsyncId;
442438
}
@@ -533,7 +529,7 @@ function popAsyncContext(asyncId) {
533529
const offset = stackLength - 1;
534530
async_id_fields[kExecutionAsyncId] = async_wrap.async_ids_stack[2 * offset];
535531
async_id_fields[kTriggerAsyncId] = async_wrap.async_ids_stack[2 * offset + 1];
536-
ArrayPrototypePop(execution_async_resources);
532+
execution_async_resources.pop();
537533
async_hook_fields[kStackLength] = offset;
538534
return offset > 0;
539535
}

‎lib/internal/per_context/primordials.js

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
// so that Node.js's builtin modules do not need to later look these up from
77
// the global proxy, which can be mutated by users.
88

9+
// Use of primordials have sometimes a dramatic impact on performance, please
10+
// benchmark all changes made in performance-sensitive areas of the codebase.
11+
// See: https://github.com/nodejs/node/pull/38248
12+
913
const {
1014
defineProperty: ReflectDefineProperty,
1115
getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor,

‎lib/internal/streams/destroy.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const {
77
},
88
} = require('internal/errors');
99
const {
10-
FunctionPrototypeCall,
1110
Symbol,
1211
} = primordials;
1312

@@ -99,8 +98,7 @@ function _destroy(self, err, cb) {
9998
try {
10099
const then = result.then;
101100
if (typeof then === 'function') {
102-
FunctionPrototypeCall(
103-
then,
101+
then.call(
104102
result,
105103
function() {
106104
if (called)
@@ -318,8 +316,7 @@ function constructNT(stream) {
318316
try {
319317
const then = result.then;
320318
if (typeof then === 'function') {
321-
FunctionPrototypeCall(
322-
then,
319+
then.call(
323320
result,
324321
function() {
325322
// If the callback was invoked, do nothing further.

‎lib/internal/streams/end-of-stream.js

+11-16
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33

44
'use strict';
55

6-
const {
7-
FunctionPrototype,
8-
FunctionPrototypeCall,
9-
ReflectApply,
10-
} = primordials;
116
const {
127
AbortError,
138
codes,
@@ -55,7 +50,7 @@ function isWritableFinished(stream) {
5550
return wState.finished || (wState.ended && wState.length === 0);
5651
}
5752

58-
const nop = FunctionPrototype;
53+
const nop = () => {};
5954

6055
function isReadableEnded(stream) {
6156
if (stream.readableEnded) return true;
@@ -113,7 +108,7 @@ function eos(stream, options, callback) {
113108
if (stream.destroyed) willEmitClose = false;
114109

115110
if (willEmitClose && (!stream.readable || readable)) return;
116-
if (!readable || readableEnded) FunctionPrototypeCall(callback, stream);
111+
if (!readable || readableEnded) callback.call(stream);
117112
};
118113

119114
let readableEnded = stream.readableEnded ||
@@ -126,25 +121,25 @@ function eos(stream, options, callback) {
126121
if (stream.destroyed) willEmitClose = false;
127122

128123
if (willEmitClose && (!stream.writable || writable)) return;
129-
if (!writable || writableFinished) FunctionPrototypeCall(callback, stream);
124+
if (!writable || writableFinished) callback.call(stream);
130125
};
131126

132127
const onerror = (err) => {
133-
FunctionPrototypeCall(callback, stream, err);
128+
callback.call(stream, err);
134129
};
135130

136131
const onclose = () => {
137132
if (readable && !readableEnded) {
138133
if (!isReadableEnded(stream))
139-
return FunctionPrototypeCall(callback, stream,
140-
new ERR_STREAM_PREMATURE_CLOSE());
134+
return callback.call(stream,
135+
new ERR_STREAM_PREMATURE_CLOSE());
141136
}
142137
if (writable && !writableFinished) {
143138
if (!isWritableFinished(stream))
144-
return FunctionPrototypeCall(callback, stream,
145-
new ERR_STREAM_PREMATURE_CLOSE());
139+
return callback.call(stream,
140+
new ERR_STREAM_PREMATURE_CLOSE());
146141
}
147-
FunctionPrototypeCall(callback, stream);
142+
callback.call(stream);
148143
};
149144

150145
const onrequest = () => {
@@ -218,15 +213,15 @@ function eos(stream, options, callback) {
218213
// Keep it because cleanup removes it.
219214
const endCallback = callback;
220215
cleanup();
221-
FunctionPrototypeCall(endCallback, stream, new AbortError());
216+
endCallback.call(stream, new AbortError());
222217
};
223218
if (options.signal.aborted) {
224219
process.nextTick(abort);
225220
} else {
226221
const originalCallback = callback;
227222
callback = once((...args) => {
228223
options.signal.removeEventListener('abort', abort);
229-
ReflectApply(originalCallback, stream, args);
224+
originalCallback.apply(stream, args);
230225
});
231226
options.signal.addEventListener('abort', abort);
232227
}

‎lib/internal/streams/lazy_transform.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
'use strict';
55

66
const {
7-
FunctionPrototypeCall,
87
ObjectDefineProperties,
98
ObjectDefineProperty,
109
ObjectSetPrototypeOf,
@@ -26,7 +25,7 @@ ObjectSetPrototypeOf(LazyTransform, stream.Transform);
2625

2726
function makeGetter(name) {
2827
return function() {
29-
FunctionPrototypeCall(stream.Transform, this, this._options);
28+
stream.Transform.call(this, this._options);
3029
this._writableState.decodeStrings = false;
3130

3231
if (!this._options || !this._options.defaultEncoding) {

‎lib/internal/streams/legacy.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
const {
44
ArrayIsArray,
5-
ArrayPrototypeUnshift,
6-
FunctionPrototypeCall,
75
ObjectSetPrototypeOf,
86
} = primordials;
97

108
const EE = require('events');
119

1210
function Stream(opts) {
13-
FunctionPrototypeCall(EE, this, opts);
11+
EE.call(this, opts);
1412
}
1513
ObjectSetPrototypeOf(Stream.prototype, EE.prototype);
1614
ObjectSetPrototypeOf(Stream, EE);
@@ -108,7 +106,7 @@ function prependListener(emitter, event, fn) {
108106
if (!emitter._events || !emitter._events[event])
109107
emitter.on(event, fn);
110108
else if (ArrayIsArray(emitter._events[event]))
111-
ArrayPrototypeUnshift(emitter._events[event], fn);
109+
emitter._events[event].unshift(fn);
112110
else
113111
emitter._events[event] = [fn, emitter._events[event]];
114112
}

‎lib/internal/streams/passthrough.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
'use strict';
2727

2828
const {
29-
FunctionPrototypeCall,
3029
ObjectSetPrototypeOf,
3130
} = primordials;
3231

@@ -40,7 +39,7 @@ function PassThrough(options) {
4039
if (!(this instanceof PassThrough))
4140
return new PassThrough(options);
4241

43-
FunctionPrototypeCall(Transform, this, options);
42+
Transform.call(this, options);
4443
}
4544

4645
PassThrough.prototype._transform = function(chunk, encoding, cb) {

‎lib/internal/streams/pipeline.js

+13-18
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55

66
const {
77
ArrayIsArray,
8-
ArrayPrototypePop,
9-
ArrayPrototypePush,
10-
ArrayPrototypeShift,
11-
FunctionPrototypeCall,
12-
ReflectApply,
138
SymbolAsyncIterator,
149
} = primordials;
1510

@@ -84,7 +79,7 @@ function popCallback(streams) {
8479
// a single stream. Therefore optimize for the average case instead of
8580
// checking for length === 0 as well.
8681
validateCallback(streams[streams.length - 1]);
87-
return ArrayPrototypePop(streams);
82+
return streams.pop();
8883
}
8984

9085
function makeAsyncIterable(val) {
@@ -103,7 +98,7 @@ async function* fromReadable(val) {
10398
Readable = require('internal/streams/readable');
10499
}
105100

106-
yield* FunctionPrototypeCall(Readable.prototype[SymbolAsyncIterator], val);
101+
yield* Readable.prototype[SymbolAsyncIterator].call(val);
107102
}
108103

109104
async function pump(iterable, writable, finish) {
@@ -160,7 +155,7 @@ function pipeline(...streams) {
160155
}
161156

162157
while (destroys.length) {
163-
ArrayPrototypeShift(destroys)(error);
158+
destroys.shift()(error);
164159
}
165160

166161
if (final) {
@@ -176,7 +171,7 @@ function pipeline(...streams) {
176171

177172
if (isStream(stream)) {
178173
finishCount++;
179-
ArrayPrototypePush(destroys, destroyer(stream, reading, writing, finish));
174+
destroys.push(destroyer(stream, reading, writing, finish));
180175
}
181176

182177
if (i === 0) {
@@ -220,14 +215,14 @@ function pipeline(...streams) {
220215
// second use.
221216
const then = ret?.then;
222217
if (typeof then === 'function') {
223-
ReflectApply(then, ret, [
224-
(val) => {
225-
value = val;
226-
pt.end(val);
227-
}, (err) => {
228-
pt.destroy(err);
229-
},
230-
]);
218+
then.call(ret,
219+
(val) => {
220+
value = val;
221+
pt.end(val);
222+
}, (err) => {
223+
pt.destroy(err);
224+
},
225+
);
231226
} else if (isIterable(ret, true)) {
232227
finishCount++;
233228
pump(ret, pt, finish);
@@ -239,7 +234,7 @@ function pipeline(...streams) {
239234
ret = pt;
240235

241236
finishCount++;
242-
ArrayPrototypePush(destroys, destroyer(ret, false, true, finish));
237+
destroys.push(destroyer(ret, false, true, finish));
243238
}
244239
} else if (isStream(stream)) {
245240
if (isReadable(ret)) {

‎lib/internal/streams/readable.js

+19-24
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,14 @@
2222
'use strict';
2323

2424
const {
25-
ArrayPrototypeForEach,
2625
ArrayPrototypeIndexOf,
27-
ArrayPrototypePush,
28-
ArrayPrototypeSplice,
29-
FunctionPrototype,
30-
FunctionPrototypeBind,
31-
FunctionPrototypeCall,
3226
NumberIsInteger,
3327
NumberIsNaN,
3428
NumberParseInt,
3529
ObjectDefineProperties,
3630
ObjectKeys,
3731
ObjectSetPrototypeOf,
3832
Promise,
39-
ReflectApply,
4033
SafeSet,
4134
SymbolAsyncIterator,
4235
Symbol
@@ -78,7 +71,7 @@ let from;
7871

7972
ObjectSetPrototypeOf(Readable.prototype, Stream.prototype);
8073
ObjectSetPrototypeOf(Readable, Stream);
81-
const nop = FunctionPrototype;
74+
const nop = () => {};
8275

8376
const { errorOrDestroy } = destroyImpl;
8477

@@ -208,7 +201,7 @@ function Readable(options) {
208201
addAbortSignalNoValidate(options.signal, this);
209202
}
210203

211-
FunctionPrototypeCall(Stream, this, options);
204+
Stream.call(this, options);
212205

213206
destroyImpl.construct(this, () => {
214207
if (this._readableState.needReadable) {
@@ -668,7 +661,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
668661
}
669662
}
670663

671-
ArrayPrototypePush(state.pipes, dest);
664+
state.pipes.push(dest);
672665
debug('pipe count=%d opts=%j', state.pipes.length, pipeOpts);
673666

674667
const doEnd = (!pipeOpts || pipeOpts.end !== false) &&
@@ -855,8 +848,8 @@ Readable.prototype.unpipe = function(dest) {
855848
state.pipes = [];
856849
this.pause();
857850

858-
ArrayPrototypeForEach(dests, (dest) =>
859-
dest.emit('unpipe', this, { hasUnpiped: false }));
851+
for (let i = 0; i < dests.length; i++)
852+
dests[i].emit('unpipe', this, { hasUnpiped: false });
860853
return this;
861854
}
862855

@@ -865,7 +858,7 @@ Readable.prototype.unpipe = function(dest) {
865858
if (index === -1)
866859
return this;
867860

868-
ArrayPrototypeSplice(state.pipes, index, 1);
861+
state.pipes.splice(index, 1);
869862
if (state.pipes.length === 0)
870863
this.pause();
871864

@@ -877,7 +870,7 @@ Readable.prototype.unpipe = function(dest) {
877870
// Set up data events if they are asked for
878871
// Ensure readable listeners eventually get something.
879872
Readable.prototype.on = function(ev, fn) {
880-
const res = FunctionPrototypeCall(Stream.prototype.on, this, ev, fn);
873+
const res = Stream.prototype.on.call(this, ev, fn);
881874
const state = this._readableState;
882875

883876
if (ev === 'data') {
@@ -907,8 +900,8 @@ Readable.prototype.on = function(ev, fn) {
907900
Readable.prototype.addListener = Readable.prototype.on;
908901

909902
Readable.prototype.removeListener = function(ev, fn) {
910-
const res = FunctionPrototypeCall(Stream.prototype.removeListener, this,
911-
ev, fn);
903+
const res = Stream.prototype.removeListener.call(this,
904+
ev, fn);
912905

913906
if (ev === 'readable') {
914907
// We need to check if there is someone still listening to
@@ -925,8 +918,8 @@ Readable.prototype.removeListener = function(ev, fn) {
925918
Readable.prototype.off = Readable.prototype.removeListener;
926919

927920
Readable.prototype.removeAllListeners = function(ev) {
928-
const res = ReflectApply(Stream.prototype.removeAllListeners, this,
929-
arguments);
921+
const res = Stream.prototype.removeAllListeners.apply(this,
922+
arguments);
930923

931924
if (ev === 'readable' || ev === undefined) {
932925
// We need to check if there is someone still listening to
@@ -1057,11 +1050,13 @@ Readable.prototype.wrap = function(stream) {
10571050
};
10581051

10591052
// Proxy all the other methods. Important when wrapping filters and duplexes.
1060-
ArrayPrototypeForEach(ObjectKeys(stream), (i) => {
1053+
const streamKeys = ObjectKeys(stream);
1054+
for (let j = 1; j < streamKeys.length; j++) {
1055+
const i = streamKeys[j];
10611056
if (this[i] === undefined && typeof stream[i] === 'function') {
1062-
this[i] = FunctionPrototypeBind(stream[i], stream);
1057+
this[i] = stream[i].bind(stream);
10631058
}
1064-
});
1059+
}
10651060

10661061
return this;
10671062
};
@@ -1110,15 +1105,15 @@ async function* createAsyncIterator(stream) {
11101105
.on('error', function(err) {
11111106
error = err;
11121107
errorEmitted = true;
1113-
FunctionPrototypeCall(next, this);
1108+
next.call(this);
11141109
})
11151110
.on('end', function() {
11161111
endEmitted = true;
1117-
FunctionPrototypeCall(next, this);
1112+
next.call(this);
11181113
})
11191114
.on('close', function() {
11201115
closeEmitted = true;
1121-
FunctionPrototypeCall(next, this);
1116+
next.call(this);
11221117
});
11231118

11241119
try {

‎lib/internal/streams/transform.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
'use strict';
6565

6666
const {
67-
FunctionPrototypeCall,
6867
ObjectSetPrototypeOf,
6968
Symbol
7069
} = primordials;
@@ -133,8 +132,7 @@ function final(cb) {
133132
try {
134133
const then = result.then;
135134
if (typeof then === 'function') {
136-
FunctionPrototypeCall(
137-
then,
135+
then.call(
138136
result,
139137
(data) => {
140138
if (called)
@@ -167,7 +165,7 @@ function final(cb) {
167165

168166
function prefinish() {
169167
if (this._final !== final) {
170-
FunctionPrototypeCall(final, this);
168+
final.call(this);
171169
}
172170
}
173171

@@ -209,8 +207,7 @@ Transform.prototype._write = function(chunk, encoding, callback) {
209207
try {
210208
const then = result.then;
211209
if (typeof then === 'function') {
212-
FunctionPrototypeCall(
213-
then,
210+
then.call(
214211
result,
215212
(val) => {
216213
if (called)

‎lib/internal/streams/writable.js

+19-20
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,8 @@
2626
'use strict';
2727

2828
const {
29-
ArrayPrototypeForEach,
30-
ArrayPrototypePush,
3129
ArrayPrototypeSlice,
32-
ArrayPrototypeSplice,
3330
Error,
34-
FunctionPrototypeCall,
3531
FunctionPrototypeSymbolHasInstance,
3632
ObjectDefineProperty,
3733
ObjectDefineProperties,
@@ -257,7 +253,7 @@ function Writable(options) {
257253
addAbortSignalNoValidate(options.signal, this);
258254
}
259255

260-
FunctionPrototypeCall(Stream, this, options);
256+
Stream.call(this, options);
261257

262258
destroyImpl.construct(this, () => {
263259
const state = this._writableState;
@@ -521,10 +517,10 @@ function errorBuffer(state) {
521517
callback(new ERR_STREAM_DESTROYED('write'));
522518
}
523519

524-
ArrayPrototypeForEach(
525-
ArrayPrototypeSplice(state[kOnFinished], 0),
526-
(callback) => callback(new ERR_STREAM_DESTROYED('end'))
527-
);
520+
const onfinishCallbacks = state[kOnFinished].splice(0);
521+
for (let i = 0; i < onfinishCallbacks.length; i++) {
522+
onfinishCallbacks[i](new ERR_STREAM_DESTROYED('end'));
523+
}
528524

529525
resetBuffer(state);
530526
}
@@ -576,7 +572,7 @@ function clearBuffer(stream, state) {
576572
if (i === buffered.length) {
577573
resetBuffer(state);
578574
} else if (i > 256) {
579-
ArrayPrototypeSplice(buffered, 0, i);
575+
buffered.splice(0, i);
580576
state.bufferedIndex = 0;
581577
} else {
582578
state.bufferedIndex = i;
@@ -644,7 +640,7 @@ Writable.prototype.end = function(chunk, encoding, cb) {
644640
if (err || state.finished) {
645641
process.nextTick(cb, err);
646642
} else {
647-
ArrayPrototypePush(state[kOnFinished], cb);
643+
state[kOnFinished].push(cb);
648644
}
649645
}
650646

@@ -667,8 +663,9 @@ function callFinal(stream, state) {
667663
const result = stream._final((err) => {
668664
state.pendingcb--;
669665
if (err) {
670-
for (const callback of ArrayPrototypeSplice(state[kOnFinished], 0)) {
671-
callback(err);
666+
const onfinishCallbacks = state[kOnFinished].splice(0);
667+
for (let i = 0; i < onfinishCallbacks.length; i++) {
668+
onfinishCallbacks[i](err);
672669
}
673670
errorOrDestroy(stream, err, state.sync);
674671
} else if (needFinish(state)) {
@@ -685,8 +682,7 @@ function callFinal(stream, state) {
685682
try {
686683
const then = result.then;
687684
if (typeof then === 'function') {
688-
FunctionPrototypeCall(
689-
then,
685+
then.call(
690686
result,
691687
function() {
692688
if (state.prefinished)
@@ -697,8 +693,9 @@ function callFinal(stream, state) {
697693
process.nextTick(finish, stream, state);
698694
},
699695
function(err) {
700-
for (const cb of ArrayPrototypeSplice(state[kOnFinished], 0)) {
701-
process.nextTick(cb, err);
696+
const onfinishCallbacks = state[kOnFinished].splice(0);
697+
for (let i = 0; i < onfinishCallbacks.length; i++) {
698+
process.nextTick(onfinishCallbacks[i], err);
702699
}
703700
process.nextTick(errorOrDestroy, stream, err, state.sync);
704701
});
@@ -744,8 +741,10 @@ function finish(stream, state) {
744741

745742
state.finished = true;
746743

747-
ArrayPrototypeForEach(ArrayPrototypeSplice(state[kOnFinished], 0),
748-
(callback) => callback());
744+
const onfinishCallbacks = state[kOnFinished].splice(0);
745+
for (let i = 0; i < onfinishCallbacks.length; i++) {
746+
onfinishCallbacks[i]();
747+
}
749748

750749
stream.emit('finish');
751750

@@ -859,7 +858,7 @@ Writable.prototype.destroy = function(err, cb) {
859858
process.nextTick(errorBuffer, state);
860859
}
861860

862-
FunctionPrototypeCall(destroy, this, err, cb);
861+
destroy.call(this, err, cb);
863862
return this;
864863
};
865864

‎lib/internal/timers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ const {
7878
NumberIsFinite,
7979
NumberMIN_SAFE_INTEGER,
8080
ObjectCreate,
81-
Symbol,
8281
ReflectApply,
82+
Symbol,
8383
} = primordials;
8484

8585
const {

‎lib/internal/util.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
const {
44
ArrayFrom,
55
ArrayIsArray,
6-
ArrayPrototypePop,
76
ArrayPrototypePush,
87
ArrayPrototypeSlice,
98
ArrayPrototypeSort,
@@ -148,13 +147,13 @@ function slowCases(enc) {
148147
case 4:
149148
if (enc === 'UTF8') return 'utf8';
150149
if (enc === 'ucs2' || enc === 'UCS2') return 'utf16le';
151-
enc = StringPrototypeToLowerCase(`${enc}`);
150+
enc = `${enc}`.toLowerCase();
152151
if (enc === 'utf8') return 'utf8';
153152
if (enc === 'ucs2') return 'utf16le';
154153
break;
155154
case 3:
156155
if (enc === 'hex' || enc === 'HEX' ||
157-
StringPrototypeToLowerCase(`${enc}`) === 'hex')
156+
`${enc}`.toLowerCase() === 'hex')
158157
return 'hex';
159158
break;
160159
case 5:
@@ -163,7 +162,7 @@ function slowCases(enc) {
163162
if (enc === 'UTF-8') return 'utf8';
164163
if (enc === 'ASCII') return 'ascii';
165164
if (enc === 'UCS-2') return 'utf16le';
166-
enc = StringPrototypeToLowerCase(`${enc}`);
165+
enc = `${enc}`.toLowerCase();
167166
if (enc === 'utf-8') return 'utf8';
168167
if (enc === 'ascii') return 'ascii';
169168
if (enc === 'ucs-2') return 'utf16le';
@@ -173,23 +172,23 @@ function slowCases(enc) {
173172
if (enc === 'latin1' || enc === 'binary') return 'latin1';
174173
if (enc === 'BASE64') return 'base64';
175174
if (enc === 'LATIN1' || enc === 'BINARY') return 'latin1';
176-
enc = StringPrototypeToLowerCase(`${enc}`);
175+
enc = `${enc}`.toLowerCase();
177176
if (enc === 'base64') return 'base64';
178177
if (enc === 'latin1' || enc === 'binary') return 'latin1';
179178
break;
180179
case 7:
181180
if (enc === 'utf16le' || enc === 'UTF16LE' ||
182-
StringPrototypeToLowerCase(`${enc}`) === 'utf16le')
181+
`${enc}`.toLowerCase() === 'utf16le')
183182
return 'utf16le';
184183
break;
185184
case 8:
186185
if (enc === 'utf-16le' || enc === 'UTF-16LE' ||
187-
StringPrototypeToLowerCase(`${enc}`) === 'utf-16le')
186+
`${enc}`.toLowerCase() === 'utf-16le')
188187
return 'utf16le';
189188
break;
190189
case 9:
191190
if (enc === 'base64url' || enc === 'BASE64URL' ||
192-
StringPrototypeToLowerCase(`${enc}`) === 'base64url')
191+
`${enc}`.toLowerCase() === 'base64url')
193192
return 'base64url';
194193
break;
195194
default:
@@ -370,7 +369,7 @@ function join(output, separator) {
370369
function spliceOne(list, index) {
371370
for (; index + 1 < list.length; index++)
372371
list[index] = list[index + 1];
373-
ArrayPrototypePop(list);
372+
list.pop();
374373
}
375374

376375
const kNodeModulesRE = /^(.*)[\\/]node_modules[\\/]/;

‎lib/internal/util/debuglog.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const {
4-
FunctionPrototype,
54
FunctionPrototypeBind,
65
ObjectCreate,
76
ObjectDefineProperty,
@@ -45,7 +44,7 @@ function emitWarningIfNeeded(set) {
4544
}
4645
}
4746

48-
const noop = FunctionPrototype;
47+
const noop = () => {};
4948

5049
function debuglogImpl(enabled, set) {
5150
if (debugImpls[set] === undefined) {
@@ -81,15 +80,27 @@ function debuglog(set, cb) {
8180
debug = debuglogImpl(enabled, set);
8281
if (typeof cb === 'function')
8382
cb(debug);
84-
debug(...new SafeArrayIterator(args));
83+
switch (args.length) {
84+
case 0: return debug();
85+
case 1: return debug(args[0]);
86+
case 2: return debug(args[0], args[1]);
87+
default: return debug(...new SafeArrayIterator(args));
88+
}
8589
};
8690
let enabled;
8791
let test = () => {
8892
init();
8993
test = () => enabled;
9094
return enabled;
9195
};
92-
const logger = (...args) => debug(...new SafeArrayIterator(args));
96+
const logger = (...args) => {
97+
switch (args.length) {
98+
case 0: return debug();
99+
case 1: return debug(args[0]);
100+
case 2: return debug(args[0], args[1]);
101+
default: return debug(...new SafeArrayIterator(args));
102+
}
103+
};
93104
ObjectDefineProperty(logger, 'enabled', {
94105
get() {
95106
return test();

‎lib/net.js

+11-16
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,13 @@
2424
const {
2525
ArrayIsArray,
2626
ArrayPrototypeIndexOf,
27-
ArrayPrototypePush,
28-
ArrayPrototypeSplice,
2927
Boolean,
3028
Error,
31-
FunctionPrototype,
32-
FunctionPrototypeCall,
3329
Number,
3430
NumberIsNaN,
3531
NumberParseInt,
3632
ObjectDefineProperty,
3733
ObjectSetPrototypeOf,
38-
ReflectApply,
3934
Symbol,
4035
} = primordials;
4136

@@ -132,7 +127,7 @@ const DEFAULT_IPV6_ADDR = '::';
132127

133128
const isWindows = process.platform === 'win32';
134129

135-
const noop = FunctionPrototype;
130+
const noop = () => {};
136131

137132
function getFlags(ipv6Only) {
138133
return ipv6Only === true ? TCPConstants.UV_TCP_IPV6ONLY : 0;
@@ -305,7 +300,7 @@ function Socket(options) {
305300
options.autoDestroy = true;
306301
// Handle strings directly.
307302
options.decodeStrings = false;
308-
ReflectApply(stream.Duplex, this, [options]);
303+
stream.Duplex.call(this, options);
309304

310305
if (options.handle) {
311306
this._handle = options.handle; // private
@@ -441,8 +436,7 @@ function afterShutdown() {
441436
// is overly vague, and makes it seem like the user's code is to blame.
442437
function writeAfterFIN(chunk, encoding, cb) {
443438
if (!this.writableEnded) {
444-
return ReflectApply(
445-
stream.Duplex.prototype.write, this, [chunk, encoding, cb]);
439+
return stream.Duplex.prototype.write.call(this, chunk, encoding, cb);
446440
}
447441

448442
if (typeof encoding === 'function') {
@@ -586,7 +580,8 @@ Socket.prototype._read = function(n) {
586580

587581

588582
Socket.prototype.end = function(data, encoding, callback) {
589-
ReflectApply(stream.Duplex.prototype.end, this, [data, encoding, callback]);
583+
stream.Duplex.prototype.end.call(this,
584+
data, encoding, callback);
590585
DTRACE_NET_STREAM_END(this);
591586
return this;
592587
};
@@ -602,7 +597,7 @@ Socket.prototype.pause = function() {
602597
this.destroy(errnoException(err, 'read'));
603598
}
604599
}
605-
return FunctionPrototypeCall(stream.Duplex.prototype.pause, this);
600+
return stream.Duplex.prototype.pause.call(this);
606601
};
607602

608603

@@ -611,7 +606,7 @@ Socket.prototype.resume = function() {
611606
!this._handle.reading) {
612607
tryReadStart(this);
613608
}
614-
return FunctionPrototypeCall(stream.Duplex.prototype.resume, this);
609+
return stream.Duplex.prototype.resume.call(this);
615610
};
616611

617612

@@ -620,7 +615,7 @@ Socket.prototype.read = function(n) {
620615
!this._handle.reading) {
621616
tryReadStart(this);
622617
}
623-
return ReflectApply(stream.Duplex.prototype.read, this, [n]);
618+
return stream.Duplex.prototype.read.call(this, n);
624619
};
625620

626621

@@ -1169,7 +1164,7 @@ function Server(options, connectionListener) {
11691164
if (!(this instanceof Server))
11701165
return new Server(options, connectionListener);
11711166

1172-
FunctionPrototypeCall(EventEmitter, this);
1167+
EventEmitter.call(this);
11731168

11741169
if (typeof options === 'function') {
11751170
connectionListener = options;
@@ -1681,10 +1676,10 @@ ObjectDefineProperty(Socket.prototype, '_handle', {
16811676

16821677
Server.prototype._setupWorker = function(socketList) {
16831678
this._usingWorkers = true;
1684-
ArrayPrototypePush(this._workers, socketList);
1679+
this._workers.push(socketList);
16851680
socketList.once('exit', (socketList) => {
16861681
const index = ArrayPrototypeIndexOf(this._workers, socketList);
1687-
ArrayPrototypeSplice(this._workers, index, 1);
1682+
this._workers.splice(index, 1);
16881683
});
16891684
};
16901685

0 commit comments

Comments
 (0)
Please sign in to comment.