Skip to content

Commit d7ff78b

Browse files
joyeecheungUlisesGascon
authored andcommitted
sea: generate code cache with deserialized isolate
V8 now requires code cache to be compiled from an isolate with the same RO space layout as the one that's going to deserialize the cache, so for a binary built with snapshot, we need to compile the code cache using a deserialized isolate. Drive-by: ignore "useCodeCache" when "useSnapshot" is true because the compilation would've been done during build time anyway in that case, and print a warning for it. PR-URL: #49226 Refs: nodejs/node-v8#252 Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 55d6649 commit d7ff78b

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

src/node_sea.cc

+13-8
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ ExitCode GenerateSnapshotForSEA(const SeaConfig& config,
411411

412412
std::optional<std::string> GenerateCodeCache(std::string_view main_path,
413413
std::string_view main_script) {
414-
RAIIIsolate raii_isolate;
414+
RAIIIsolate raii_isolate(SnapshotBuilder::GetEmbeddedSnapshotData());
415415
Isolate* isolate = raii_isolate.get();
416416

417417
HandleScope handle_scope(isolate);
@@ -489,14 +489,19 @@ ExitCode GenerateSingleExecutableBlob(
489489
std::optional<std::string_view> optional_sv_code_cache;
490490
std::string code_cache;
491491
if (static_cast<bool>(config.flags & SeaFlags::kUseCodeCache)) {
492-
std::optional<std::string> optional_code_cache =
493-
GenerateCodeCache(config.main_path, main_script);
494-
if (!optional_code_cache.has_value()) {
495-
FPrintF(stderr, "Cannot generate V8 code cache\n");
496-
return ExitCode::kGenericUserError;
492+
if (builds_snapshot_from_main) {
493+
FPrintF(stderr,
494+
"\"useCodeCache\" is redundant when \"useSnapshot\" is true\n");
495+
} else {
496+
std::optional<std::string> optional_code_cache =
497+
GenerateCodeCache(config.main_path, main_script);
498+
if (!optional_code_cache.has_value()) {
499+
FPrintF(stderr, "Cannot generate V8 code cache\n");
500+
return ExitCode::kGenericUserError;
501+
}
502+
code_cache = optional_code_cache.value();
503+
optional_sv_code_cache = code_cache;
497504
}
498-
code_cache = optional_code_cache.value();
499-
optional_sv_code_cache = code_cache;
500505
}
501506

502507
SeaResource sea{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
const {
6+
injectAndCodeSign,
7+
skipIfSingleExecutableIsNotSupported,
8+
} = require('../common/sea');
9+
10+
skipIfSingleExecutableIsNotSupported();
11+
12+
// This tests "useCodeCache" is ignored when "useSnapshot" is true.
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const { copyFileSync, writeFileSync, existsSync } = require('fs');
16+
const { spawnSync } = require('child_process');
17+
const { join } = require('path');
18+
const assert = require('assert');
19+
20+
const configFile = join(tmpdir.path, 'sea-config.json');
21+
const seaPrepBlob = join(tmpdir.path, 'sea-prep.blob');
22+
const outputFile = join(tmpdir.path, process.platform === 'win32' ? 'sea.exe' : 'sea');
23+
24+
{
25+
tmpdir.refresh();
26+
const code = `
27+
const {
28+
setDeserializeMainFunction,
29+
} = require('v8').startupSnapshot;
30+
31+
setDeserializeMainFunction(() => {
32+
console.log('Hello from snapshot');
33+
});
34+
`;
35+
36+
writeFileSync(join(tmpdir.path, 'snapshot.js'), code, 'utf-8');
37+
writeFileSync(configFile, `
38+
{
39+
"main": "snapshot.js",
40+
"output": "sea-prep.blob",
41+
"useSnapshot": true,
42+
"useCodeCache": true
43+
}
44+
`);
45+
46+
let child = spawnSync(
47+
process.execPath,
48+
['--experimental-sea-config', 'sea-config.json'],
49+
{
50+
cwd: tmpdir.path
51+
});
52+
assert.match(
53+
child.stderr.toString(),
54+
/"useCodeCache" is redundant when "useSnapshot" is true/);
55+
56+
assert(existsSync(seaPrepBlob));
57+
58+
copyFileSync(process.execPath, outputFile);
59+
injectAndCodeSign(outputFile, seaPrepBlob);
60+
61+
child = spawnSync(outputFile);
62+
assert.strictEqual(child.stdout.toString().trim(), 'Hello from snapshot');
63+
}

0 commit comments

Comments
 (0)