From 7ec6951034658b63f908977caeb83112d77cdf3b Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 19 Jun 2018 21:14:31 +0200 Subject: [PATCH] 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 Reviewed-By: Eugene Ostroukhov Reviewed-By: James M Snell Reviewed-By: Minwoo Jung Reviewed-By: Tiancheng "Timothy" Gu --- src/inspector_js_api.cc | 11 ++--------- src/node_internals.h | 34 ++++++++++++++++++++++++++++++++++ src/node_perf.cc | 7 +------ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index 802029ac4f2e5a..104cd93b3cd9e0 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -131,11 +131,7 @@ void CallAndPauseOnStart(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK_GT(args.Length(), 1); CHECK(args[0]->IsFunction()); - std::vector> 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 retval = args[0].As()->Call(env->context(), args[1], @@ -150,10 +146,7 @@ void InspectorConsoleCall(const FunctionCallbackInfo& info) { HandleScope handle_scope(isolate); Local context = isolate->GetCurrentContext(); CHECK_LT(2, info.Length()); - std::vector> 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 inspector_method = info[0]; diff --git a/src/node_internals.h b/src/node_internals.h index 025fa10100de92..cd791f8c059caf 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -40,6 +40,7 @@ #include #include +#include // 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& args, + size_t start = 0); + inline size_t size() const { return size_; } + inline v8::Local* data() { return data_; } + + private: + size_t size_; + v8::Local* data_; + v8::Local fixed_[64]; + std::vector> dynamic_; +}; + +SlicedArguments::SlicedArguments( + const v8::FunctionCallbackInfo& args, + size_t start) : size_(0), data_(fixed_) { + const size_t length = static_cast(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 er, v8::Local message); diff --git a/src/node_perf.cc b/src/node_perf.cc index 521492e589a2c0..900fbb4c9db528 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -1,8 +1,6 @@ #include "node_internals.h" #include "node_perf.h" -#include - #ifdef __POSIX__ #include // gettimeofday #endif @@ -309,10 +307,7 @@ void TimerFunctionCall(const FunctionCallbackInfo& args) { Local fn = args.Data().As(); size_t count = args.Length(); size_t idx; - std::vector> 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;