Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 48ed81f

Browse filesBrowse files
addaleaxtargos
authored andcommitted
src: improve StreamBase read throughput
Improve performance by providing JS with the raw ingridients for the read data, i.e. an `ArrayBuffer` + offset + length fields, instead of creating `Buffer` instances in C++ land. PR-URL: #23797 Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 1cda41b commit 48ed81f
Copy full SHA for 48ed81f

File tree

Expand file treeCollapse file tree

16 files changed

+115
-44
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

16 files changed

+115
-44
lines changed
Open diff view settings
Collapse file

‎benchmark/net/tcp-raw-c2s.js‎

Copy file name to clipboardExpand all lines: benchmark/net/tcp-raw-c2s.js
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ function main({ dur, len, type }) {
4646
process.exit(0);
4747
}, dur * 1000);
4848

49-
clientHandle.onread = function(nread, buffer) {
49+
clientHandle.onread = function(buffer) {
5050
// we're not expecting to ever get an EOF from the client.
5151
// just lots of data forever.
52-
if (nread < 0)
53-
fail(nread, 'read');
52+
if (!buffer)
53+
fail('read');
5454

5555
// don't slice the buffer. the point of this is to isolate, not
5656
// simulate real traffic.
57-
bytes += buffer.length;
57+
bytes += buffer.byteLength;
5858
};
5959

6060
clientHandle.readStart();
Collapse file

‎benchmark/net/tcp-raw-pipe.js‎

Copy file name to clipboardExpand all lines: benchmark/net/tcp-raw-pipe.js
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ function main({ dur, len, type }) {
4343
if (err)
4444
fail(err, 'connect');
4545

46-
clientHandle.onread = function(nread, buffer) {
46+
clientHandle.onread = function(buffer) {
4747
// we're not expecting to ever get an EOF from the client.
4848
// just lots of data forever.
49-
if (nread < 0)
50-
fail(nread, 'read');
49+
if (!buffer)
50+
fail('read');
5151

5252
const writeReq = new WriteWrap();
5353
writeReq.async = false;
54-
err = clientHandle.writeBuffer(writeReq, buffer);
54+
err = clientHandle.writeBuffer(writeReq, Buffer.from(buffer));
5555

5656
if (err)
5757
fail(err, 'write');
@@ -89,11 +89,11 @@ function main({ dur, len, type }) {
8989
if (err)
9090
fail(err, 'connect');
9191

92-
clientHandle.onread = function(nread, buffer) {
93-
if (nread < 0)
94-
fail(nread, 'read');
92+
clientHandle.onread = function(buffer) {
93+
if (!buffer)
94+
fail('read');
9595

96-
bytes += buffer.length;
96+
bytes += buffer.byteLength;
9797
};
9898

9999
connectReq.oncomplete = function(err) {
Collapse file

‎benchmark/net/tcp-raw-s2c.js‎

Copy file name to clipboardExpand all lines: benchmark/net/tcp-raw-s2c.js
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ function main({ dur, len, type }) {
109109

110110
connectReq.oncomplete = function() {
111111
var bytes = 0;
112-
clientHandle.onread = function(nread, buffer) {
112+
clientHandle.onread = function(buffer) {
113113
// we're not expecting to ever get an EOF from the client.
114114
// just lots of data forever.
115-
if (nread < 0)
116-
fail(nread, 'read');
115+
if (!buffer)
116+
fail('read');
117117

118118
// don't slice the buffer. the point of this is to isolate, not
119119
// simulate real traffic.
120-
bytes += buffer.length;
120+
bytes += buffer.byteLength;
121121
};
122122

123123
clientHandle.readStart();
Collapse file

‎lib/internal/child_process.js‎

Copy file name to clipboardExpand all lines: lib/internal/child_process.js
+11-4Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ const util = require('util');
2222
const assert = require('assert');
2323

2424
const { Process } = internalBinding('process_wrap');
25-
const { WriteWrap } = internalBinding('stream_wrap');
25+
const {
26+
WriteWrap,
27+
kReadBytesOrError,
28+
kArrayBufferOffset,
29+
streamBaseState
30+
} = internalBinding('stream_wrap');
2631
const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap');
2732
const { TCP } = internalBinding('tcp_wrap');
2833
const { TTY } = internalBinding('tty_wrap');
@@ -486,11 +491,13 @@ function setupChannel(target, channel) {
486491
var pendingHandle = null;
487492
channel.buffering = false;
488493
channel.pendingHandle = null;
489-
channel.onread = function(nread, pool) {
494+
channel.onread = function(arrayBuffer) {
490495
const recvHandle = channel.pendingHandle;
491496
channel.pendingHandle = null;
492-
// TODO(bnoordhuis) Check that nread > 0.
493-
if (pool) {
497+
if (arrayBuffer) {
498+
const nread = streamBaseState[kReadBytesOrError];
499+
const offset = streamBaseState[kArrayBufferOffset];
500+
const pool = new Uint8Array(arrayBuffer, offset, nread);
494501
if (recvHandle)
495502
pendingHandle = recvHandle;
496503

Collapse file

‎lib/internal/http2/core.js‎

Copy file name to clipboardExpand all lines: lib/internal/http2/core.js
+7-2Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,11 @@ const { isArrayBufferView } = require('internal/util/types');
120120

121121
const { FileHandle } = process.binding('fs');
122122
const binding = internalBinding('http2');
123-
const { ShutdownWrap } = internalBinding('stream_wrap');
123+
const {
124+
ShutdownWrap,
125+
kReadBytesOrError,
126+
streamBaseState
127+
} = internalBinding('stream_wrap');
124128
const { UV_EOF } = internalBinding('uv');
125129

126130
const { StreamPipe } = internalBinding('stream_pipe');
@@ -2043,7 +2047,8 @@ function onFileUnpipe() {
20432047

20442048
// This is only called once the pipe has returned back control, so
20452049
// it only has to handle errors and End-of-File.
2046-
function onPipedFileHandleRead(err) {
2050+
function onPipedFileHandleRead() {
2051+
const err = streamBaseState[kReadBytesOrError];
20472052
if (err < 0 && err !== UV_EOF) {
20482053
this.stream.close(NGHTTP2_INTERNAL_ERROR);
20492054
}
Collapse file

‎lib/internal/stream_base_commons.js‎

Copy file name to clipboardExpand all lines: lib/internal/stream_base_commons.js
+12-2Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
'use strict';
22

33
const { Buffer } = require('buffer');
4-
const { WriteWrap } = internalBinding('stream_wrap');
4+
const { FastBuffer } = require('internal/buffer');
5+
const {
6+
WriteWrap,
7+
kReadBytesOrError,
8+
kArrayBufferOffset,
9+
streamBaseState
10+
} = internalBinding('stream_wrap');
511
const { UV_EOF } = internalBinding('uv');
612
const { errnoException } = require('internal/errors');
713
const { owner_symbol } = require('internal/async_hooks').symbols;
@@ -84,13 +90,17 @@ function afterWriteDispatched(self, req, err, cb) {
8490
}
8591
}
8692

87-
function onStreamRead(nread, buf) {
93+
function onStreamRead(arrayBuffer) {
94+
const nread = streamBaseState[kReadBytesOrError];
95+
8896
const handle = this;
8997
const stream = this[owner_symbol];
9098

9199
stream[kUpdateTimer]();
92100

93101
if (nread > 0 && !stream.destroyed) {
102+
const offset = streamBaseState[kArrayBufferOffset];
103+
const buf = new FastBuffer(arrayBuffer, offset, nread);
94104
if (!stream.push(buf)) {
95105
handle.reading = false;
96106
if (!stream.destroyed) {
Collapse file

‎src/env-inl.h‎

Copy file name to clipboardExpand all lines: src/env-inl.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,11 @@ Environment::trace_category_state() {
446446
return trace_category_state_;
447447
}
448448

449+
inline AliasedBuffer<int32_t, v8::Int32Array>&
450+
Environment::stream_base_state() {
451+
return stream_base_state_;
452+
}
453+
449454
inline uint32_t Environment::get_next_module_id() {
450455
return module_id_counter_++;
451456
}
Collapse file

‎src/env.cc‎

Copy file name to clipboardExpand all lines: src/env.cc
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ Environment::Environment(IsolateData* isolate_data,
158158
makecallback_cntr_(0),
159159
should_abort_on_uncaught_toggle_(isolate_, 1),
160160
trace_category_state_(isolate_, kTraceCategoryCount),
161+
stream_base_state_(isolate_, StreamBase::kNumStreamBaseStateFields),
161162
http_parser_buffer_(nullptr),
162163
fs_stats_field_array_(isolate_, kFsStatsFieldsLength * 2),
163164
fs_stats_field_bigint_array_(isolate_, kFsStatsFieldsLength * 2),
Collapse file

‎src/env.h‎

Copy file name to clipboardExpand all lines: src/env.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ class Environment {
668668
should_abort_on_uncaught_toggle();
669669

670670
inline AliasedBuffer<uint8_t, v8::Uint8Array>& trace_category_state();
671+
inline AliasedBuffer<int32_t, v8::Int32Array>& stream_base_state();
671672

672673
// The necessary API for async_hooks.
673674
inline double new_async_id();
@@ -951,6 +952,8 @@ class Environment {
951952
AliasedBuffer<uint8_t, v8::Uint8Array> trace_category_state_;
952953
std::unique_ptr<TrackingTraceStateObserver> trace_state_observer_;
953954

955+
AliasedBuffer<int32_t, v8::Int32Array> stream_base_state_;
956+
954957
std::unique_ptr<performance::performance_state> performance_state_;
955958
std::unordered_map<std::string, uint64_t> performance_marks_;
956959

Collapse file

‎src/node_http2.cc‎

Copy file name to clipboardExpand all lines: src/node_http2.cc
+1-4Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,10 +1256,7 @@ void Http2StreamListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
12561256
CHECK_LE(offset, session->stream_buf_.len);
12571257
CHECK_LE(offset + buf.len, session->stream_buf_.len);
12581258

1259-
Local<Object> buffer =
1260-
Buffer::New(env, session->stream_buf_ab_, offset, nread).ToLocalChecked();
1261-
1262-
stream->CallJSOnreadMethod(nread, buffer);
1259+
stream->CallJSOnreadMethod(nread, session->stream_buf_ab_, offset);
12631260
}
12641261

12651262

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.