Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2018-12-03 16:47:57 +0300
committerJoyee Cheung <joyeec9h3@gmail.com>2018-12-18 13:02:11 +0300
commit0858e5d9d8db085cb83b3f1f3f94ed6b550a7bc5 (patch)
tree23855a4a96c3101d99a121c9ff158b9bea912708 /src/node_native_module.h
parentceb66352236240498a9263500c7bde74e58c71fa (diff)
src: always compile and store code cache for native modules
This patch changes the NativeModuleLoader to always try to find code cache for native modules when it compiles them, and always produce and store the code cache after compilation. The cache map is protected by a mutex and can be accessed by different threads - including the worker threads and the main thread. Hence any thread can reuse the code cache if the native module has already been compiled by another thread - in particular the cache of the bootstrappers and per_context.js will always be hit when a new thread is spun. This results in a ~6% startup overhead in the worst case (when only the main thread is launched without requiring any additional native module - it now needs to do the extra work of finding and storing caches), which balances out the recent improvements by moving the compilation to C++, but it also leads to a ~60% improvement in the best case (when a worker thread is spun and requires a lot of native modules thus hitting the cache compiled by the main thread). PR-URL: https://github.com/nodejs/node/pull/24950 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_native_module.h')
-rw-r--r--src/node_native_module.h47
1 files changed, 25 insertions, 22 deletions
diff --git a/src/node_native_module.h b/src/node_native_module.h
index 54c5f388f74..2e5821c2cfc 100644
--- a/src/node_native_module.h
+++ b/src/node_native_module.h
@@ -7,6 +7,7 @@
#include <set>
#include <string>
#include "env.h"
+#include "node_mutex.h"
#include "node_union_bytes.h"
#include "v8.h"
@@ -14,7 +15,9 @@ namespace node {
namespace native_module {
using NativeModuleRecordMap = std::map<std::string, UnionBytes>;
-using NativeModuleHashMap = std::map<std::string, std::string>;
+using NativeModuleCacheMap =
+ std::unordered_map<std::string,
+ std::unique_ptr<v8::ScriptCompiler::CachedData>>;
// The native (C++) side of the NativeModule in JS land, which
// handles compilation and caching of builtin modules (NativeModule)
@@ -25,16 +28,12 @@ using NativeModuleHashMap = std::map<std::string, std::string>;
// The instances of this class are per-process.
class NativeModuleLoader {
public:
- // kCodeCache indicates that the compilation result should be returned
- // as a Uint8Array, whereas kFunction indicates that the result should
- // be returned as a Function.
- // TODO(joyeecheung): it's possible to always produce code cache
- // on the main thread and consume them in worker threads, or just
- // share the cache among all the threads, although
- // we need to decide whether to do that even when workers are not used.
- enum class CompilationResultType { kCodeCache, kFunction };
-
NativeModuleLoader();
+ // TODO(joyeecheung): maybe we should make this a singleton, instead of
+ // putting it in per_process.
+ NativeModuleLoader(const NativeModuleLoader&) = delete;
+ NativeModuleLoader& operator=(const NativeModuleLoader&) = delete;
+
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
@@ -43,8 +42,6 @@ class NativeModuleLoader {
// Returns config.gypi as a JSON string
v8::Local<v8::String> GetConfigString(v8::Isolate* isolate) const;
- v8::Local<v8::String> GetSource(v8::Isolate* isolate, const char* id) const;
-
// Run a script with JS source bundled inside the binary as if it's wrapped
// in a function called with a null receiver and arguments specified in C++.
// The returned value is empty if an exception is encountered.
@@ -68,8 +65,10 @@ class NativeModuleLoader {
static void ConfigStringGetter(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
- // Compile code cache for a specific native module
- static void CompileCodeCache(const v8::FunctionCallbackInfo<v8::Value>& args);
+ // Get code cache for a specific native module
+ static void GetCodeCache(const v8::FunctionCallbackInfo<v8::Value>& args);
+ v8::MaybeLocal<v8::Uint8Array> GetCodeCache(v8::Isolate* isolate,
+ const char* id) const;
// Compile a specific native module as a function
static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -82,30 +81,34 @@ class NativeModuleLoader {
// in node_code_cache_stub.cc
void LoadCodeCache(); // Loads data into code_cache_
- v8::ScriptCompiler::CachedData* GetCachedData(const char* id) const;
-
// Compile a script as a NativeModule that can be loaded via
// NativeModule.p.require in JS land.
- static v8::MaybeLocal<v8::Value> CompileAsModule(
- Environment* env, const char* id, CompilationResultType result_type);
+ static v8::MaybeLocal<v8::Function> CompileAsModule(Environment* env,
+ const char* id);
// For bootstrappers optional_env may be a nullptr.
// If an exception is encountered (e.g. source code contains
// syntax error), the returned value is empty.
- v8::MaybeLocal<v8::Value> LookupAndCompile(
+ v8::MaybeLocal<v8::Function> LookupAndCompile(
v8::Local<v8::Context> context,
const char* id,
std::vector<v8::Local<v8::String>>* parameters,
- CompilationResultType result_type,
Environment* optional_env);
- bool has_code_cache_ = false;
NativeModuleRecordMap source_;
- NativeModuleRecordMap code_cache_;
+ NativeModuleCacheMap code_cache_;
UnionBytes config_;
+
+ // Used to synchronize access to the code cache map
+ Mutex code_cache_mutex_;
};
} // namespace native_module
+
+namespace per_process {
+extern native_module::NativeModuleLoader native_module_loader;
+} // namespace per_process
+
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS