Skip to content

Commit e1d55a0

Browse files
committed
src: port bootstrap/cache.js to C++
This allows us to query the categories of modules in C++ so we can implement the code cache generator in C++ that does not depend on a Node.js binary. PR-URL: #27046 Refs: #21563 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent f59ec2a commit e1d55a0

File tree

7 files changed

+140
-107
lines changed

7 files changed

+140
-107
lines changed
+4-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
'use strict';
22

3-
const list = require('internal/bootstrap/cache');
3+
const { internalBinding } = require('internal/test/binding');
44
const {
5-
isMainThread
6-
} = require('worker_threads');
5+
moduleCategories: { canBeRequired }
6+
} = internalBinding('native_module');
77

8-
for (const key of list.cachableBuiltins) {
9-
if (!isMainThread && key === 'trace_events') {
10-
continue;
11-
}
8+
for (const key of canBeRequired) {
129
require(key);
1310
}

lib/internal/bootstrap/cache.js

-85
This file was deleted.

node.gyp

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
'node_intermediate_lib_type%': 'static_library',
2828
'library_files': [
2929
'lib/internal/bootstrap/primordials.js',
30-
'lib/internal/bootstrap/cache.js',
3130
'lib/internal/bootstrap/environment.js',
3231
'lib/internal/bootstrap/loaders.js',
3332
'lib/internal/bootstrap/node.js',

src/node_native_module.cc

+114
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,75 @@ using v8::String;
3636
using v8::Uint8Array;
3737
using v8::Value;
3838

39+
void NativeModuleLoader::InitializeModuleCategories() {
40+
if (module_categories_.is_initialized) {
41+
DCHECK(!module_categories_.can_be_required.empty());
42+
return;
43+
}
44+
45+
std::vector<std::string> prefixes = {
46+
#if !HAVE_OPENSSL
47+
"internal/crypto/",
48+
#endif // !HAVE_OPENSSL
49+
50+
"internal/bootstrap/",
51+
"internal/per_context/",
52+
"internal/deps/",
53+
"internal/main/"
54+
};
55+
56+
module_categories_.cannot_be_required = std::set<std::string> {
57+
#if !HAVE_INSPECTOR
58+
"inspector",
59+
"internal/util/inspector",
60+
#endif // !HAVE_INSPECTOR
61+
62+
#if !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT)
63+
"trace_events",
64+
#endif // !NODE_USE_V8_PLATFORM
65+
66+
#if !HAVE_OPENSSL
67+
"crypto",
68+
"https",
69+
"http2",
70+
"tls",
71+
"_tls_common",
72+
"_tls_wrap",
73+
"internal/http2/core",
74+
"internal/http2/compat",
75+
"internal/policy/manifest",
76+
"internal/process/policy",
77+
"internal/streams/lazy_transform",
78+
#endif // !HAVE_OPENSSL
79+
80+
"sys", // Deprecated.
81+
"internal/test/binding",
82+
"internal/v8_prof_polyfill",
83+
"internal/v8_prof_processor",
84+
};
85+
86+
for (auto const& x : source_) {
87+
const std::string& id = x.first;
88+
for (auto const& prefix : prefixes) {
89+
if (prefix.length() > id.length()) {
90+
continue;
91+
}
92+
if (id.find(prefix) == 0) {
93+
module_categories_.cannot_be_required.emplace(id);
94+
}
95+
}
96+
}
97+
98+
for (auto const& x : source_) {
99+
const std::string& id = x.first;
100+
if (0 == module_categories_.cannot_be_required.count(id)) {
101+
module_categories_.can_be_required.emplace(id);
102+
}
103+
}
104+
105+
module_categories_.is_initialized = true;
106+
}
107+
39108
// TODO(joyeecheung): make these more general and put them into util.h
40109
Local<Object> MapToObject(Local<Context> context,
41110
const NativeModuleRecordMap& in) {
@@ -63,6 +132,39 @@ bool NativeModuleLoader::Exists(const char* id) {
63132
return source_.find(id) != source_.end();
64133
}
65134

135+
void NativeModuleLoader::GetModuleCategories(
136+
Local<Name> property, const PropertyCallbackInfo<Value>& info) {
137+
per_process::native_module_loader.InitializeModuleCategories();
138+
139+
Environment* env = Environment::GetCurrent(info);
140+
Isolate* isolate = env->isolate();
141+
Local<Context> context = env->context();
142+
Local<Object> result = Object::New(isolate);
143+
144+
// Copy from the per-process categories
145+
std::set<std::string> cannot_be_required =
146+
per_process::native_module_loader.module_categories_.cannot_be_required;
147+
std::set<std::string> can_be_required =
148+
per_process::native_module_loader.module_categories_.can_be_required;
149+
150+
if (!env->owns_process_state()) {
151+
can_be_required.erase("trace_events");
152+
cannot_be_required.insert("trace_events");
153+
}
154+
155+
result
156+
->Set(context,
157+
OneByteString(isolate, "cannotBeRequired"),
158+
ToJsSet(context, cannot_be_required))
159+
.FromJust();
160+
result
161+
->Set(context,
162+
OneByteString(isolate, "canBeRequired"),
163+
ToJsSet(context, can_be_required))
164+
.FromJust();
165+
info.GetReturnValue().Set(result);
166+
}
167+
66168
void NativeModuleLoader::GetCacheUsage(
67169
const FunctionCallbackInfo<Value>& args) {
68170
Environment* env = Environment::GetCurrent(args);
@@ -298,6 +400,18 @@ void NativeModuleLoader::Initialize(Local<Object> target,
298400
SideEffectType::kHasNoSideEffect)
299401
.FromJust());
300402

403+
CHECK(target
404+
->SetAccessor(
405+
env->context(),
406+
FIXED_ONE_BYTE_STRING(env->isolate(), "moduleCategories"),
407+
GetModuleCategories,
408+
nullptr,
409+
env->as_callback_data(),
410+
DEFAULT,
411+
None,
412+
SideEffectType::kHasNoSideEffect)
413+
.FromJust());
414+
301415
env->SetMethod(
302416
target, "getCacheUsage", NativeModuleLoader::GetCacheUsage);
303417
env->SetMethod(

src/node_native_module.h

+12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class NativeModuleLoader {
5454
Environment* optional_env);
5555

5656
private:
57+
static void GetModuleCategories(
58+
v8::Local<v8::Name> property,
59+
const v8::PropertyCallbackInfo<v8::Value>& info);
5760
static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
5861
// Passing ids of builtin module source code into JS land as
5962
// internalBinding('native_module').moduleIds
@@ -84,6 +87,15 @@ class NativeModuleLoader {
8487
static v8::MaybeLocal<v8::Function> CompileAsModule(Environment* env,
8588
const char* id);
8689

90+
void InitializeModuleCategories();
91+
struct ModuleCategories {
92+
bool is_initialized = false;
93+
std::set<std::string> can_be_required;
94+
std::set<std::string> cannot_be_required;
95+
};
96+
97+
ModuleCategories module_categories_;
98+
8799
NativeModuleRecordMap source_;
88100
NativeModuleCacheMap code_cache_;
89101
UnionBytes config_;

test/code-cache/test-code-cache.js

+4-11
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,15 @@
77

88
const { isMainThread } = require('../common');
99
const assert = require('assert');
10-
const {
11-
cachableBuiltins,
12-
cannotBeRequired
13-
} = require('internal/bootstrap/cache');
14-
1510
const {
1611
internalBinding
1712
} = require('internal/test/binding');
1813
const {
19-
getCacheUsage
14+
getCacheUsage,
15+
moduleCategories: { canBeRequired, cannotBeRequired }
2016
} = internalBinding('native_module');
2117

22-
for (const key of cachableBuiltins) {
23-
if (!isMainThread && key === 'trace_events') {
24-
continue; // Cannot load trace_events in workers
25-
}
18+
for (const key of canBeRequired) {
2619
require(key);
2720
}
2821

@@ -60,7 +53,7 @@ if (process.config.variables.node_code_cache_path === undefined) {
6053
);
6154

6255
for (const key of loadedModules) {
63-
if (cannotBeRequired.includes(key)) {
56+
if (cannotBeRequired.has(key)) {
6457
assert(compiledWithoutCache.has(key),
6558
`"${key}" should've been compiled without code cache`);
6659
} else {

tools/generate_code_cache.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
// compiled into the binary using the `--code-cache-path` option
88
// of `configure`.
99

10+
const { internalBinding } = require('internal/test/binding');
1011
const {
12+
moduleCategories: { canBeRequired },
1113
getCodeCache,
1214
compileFunction,
13-
cachableBuiltins
14-
} = require('internal/bootstrap/cache');
15+
} = internalBinding('native_module');
1516

1617
const {
1718
types: {
@@ -85,7 +86,9 @@ function lexical(a, b) {
8586
return 0;
8687
}
8788

88-
for (const key of cachableBuiltins.sort(lexical)) {
89+
// TODO(joyeecheung): support non-modules that require different
90+
// parameters in the wrapper.
91+
for (const key of [...canBeRequired].sort(lexical)) {
8992
compileFunction(key); // compile it
9093
const cachedData = getCodeCache(key);
9194
if (!isUint8Array(cachedData)) {

0 commit comments

Comments
 (0)