Skip to content

Commit e0bcb6a

Browse files
bnoordhuistargos
authored andcommitted
src: avoid common case heap allocation
Optimize three functions that pass on (part of) their JS arguments to the JS function they call by stack-allocating the storage in the common case. PR-URL: #21409 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Eugene Ostroukhov <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
1 parent 8e5104b commit e0bcb6a

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

src/inspector_js_api.cc

+2-9
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,7 @@ void CallAndPauseOnStart(const FunctionCallbackInfo<v8::Value>& args) {
131131
Environment* env = Environment::GetCurrent(args);
132132
CHECK_GT(args.Length(), 1);
133133
CHECK(args[0]->IsFunction());
134-
std::vector<v8::Local<v8::Value>> call_args;
135-
for (int i = 2; i < args.Length(); i++) {
136-
call_args.push_back(args[i]);
137-
}
138-
134+
SlicedArguments call_args(args, /* start */ 2);
139135
env->inspector_agent()->PauseOnNextJavascriptStatement("Break on start");
140136
v8::MaybeLocal<v8::Value> retval =
141137
args[0].As<v8::Function>()->Call(env->context(), args[1],
@@ -150,10 +146,7 @@ void InspectorConsoleCall(const FunctionCallbackInfo<Value>& info) {
150146
HandleScope handle_scope(isolate);
151147
Local<Context> context = isolate->GetCurrentContext();
152148
CHECK_LT(2, info.Length());
153-
std::vector<Local<Value>> call_args;
154-
for (int i = 3; i < info.Length(); ++i) {
155-
call_args.push_back(info[i]);
156-
}
149+
SlicedArguments call_args(info, /* start */ 3);
157150
Environment* env = Environment::GetCurrent(isolate);
158151
if (InspectorEnabled(env)) {
159152
Local<Value> inspector_method = info[0];

src/node_internals.h

+34
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <stdlib.h>
4141

4242
#include <string>
43+
#include <vector>
4344

4445
// Custom constants used by both node_constants.cc and node_zlib.cc
4546
#define Z_MIN_WINDOWBITS 8
@@ -315,6 +316,39 @@ class FatalTryCatch : public v8::TryCatch {
315316
Environment* env_;
316317
};
317318

319+
class SlicedArguments {
320+
public:
321+
inline explicit SlicedArguments(
322+
const v8::FunctionCallbackInfo<v8::Value>& args,
323+
size_t start = 0);
324+
inline size_t size() const { return size_; }
325+
inline v8::Local<v8::Value>* data() { return data_; }
326+
327+
private:
328+
size_t size_;
329+
v8::Local<v8::Value>* data_;
330+
v8::Local<v8::Value> fixed_[64];
331+
std::vector<v8::Local<v8::Value>> dynamic_;
332+
};
333+
334+
SlicedArguments::SlicedArguments(
335+
const v8::FunctionCallbackInfo<v8::Value>& args,
336+
size_t start) : size_(0), data_(fixed_) {
337+
const size_t length = static_cast<size_t>(args.Length());
338+
if (start >= length) return;
339+
const size_t size = length - start;
340+
341+
if (size > arraysize(fixed_)) {
342+
dynamic_.resize(size);
343+
data_ = dynamic_.data();
344+
}
345+
346+
for (size_t i = 0; i < size; ++i)
347+
data_[i] = args[i + start];
348+
349+
size_ = size;
350+
}
351+
318352
void ReportException(Environment* env,
319353
v8::Local<v8::Value> er,
320354
v8::Local<v8::Message> message);

src/node_perf.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#include "node_internals.h"
22
#include "node_perf.h"
33

4-
#include <vector>
5-
64
#ifdef __POSIX__
75
#include <sys/time.h> // gettimeofday
86
#endif
@@ -309,10 +307,7 @@ void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) {
309307
Local<Function> fn = args.Data().As<Function>();
310308
size_t count = args.Length();
311309
size_t idx;
312-
std::vector<Local<Value>> call_args;
313-
for (size_t i = 0; i < count; ++i)
314-
call_args.push_back(args[i]);
315-
310+
SlicedArguments call_args(args);
316311
Utf8Value name(isolate, GetName(fn));
317312

318313
uint64_t start;

0 commit comments

Comments
 (0)