Skip to content

Commit 7ffbb1f

Browse files
joyeecheungBridgeAR
authored andcommitted
http2: remove pushValueToArray in Http2Session::HandleHeadersFrame
Instead of calling into JS from C++ to push values into an array, use the new Array::New API that takes a pointer and a length directly. PR-URL: #24264 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
1 parent bb766ae commit 7ffbb1f

File tree

1 file changed

+14
-29
lines changed

1 file changed

+14
-29
lines changed

src/node_http2.cc

+14-29
Original file line numberDiff line numberDiff line change
@@ -1292,45 +1292,30 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) {
12921292
Local<String> value_str;
12931293

12941294
Local<Array> holder = Array::New(isolate);
1295-
Local<Function> fn = env()->push_values_to_array_function();
1296-
Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX * 2];
1297-
12981295
// The headers are passed in above as a queue of nghttp2_header structs.
12991296
// The following converts that into a JS array with the structure:
13001297
// [name1, value1, name2, value2, name3, value3, name3, value4] and so on.
13011298
// That array is passed up to the JS layer and converted into an Object form
13021299
// like {name1: value1, name2: value2, name3: [value3, value4]}. We do it
13031300
// this way for performance reasons (it's faster to generate and pass an
13041301
// array than it is to generate and pass the object).
1305-
size_t n = 0;
1306-
while (n < headers.size()) {
1307-
size_t j = 0;
1308-
while (n < headers.size() && j < arraysize(argv) / 2) {
1309-
nghttp2_header item = headers[n++];
1310-
// The header name and value are passed as external one-byte strings
1311-
name_str =
1312-
ExternalHeader::New<true>(this, item.name).ToLocalChecked();
1313-
value_str =
1314-
ExternalHeader::New<false>(this, item.value).ToLocalChecked();
1315-
argv[j * 2] = name_str;
1316-
argv[j * 2 + 1] = value_str;
1317-
j++;
1318-
}
1319-
// For performance, we pass name and value pairs to array.protototype.push
1320-
// in batches of size NODE_PUSH_VAL_TO_ARRAY_MAX * 2 until there are no
1321-
// more items to push.
1322-
if (j > 0) {
1323-
fn->Call(env()->context(), holder, j * 2, argv).ToLocalChecked();
1324-
}
1302+
size_t headers_size = headers.size();
1303+
std::vector<Local<Value>> headers_v(headers_size * 2);
1304+
for (size_t i = 0; i < headers_size; ++i) {
1305+
const nghttp2_header& item = headers[i];
1306+
// The header name and value are passed as external one-byte strings
1307+
headers_v[i * 2] =
1308+
ExternalHeader::New<true>(this, item.name).ToLocalChecked();
1309+
headers_v[i * 2 + 1] =
1310+
ExternalHeader::New<false>(this, item.value).ToLocalChecked();
13251311
}
13261312

13271313
Local<Value> args[5] = {
1328-
stream->object(),
1329-
Integer::New(isolate, id),
1330-
Integer::New(isolate, stream->headers_category()),
1331-
Integer::New(isolate, frame->hd.flags),
1332-
holder
1333-
};
1314+
stream->object(),
1315+
Integer::New(isolate, id),
1316+
Integer::New(isolate, stream->headers_category()),
1317+
Integer::New(isolate, frame->hd.flags),
1318+
Array::New(isolate, headers_v.data(), headers_size * 2)};
13341319
MakeCallback(env()->onheaders_string(), arraysize(args), args);
13351320
}
13361321

0 commit comments

Comments
 (0)