node/test/parallel/test-code-cache.js
Joyee Cheung fbe1478077
bootstrap: include code cache in the embedded snapshot
Since V8 code cache encodes indices to the read-only space
it is safer to make sure that the code cache is generated in the
same heap used to generate the embdded snapshot. This patch
merges the code cache builder into the snapshot builder and
makes the code cache part of node::SnapshotData that is
deserialized into the native module loader during bootstrap.

PR-URL: https://github.com/nodejs/node/pull/43023
Fixes: https://github.com/nodejs/node/issues/31074
Refs: https://github.com/nodejs/node/issues/35711
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2022-05-17 20:38:11 +08:00

77 lines
2.4 KiB
JavaScript

// Flags: --expose-internals
'use strict';
// This test verifies that if the binary is compiled with code cache,
// and the cache is used when built in modules are compiled.
// Otherwise, verifies that no cache is used when compiling builtins.
const { isMainThread } = require('../common');
const assert = require('assert');
const {
internalBinding
} = require('internal/test/binding');
const {
getCacheUsage,
moduleCategories: { canBeRequired, cannotBeRequired }
} = internalBinding('native_module');
for (const key of canBeRequired) {
require(`node:${key}`);
}
// The computation has to be delayed until we have done loading modules
const {
compiledWithoutCache,
compiledWithCache,
compiledInSnapshot
} = getCacheUsage();
function extractModules(list) {
return list.filter((m) => m.startsWith('NativeModule'))
.map((m) => m.replace('NativeModule ', ''));
}
const loadedModules = extractModules(process.moduleLoadList);
// Cross-compiled binaries do not have code cache, verifies that the builtins
// are all compiled without cache and we are doing the bookkeeping right.
if (!process.features.cached_builtins) {
assert(!process.config.variables.node_use_node_code_cache ||
process.execArgv.includes('--no-node-snapshot'));
if (isMainThread) {
assert.deepStrictEqual(compiledWithCache, new Set());
for (const key of loadedModules) {
assert(compiledWithoutCache.has(key),
`"${key}" should've been compiled without code cache`);
}
} else {
// TODO(joyeecheung): create a list of modules whose cache can be shared
// from the main thread to the worker thread and check that their
// cache are hit
assert.notDeepStrictEqual(compiledWithCache, new Set());
}
} else { // Native compiled
assert(process.config.variables.node_use_node_code_cache);
if (!isMainThread) {
for (const key of [ 'internal/bootstrap/pre_execution' ]) {
canBeRequired.add(key);
cannotBeRequired.delete(key);
}
}
const wrong = [];
for (const key of loadedModules) {
if (cannotBeRequired.has(key) && !compiledWithoutCache.has(key)) {
wrong.push(`"${key}" should've been compiled **without** code cache`);
}
if (canBeRequired.has(key) &&
!compiledWithCache.has(key) &&
compiledInSnapshot.indexOf(key) === -1) {
wrong.push(`"${key}" should've been compiled **with** code cache`);
}
}
assert.strictEqual(wrong.length, 0, wrong.join('\n'));
}