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: https://github.com/nodejs/node/pull/24264
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
Joyee Cheung 2018-11-09 11:28:56 +08:00
parent 60eca6a5d4
commit 5b97e31f72
No known key found for this signature in database
GPG Key ID: 92B78A53C8303B8D

View File

@ -1292,9 +1292,6 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) {
Local<String> value_str; Local<String> value_str;
Local<Array> holder = Array::New(isolate); Local<Array> holder = Array::New(isolate);
Local<Function> fn = env()->push_values_to_array_function();
Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX * 2];
// The headers are passed in above as a queue of nghttp2_header structs. // The headers are passed in above as a queue of nghttp2_header structs.
// The following converts that into a JS array with the structure: // The following converts that into a JS array with the structure:
// [name1, value1, name2, value2, name3, value3, name3, value4] and so on. // [name1, value1, name2, value2, name3, value3, name3, value4] and so on.
@ -1302,26 +1299,15 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) {
// like {name1: value1, name2: value2, name3: [value3, value4]}. We do it // like {name1: value1, name2: value2, name3: [value3, value4]}. We do it
// this way for performance reasons (it's faster to generate and pass an // this way for performance reasons (it's faster to generate and pass an
// array than it is to generate and pass the object). // array than it is to generate and pass the object).
size_t n = 0; size_t headers_size = headers.size();
while (n < headers.size()) { std::vector<Local<Value>> headers_v(headers_size * 2);
size_t j = 0; for (size_t i = 0; i < headers_size; ++i) {
while (n < headers.size() && j < arraysize(argv) / 2) { const nghttp2_header& item = headers[i];
nghttp2_header item = headers[n++];
// The header name and value are passed as external one-byte strings // The header name and value are passed as external one-byte strings
name_str = headers_v[i * 2] =
ExternalHeader::New<true>(this, item.name).ToLocalChecked(); ExternalHeader::New<true>(this, item.name).ToLocalChecked();
value_str = headers_v[i * 2 + 1] =
ExternalHeader::New<false>(this, item.value).ToLocalChecked(); ExternalHeader::New<false>(this, item.value).ToLocalChecked();
argv[j * 2] = name_str;
argv[j * 2 + 1] = value_str;
j++;
}
// For performance, we pass name and value pairs to array.protototype.push
// in batches of size NODE_PUSH_VAL_TO_ARRAY_MAX * 2 until there are no
// more items to push.
if (j > 0) {
fn->Call(env()->context(), holder, j * 2, argv).ToLocalChecked();
}
} }
Local<Value> args[5] = { Local<Value> args[5] = {
@ -1329,8 +1315,7 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) {
Integer::New(isolate, id), Integer::New(isolate, id),
Integer::New(isolate, stream->headers_category()), Integer::New(isolate, stream->headers_category()),
Integer::New(isolate, frame->hd.flags), Integer::New(isolate, frame->hd.flags),
holder Array::New(isolate, headers_v.data(), headers_size * 2)};
};
MakeCallback(env()->onheaders_string(), arraysize(args), args); MakeCallback(env()->onheaders_string(), arraysize(args), args);
} }