Skip to content

Commit 3d0602c

Browse files
joyeecheungdanielleadams
authored andcommitted
http: use v8::Array::New() with a prebuilt vector
Avoid using v8::Array::Set() which results in JS execution and is thus slow. Prebuild the vector in C++ land and build the JS array directly with that vector whereever possible. PR-URL: #46447 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Darshan Sen <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 5ef78e5 commit 3d0602c

File tree

1 file changed

+22
-29
lines changed

1 file changed

+22
-29
lines changed

src/node_http_parser.cc

+22-29
Original file line numberDiff line numberDiff line change
@@ -1037,68 +1037,60 @@ void ConnectionsList::New(const FunctionCallbackInfo<Value>& args) {
10371037

10381038
void ConnectionsList::All(const FunctionCallbackInfo<Value>& args) {
10391039
Isolate* isolate = args.GetIsolate();
1040-
Local<Context> context = isolate->GetCurrentContext();
10411040

1042-
Local<Array> all = Array::New(isolate);
10431041
ConnectionsList* list;
10441042

10451043
ASSIGN_OR_RETURN_UNWRAP(&list, args.Holder());
10461044

1047-
uint32_t i = 0;
1045+
std::vector<Local<Value>> result;
1046+
result.reserve(list->all_connections_.size());
10481047
for (auto parser : list->all_connections_) {
1049-
if (all->Set(context, i++, parser->object()).IsNothing()) {
1050-
return;
1051-
}
1048+
result.emplace_back(parser->object());
10521049
}
10531050

1054-
return args.GetReturnValue().Set(all);
1051+
return args.GetReturnValue().Set(
1052+
Array::New(isolate, result.data(), result.size()));
10551053
}
10561054

10571055
void ConnectionsList::Idle(const FunctionCallbackInfo<Value>& args) {
10581056
Isolate* isolate = args.GetIsolate();
1059-
Local<Context> context = isolate->GetCurrentContext();
10601057

1061-
Local<Array> idle = Array::New(isolate);
10621058
ConnectionsList* list;
10631059

10641060
ASSIGN_OR_RETURN_UNWRAP(&list, args.Holder());
10651061

1066-
uint32_t i = 0;
1062+
std::vector<Local<Value>> result;
1063+
result.reserve(list->all_connections_.size());
10671064
for (auto parser : list->all_connections_) {
10681065
if (parser->last_message_start_ == 0) {
1069-
if (idle->Set(context, i++, parser->object()).IsNothing()) {
1070-
return;
1071-
}
1066+
result.emplace_back(parser->object());
10721067
}
10731068
}
10741069

1075-
return args.GetReturnValue().Set(idle);
1070+
return args.GetReturnValue().Set(
1071+
Array::New(isolate, result.data(), result.size()));
10761072
}
10771073

10781074
void ConnectionsList::Active(const FunctionCallbackInfo<Value>& args) {
10791075
Isolate* isolate = args.GetIsolate();
1080-
Local<Context> context = isolate->GetCurrentContext();
10811076

1082-
Local<Array> active = Array::New(isolate);
10831077
ConnectionsList* list;
10841078

10851079
ASSIGN_OR_RETURN_UNWRAP(&list, args.Holder());
10861080

1087-
uint32_t i = 0;
1081+
std::vector<Local<Value>> result;
1082+
result.reserve(list->active_connections_.size());
10881083
for (auto parser : list->active_connections_) {
1089-
if (active->Set(context, i++, parser->object()).IsNothing()) {
1090-
return;
1091-
}
1084+
result.emplace_back(parser->object());
10921085
}
10931086

1094-
return args.GetReturnValue().Set(active);
1087+
return args.GetReturnValue().Set(
1088+
Array::New(isolate, result.data(), result.size()));
10951089
}
10961090

10971091
void ConnectionsList::Expired(const FunctionCallbackInfo<Value>& args) {
10981092
Isolate* isolate = args.GetIsolate();
1099-
Local<Context> context = isolate->GetCurrentContext();
11001093

1101-
Local<Array> expired = Array::New(isolate);
11021094
ConnectionsList* list;
11031095

11041096
ASSIGN_OR_RETURN_UNWRAP(&list, args.Holder());
@@ -1110,7 +1102,7 @@ void ConnectionsList::Expired(const FunctionCallbackInfo<Value>& args) {
11101102
static_cast<uint64_t>(args[1].As<Uint32>()->Value()) * 1000000;
11111103

11121104
if (headers_timeout == 0 && request_timeout == 0) {
1113-
return args.GetReturnValue().Set(expired);
1105+
return args.GetReturnValue().Set(Array::New(isolate, 0));
11141106
} else if (request_timeout > 0 && headers_timeout > request_timeout) {
11151107
std::swap(headers_timeout, request_timeout);
11161108
}
@@ -1121,9 +1113,11 @@ void ConnectionsList::Expired(const FunctionCallbackInfo<Value>& args) {
11211113
const uint64_t request_deadline =
11221114
request_timeout > 0 ? now - request_timeout : 0;
11231115

1124-
uint32_t i = 0;
11251116
auto iter = list->active_connections_.begin();
11261117
auto end = list->active_connections_.end();
1118+
1119+
std::vector<Local<Value>> result;
1120+
result.reserve(list->active_connections_.size());
11271121
while (iter != end) {
11281122
Parser* parser = *iter;
11291123
iter++;
@@ -1136,15 +1130,14 @@ void ConnectionsList::Expired(const FunctionCallbackInfo<Value>& args) {
11361130
request_deadline > 0 &&
11371131
parser->last_message_start_ < request_deadline)
11381132
) {
1139-
if (expired->Set(context, i++, parser->object()).IsNothing()) {
1140-
return;
1141-
}
1133+
result.emplace_back(parser->object());
11421134

11431135
list->active_connections_.erase(parser);
11441136
}
11451137
}
11461138

1147-
return args.GetReturnValue().Set(expired);
1139+
return args.GetReturnValue().Set(
1140+
Array::New(isolate, result.data(), result.size()));
11481141
}
11491142

11501143
const llhttp_settings_t Parser::settings = {

0 commit comments

Comments
 (0)