node/tools/code_cache/cache_builder.cc
Joyee Cheung fbc52e5729
src: disambiguate terms used to refer to builtins and addons
The term "native module" dates back to some of the oldest code
in the code base. Within the context of Node.js core it usually
refers to modules that are native to Node.js (e.g. fs, http),
but it can cause confusion for people who don't work on this
part of the code base, as "native module" can also refer to
native addons - which is even the case in some of the API
docs and error messages.

This patch tries to make the usage of these terms more consistent.
Now within the context of Node.js core:

- JavaScript scripts that are built-in to Node.js are now referred
  to as "built-in(s)". If they are available as modules,
  they can also be referred to as "built-in module(s)".
- Dynamically-linked shared objects that are loaded into
  the Node.js processes are referred to as "addons".

We will try to avoid using the term "native modules" because it could
be ambiguous.

Changes in this patch:

File names:
- node_native_module.h -> node_builtins.h,
- node_native_module.cc -> node_builtins.cc

C++ binding names:
- `native_module` -> `builtins`

`node::Environment`:
- `native_modules_without_cache` -> `builtins_without_cache`
- `native_modules_with_cache` -> `builtins_with_cache`
- `native_modules_in_snapshot` -> `builtins_in_cache`
- `native_module_require` -> `builtin_module_require`

`node::EnvSerializeInfo`:
- `native_modules` -> `builtins

`node::native_module::NativeModuleLoader`:
- `native_module` namespace -> `builtins` namespace
- `NativeModuleLoader` -> `BuiltinLoader`
- `NativeModuleRecordMap` -> `BuiltinSourceMap`
- `NativeModuleCacheMap` -> `BuiltinCodeCacheMap`
- `ModuleIds` -> `BuiltinIds`
- `ModuleCategories` -> `BuiltinCategories`
- `LoadBuiltinModuleSource` -> `LoadBuiltinSource`

`loader.js`:
- `NativeModule` -> `BuiltinModule` (the `NativeModule` name used in
  `process.moduleLoadList` is kept for compatibility)

And other clarifications in the documentation and comments.

PR-URL: https://github.com/nodejs/node/pull/44135
Backport-PR-URL: https://github.com/nodejs/node/pull/45663
Fixes: https://github.com/nodejs/node/issues/44036
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
2022-12-08 09:55:24 -05:00

149 lines
4.2 KiB
C++

#include "cache_builder.h"
#include "debug_utils-inl.h"
#include "node_builtins.h"
#include "node_builtins_env.h"
#include "util.h"
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <cstdlib>
namespace node {
namespace builtins {
using v8::Context;
using v8::Local;
using v8::ScriptCompiler;
static std::string GetDefName(const std::string& id) {
char buf[64] = {0};
size_t size = id.size();
CHECK_LT(size, sizeof(buf));
for (size_t i = 0; i < size; ++i) {
char ch = id[i];
buf[i] = (ch == '-' || ch == '/') ? '_' : ch;
}
return buf;
}
static std::string FormatSize(size_t size) {
char buf[64] = {0};
if (size < 1024) {
snprintf(buf, sizeof(buf), "%.2fB", static_cast<double>(size));
} else if (size < 1024 * 1024) {
snprintf(buf, sizeof(buf), "%.2fKB", static_cast<double>(size / 1024));
} else {
snprintf(
buf, sizeof(buf), "%.2fMB", static_cast<double>(size / 1024 / 1024));
}
return buf;
}
static std::string GetDefinition(const std::string& id,
size_t size,
const uint8_t* data) {
std::stringstream ss;
ss << "static const uint8_t " << GetDefName(id) << "[] = {\n";
for (size_t i = 0; i < size; ++i) {
uint8_t ch = data[i];
ss << std::to_string(ch) << (i == size - 1 ? '\n' : ',');
}
ss << "};";
return ss.str();
}
static void GetInitializer(const std::string& id, std::stringstream& ss) {
std::string def_name = GetDefName(id);
ss << " code_cache.emplace(\n";
ss << " \"" << id << "\",\n";
ss << " std::make_unique<v8::ScriptCompiler::CachedData>(\n";
ss << " " << def_name << ",\n";
ss << " static_cast<int>(arraysize(" << def_name << ")), policy\n";
ss << " )\n";
ss << " );";
}
static std::string GenerateCodeCache(
const std::map<std::string, ScriptCompiler::CachedData*>& data) {
std::stringstream ss;
ss << R"(#include <cinttypes>
#include "node_builtins_env.h"
// This file is generated by mkcodecache (tools/code_cache/mkcodecache.cc)
namespace node {
namespace builtins {
const bool has_code_cache = true;
)";
size_t total = 0;
for (const auto& x : data) {
const std::string& id = x.first;
ScriptCompiler::CachedData* cached_data = x.second;
total += cached_data->length;
std::string def = GetDefinition(id, cached_data->length, cached_data->data);
ss << def << "\n\n";
std::string size_str = FormatSize(cached_data->length);
std::string total_str = FormatSize(total);
per_process::Debug(DebugCategory::CODE_CACHE,
"Generated cache for %s, size = %s, total = %s\n",
id.c_str(),
size_str.c_str(),
total_str.c_str());
}
ss << R"(void BuiltinEnv::InitializeCodeCache() {
BuiltinCodeCacheMap& code_cache =
*BuiltinLoader::GetInstance()->code_cache();
CHECK(code_cache.empty());
auto policy = v8::ScriptCompiler::CachedData::BufferPolicy::BufferNotOwned;
)";
for (const auto& x : data) {
GetInitializer(x.first, ss);
ss << "\n\n";
}
ss << R"(
}
} // namespace builtins
} // namespace node
)";
return ss.str();
}
std::string CodeCacheBuilder::Generate(Local<Context> context) {
BuiltinLoader* loader = BuiltinLoader::GetInstance();
std::vector<std::string> ids = loader->GetBuiltinIds();
std::map<std::string, ScriptCompiler::CachedData*> data;
for (const auto& id : ids) {
// TODO(joyeecheung): we can only compile the modules that can be
// required here because the parameters for other types of builtins
// are still very flexible. We should look into auto-generating
// the parameters from the source somehow.
if (loader->CanBeRequired(id.c_str())) {
BuiltinLoader::Result result;
USE(loader->CompileAsModule(context, id.c_str(), &result));
ScriptCompiler::CachedData* cached_data =
loader->GetCodeCache(id.c_str());
if (cached_data == nullptr) {
// TODO(joyeecheung): display syntax errors
std::cerr << "Failed to compile " << id << "\n";
} else {
data.emplace(id, cached_data);
}
}
}
return GenerateCodeCache(data);
}
} // namespace builtins
} // namespace node