Files
node/test/embedding/test-embedding-builtin-code-cache-harvest.js
T
Shelley Vohr 26bd28cbdb src: let embedders supply a builtin code cache without a snapshot
Environments created from the built-in snapshot get the builtins' code
cache from that snapshot. An embedder that bootstraps an Environment
from scratch (its own isolate and context, no EmbedderSnapshotData) has
no way to provide one: every builtin the bootstrap touches is compiled
from source in every such process, and each of them then serializes a
fresh cache (SaveCodeCache) that only a later worker thread would ever
consume.

Add node::EmbedderBuiltinCodeCache for that case. Its entries pair a
builtin id with a v8::ScriptCompiler::CachedData; Generate(context)
compiles every builtin in a context of the right kind of isolate and
returns them for a build step to embed, and
SetBuiltinCodeCache(isolate_data, cache) attaches them to an
IsolateData, next to where a snapshot's code cache lives, so that every
Environment created from it afterwards starts with them. The setter
runs CachedData::CompatibilityCheck() against the isolate first and
returns the result, leaving the IsolateData untouched for a cache made
with another V8 version, flag set or read-only snapshot. Entries from a
snapshot still merge with it (RefreshCodeCache() now merges instead of
assuming a single call). CreateEnvironment() plus LoadEnvironment() of
an empty script goes from about 38 ms to 13 ms with a cache attached.

ProcessInitializationFlags::kNoHarvestBuiltinCodeCache stops
serializing caches for builtins compiled without one, for embedders
that supply their own or never create workers. The default is
unchanged because worker threads copy the harvested cache.

A cctest generates a cache, attaches it, checks that a new
Environment's bootstrap compiles from it and that a corrupted cache is
refused; embedtest gains --no-harvest-builtin-code-cache for a test
that a worker does or does not find a harvested cache depending on the
flag.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65352
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-09-02 14:04:24 +00:00

26 lines
1.1 KiB
JavaScript

'use strict';
// By default a builtin compiled without a code cache serializes one that worker
// threads then start from; with kNoHarvestBuiltinCodeCache it does not.
const common = require('../common');
const tmpdir = require('../common/tmpdir');
const assert = require('assert');
const { spawnSyncAndAssert } = require('../common/child_process');
tmpdir.refresh();
const embedtest = common.resolveBuiltBinary('embedtest');
const workerScript = 'new (require("worker_threads").Worker)("", { eval: true })';
function workerCompileLog(args) {
let log;
spawnSyncAndAssert(
embedtest, ['--', ...args, workerScript],
{ cwd: tmpdir.path, env: { ...process.env, NODE_DEBUG_NATIVE: 'CODE_CACHE' } },
{ stderr(output) { log = output; return true; } });
const worker = log.slice(log.lastIndexOf('Compiling internal/bootstrap/realm'));
assert.notStrictEqual(worker, log);
return worker;
}
assert.match(workerCompileLog([]), /Code cache of internal\/bootstrap\/node \(\w+\) is accepted/);
assert.match(workerCompileLog(['--no-harvest-builtin-code-cache']),
/Compiling internal\/bootstrap\/node without code cache/);