Skip to content

Commit 236bdfd

Browse files
committed
src: build v8 tick processor as built-in source text modules
Instead of polyfilling it with vm.SourceTextModule, use a built-in source text module loader so that we can also build the code cache for it at build tiem to embed the code cache for them in the binary. Drive-by: instead of inferring how to compile a particular built-in at run time, do the inferring at build time, so the function-based built-ins can be compiled using parameters quickly looked up from a static map, and the builtins that should be compiled as source text modules are known internally based on extension in the source code (at run time, the extensions are all removed).
1 parent 684c3b3 commit 236bdfd

File tree

15 files changed

+586
-316
lines changed

15 files changed

+586
-316
lines changed

lib/internal/main/prof_process.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
'use strict';
22

3+
// TODO(joyeecheung): put the context locals in import.meta.
4+
const {
5+
ObjectAssign,
6+
globalThis,
7+
} = primordials;
8+
39
const {
410
prepareMainThreadExecution,
511
markBootstrapComplete,
612
} = require('internal/process/pre_execution');
713

14+
const { importBuiltinSourceTextModule } = internalBinding('builtins');
15+
816
prepareMainThreadExecution();
917
markBootstrapComplete();
10-
require('internal/v8_prof_processor');
18+
19+
const { globals, openFile } = require('internal/v8_prof_polyfill');
20+
ObjectAssign(globalThis, globals);
21+
openFile(process.argv[process.argv.length - 1]);
22+
23+
(async () => {
24+
const {
25+
promise,
26+
} = importBuiltinSourceTextModule('internal/deps/v8/tools/tickprocessor-driver');
27+
await promise;
28+
})();

lib/internal/v8_prof_polyfill.js

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@
3030
/* eslint-disable node-core/prefer-primordials, no-restricted-globals */
3131
/* global console */
3232

33-
module.exports = { versionCheck };
33+
const {
34+
ArrayPrototypePush,
35+
ArrayPrototypePushApply,
36+
ArrayPrototypeSlice,
37+
} = primordials;
3438

35-
// Don't execute when required directly instead of being eval'd from
36-
// lib/internal/v8_prof_processor.js. This way we can test functions
37-
// from this file in isolation.
38-
if (module.id === 'internal/v8_prof_polyfill') return;
39-
40-
// Node polyfill
4139
const fs = require('fs');
4240
const cp = require('child_process');
4341
const { Buffer } = require('buffer');
42+
const { StringDecoder } = require('string_decoder');
43+
4444
const os = {
4545
system: function(name, args) {
4646
if (process.platform === 'linux' && name === 'nm') {
@@ -68,24 +68,40 @@ const os = {
6868
},
6969
};
7070
const print = console.log;
71+
7172
function read(fileName) {
7273
return fs.readFileSync(fileName, 'utf8');
7374
}
7475
const quit = process.exit;
75-
// Polyfill "readline()".
76-
const logFile = globalThis.arguments[globalThis.arguments.length - 1];
77-
try {
78-
fs.accessSync(logFile);
79-
} catch {
80-
console.error('Please provide a valid isolate file as the final argument.');
81-
process.exit(1);
76+
77+
const tickArguments = [];
78+
if (process.platform === 'darwin') {
79+
ArrayPrototypePush(tickArguments, '--mac');
80+
} else if (process.platform === 'win32') {
81+
ArrayPrototypePush(tickArguments, '--windows');
8282
}
83-
const fd = fs.openSync(logFile, 'r');
83+
ArrayPrototypePushApply(tickArguments,
84+
ArrayPrototypeSlice(process.argv, 1));
85+
86+
function write(str) { process.stdout.write(str); };
87+
function printErr(str) { process.stderr.write(str); };
88+
89+
let logFile;
90+
let fd;
8491
const buf = Buffer.allocUnsafe(4096);
85-
const dec = new (require('string_decoder').StringDecoder)('utf-8');
92+
const dec = new StringDecoder('utf-8');
8693
let line = '';
8794

88-
{
95+
function openFile(filename) {
96+
logFile = filename;
97+
try {
98+
fd = fs.openSync(logFile, 'r');
99+
} catch (e) {
100+
console.error(`Cannot access log file: ${logFile}`);
101+
console.error('Please provide a valid isolate file as the final argument.');
102+
throw e;
103+
}
104+
89105
const message = versionCheck(peekline(), process.versions.v8);
90106
if (message) console.log(message);
91107
}
@@ -162,10 +178,17 @@ function macCppfiltNm(out) {
162178
});
163179
}
164180

165-
Object.assign(globalThis, {
166-
os,
167-
print,
168-
read,
169-
quit,
170-
readline,
171-
});
181+
module.exports = {
182+
globals: {
183+
arguments: tickArguments,
184+
write,
185+
printErr,
186+
os,
187+
print,
188+
read,
189+
quit,
190+
readline,
191+
},
192+
openFile,
193+
versionCheck,
194+
};

lib/internal/v8_prof_processor.js

Lines changed: 0 additions & 54 deletions
This file was deleted.

node.gyp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
'src/async_context_frame.cc',
7474
'src/async_wrap.cc',
7575
'src/base_object.cc',
76+
'src/builtin_info.cc',
7677
'src/cares_wrap.cc',
7778
'src/cleanup_queue.cc',
7879
'src/compile_cache.cc',
@@ -214,6 +215,7 @@
214215
'src/base_object_types.h',
215216
'src/blob_serializer_deserializer.h',
216217
'src/blob_serializer_deserializer-inl.h',
218+
"src/builtin_info.h",
217219
'src/callback_queue.h',
218220
'src/callback_queue-inl.h',
219221
'src/cleanup_queue.h',
@@ -1381,6 +1383,8 @@
13811383
'tools/executable_wrapper.h',
13821384
'src/embedded_data.h',
13831385
'src/embedded_data.cc',
1386+
'src/builtin_info.h',
1387+
'src/builtin_info.cc',
13841388
],
13851389
'conditions': [
13861390
[ 'node_shared_simdutf=="false"', {

src/api/environment.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ Maybe<void> InitializePrimordials(Local<Context> context,
914914
exports, primordials, private_symbols, per_isolate_symbols};
915915

916916
if (builtin_loader
917-
.CompileAndCall(
917+
.CompileAndCallWith(
918918
context, *module, arraysize(arguments), arguments, nullptr)
919919
.IsEmpty()) {
920920
// Execution failed during context creation.

src/builtin_info.cc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include "builtin_info.h"
2+
3+
namespace node {
4+
namespace builtins {
5+
6+
BuiltinSourceType GetBuiltinSourceType(const std::string& id,
7+
const std::string& filename) {
8+
if (filename.ends_with(".mjs")) {
9+
return BuiltinSourceType::kSourceTextModule;
10+
}
11+
if (id.starts_with("internal/bootstrap/realm")) {
12+
return BuiltinSourceType::kBootstrapRealm;
13+
}
14+
if (id.starts_with("internal/bootstrap/")) {
15+
return BuiltinSourceType::kBootstrapScript;
16+
}
17+
if (id.starts_with("internal/per_context/")) {
18+
return BuiltinSourceType::kPerContextScript;
19+
}
20+
if (id.starts_with("internal/main/")) {
21+
return BuiltinSourceType::kMainScript;
22+
}
23+
if (id.starts_with("internal/deps/v8/tools/")) {
24+
return BuiltinSourceType::kSourceTextModule;
25+
}
26+
return BuiltinSourceType::kFunction;
27+
}
28+
29+
std::string GetBuiltinSourceTypeName(BuiltinSourceType type) {
30+
switch (type) {
31+
case BuiltinSourceType::kBootstrapRealm:
32+
return "kBootstrapRealm";
33+
case BuiltinSourceType::kBootstrapScript:
34+
return "kBootstrapScript";
35+
case BuiltinSourceType::kPerContextScript:
36+
return "kPerContextScript";
37+
case BuiltinSourceType::kMainScript:
38+
return "kMainScript";
39+
case BuiltinSourceType::kFunction:
40+
return "kFunction";
41+
case BuiltinSourceType::kSourceTextModule:
42+
return "kSourceTextModule";
43+
}
44+
abort();
45+
}
46+
47+
} // namespace builtins
48+
} // namespace node

src/builtin_info.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef SRC_BUILTIN_INFO_H_
2+
#define SRC_BUILTIN_INFO_H_
3+
4+
#include <cinttypes>
5+
#include <string>
6+
#include <unordered_map>
7+
#include <vector>
8+
9+
// This file must not depend on node.h or other code that depends on
10+
// the full Node.js implementation because it is used during the
11+
// compilation of the Node.js implementation itself (especially js2c).
12+
13+
namespace node {
14+
namespace builtins {
15+
16+
enum class BuiltinSourceType {
17+
kBootstrapRealm, // internal/bootstrap/realm
18+
kBootstrapScript, // internal/bootstrap/*
19+
kPerContextScript, // internal/per_context/*
20+
kMainScript, // internal/main/*
21+
kFunction, // others
22+
kSourceTextModule, // selected modules, ends with .mjs in source
23+
};
24+
25+
struct BuiltinInfo {
26+
// C++17 inline static
27+
inline static const std::unordered_map<BuiltinSourceType,
28+
std::vector<std::string>>
29+
parameter_map{
30+
{BuiltinSourceType::kBootstrapRealm,
31+
{"process",
32+
"getLinkedBinding",
33+
"getInternalBinding",
34+
"primordials"}},
35+
{BuiltinSourceType::kBootstrapScript,
36+
{"process", "require", "internalBinding", "primordials"}},
37+
{BuiltinSourceType::kPerContextScript,
38+
{"exports", "primordials", "privateSymbols", "perIsolateSymbols"}},
39+
{BuiltinSourceType::kMainScript,
40+
{"process", "require", "internalBinding", "primordials"}},
41+
{BuiltinSourceType::kFunction,
42+
{"exports",
43+
"require",
44+
"module",
45+
"process",
46+
"internalBinding",
47+
"primordials"}},
48+
};
49+
};
50+
51+
std::string GetBuiltinSourceTypeName(BuiltinSourceType type);
52+
BuiltinSourceType GetBuiltinSourceType(const std::string& id,
53+
const std::string& filename);
54+
} // namespace builtins
55+
} // namespace node
56+
57+
#endif // SRC_BUILTIN_INFO_H_

src/env_properties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
V(onpskexchange_symbol, "onpskexchange") \
5858
V(resource_symbol, "resource_symbol") \
5959
V(trigger_async_id_symbol, "trigger_async_id_symbol") \
60+
V(builtin_source_text_module_hdo, "builtin_source_text_module_hdo") \
6061
V(source_text_module_default_hdo, "source_text_module_default_hdo") \
6162
V(vm_context_no_contextify, "vm_context_no_contextify") \
6263
V(vm_dynamic_import_default_internal, "vm_dynamic_import_default_internal") \

0 commit comments

Comments
 (0)