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: https://github.com/nodejs/node/pull/21409
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
This commit is contained in:
Ben Noordhuis 2018-06-19 21:14:31 +02:00
parent cbe307dc81
commit 7ec6951034
3 changed files with 37 additions and 15 deletions

View File

@ -131,11 +131,7 @@ void CallAndPauseOnStart(const FunctionCallbackInfo<v8::Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK_GT(args.Length(), 1);
CHECK(args[0]->IsFunction());
std::vector<v8::Local<v8::Value>> call_args;
for (int i = 2; i < args.Length(); i++) {
call_args.push_back(args[i]);
}
SlicedArguments call_args(args, /* start */ 2);
env->inspector_agent()->PauseOnNextJavascriptStatement("Break on start");
v8::MaybeLocal<v8::Value> retval =
args[0].As<v8::Function>()->Call(env->context(), args[1],
@ -150,10 +146,7 @@ void InspectorConsoleCall(const FunctionCallbackInfo<Value>& info) {
HandleScope handle_scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
CHECK_LT(2, info.Length());
std::vector<Local<Value>> call_args;
for (int i = 3; i < info.Length(); ++i) {
call_args.push_back(info[i]);
}
SlicedArguments call_args(info, /* start */ 3);
Environment* env = Environment::GetCurrent(isolate);
if (InspectorEnabled(env)) {
Local<Value> inspector_method = info[0];

View File

@ -40,6 +40,7 @@
#include <stdlib.h>
#include <string>
#include <vector>
// Custom constants used by both node_constants.cc and node_zlib.cc
#define Z_MIN_WINDOWBITS 8
@ -315,6 +316,39 @@ class FatalTryCatch : public v8::TryCatch {
Environment* env_;
};
class SlicedArguments {
public:
inline explicit SlicedArguments(
const v8::FunctionCallbackInfo<v8::Value>& args,
size_t start = 0);
inline size_t size() const { return size_; }
inline v8::Local<v8::Value>* data() { return data_; }
private:
size_t size_;
v8::Local<v8::Value>* data_;
v8::Local<v8::Value> fixed_[64];
std::vector<v8::Local<v8::Value>> dynamic_;
};
SlicedArguments::SlicedArguments(
const v8::FunctionCallbackInfo<v8::Value>& args,
size_t start) : size_(0), data_(fixed_) {
const size_t length = static_cast<size_t>(args.Length());
if (start >= length) return;
const size_t size = length - start;
if (size > arraysize(fixed_)) {
dynamic_.resize(size);
data_ = dynamic_.data();
}
for (size_t i = 0; i < size; ++i)
data_[i] = args[i + start];
size_ = size;
}
void ReportException(Environment* env,
v8::Local<v8::Value> er,
v8::Local<v8::Message> message);

View File

@ -1,8 +1,6 @@
#include "node_internals.h"
#include "node_perf.h"
#include <vector>
#ifdef __POSIX__
#include <sys/time.h> // gettimeofday
#endif
@ -309,10 +307,7 @@ void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) {
Local<Function> fn = args.Data().As<Function>();
size_t count = args.Length();
size_t idx;
std::vector<Local<Value>> call_args;
for (size_t i = 0; i < count; ++i)
call_args.push_back(args[i]);
SlicedArguments call_args(args);
Utf8Value name(isolate, GetName(fn));
uint64_t start;