mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
This patch makes it possible to generate the code cache for the builtins directly from the original script object (instead of compiling a new one) and after the script has been run (via `NativeModule.require`). Before this patch only the top level functions (the wrapped ones) are included in the cache, after this patch the inner functions in those modules will be included as well. Also blacklists modules from dependencies like V8 and node-inspect since we cannot guarantee that they are suitable to be executed directly. PR-URL: https://github.com/nodejs/node/pull/21567 Refs: https://github.com/nodejs/node/issues/21563 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
114 lines
3.2 KiB
JavaScript
114 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
// Flags: --expose-internals
|
|
|
|
// This file generates the code cache for builtin modules and
|
|
// writes them into static char arrays of a C++ file that can be
|
|
// compiled into the binary using the `--code-cache-path` option
|
|
// of `configure`.
|
|
|
|
const {
|
|
getCodeCache,
|
|
cachableBuiltins
|
|
} = require('internal/bootstrap/cache');
|
|
|
|
const fs = require('fs');
|
|
|
|
const resultPath = process.argv[2];
|
|
if (!resultPath) {
|
|
console.error(`Usage: ${process.argv[0]} ${process.argv[1]}` +
|
|
'path/to/node_code_cache.cc');
|
|
process.exit(1);
|
|
}
|
|
|
|
/**
|
|
* Format a number of a size in bytes into human-readable strings
|
|
* @param {number} num
|
|
* @return {string}
|
|
*/
|
|
function formatSize(num) {
|
|
if (num < 1024) {
|
|
return `${(num).toFixed(2)}B`;
|
|
} else if (num < 1024 ** 2) {
|
|
return `${(num / 1024).toFixed(2)}KB`;
|
|
} else if (num < 1024 ** 3) {
|
|
return `${(num / (1024 ** 2)).toFixed(2)}MB`;
|
|
} else {
|
|
return `${(num / (1024 ** 3)).toFixed(2)}GB`;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates the source code of definitions of the char arrays
|
|
* that contains the code cache and the source code of the
|
|
* initializers of the code cache.
|
|
*
|
|
* @param {string} key ID of the builtin module
|
|
* @param {Buffer} cache Code cache of the builtin module
|
|
* @return { definition: string, initializer: string }
|
|
*/
|
|
function getInitalizer(key, cache) {
|
|
const defName = key.replace(/\//g, '_').replace(/-/g, '_');
|
|
const definition = `static uint8_t ${defName}_raw[] = {\n` +
|
|
`${cache.join(',')}\n};`;
|
|
const initializer = `
|
|
v8::Local<v8::ArrayBuffer> ${defName}_ab =
|
|
v8::ArrayBuffer::New(isolate, ${defName}_raw, ${cache.length});
|
|
v8::Local<v8::Uint8Array> ${defName}_array =
|
|
v8::Uint8Array::New(${defName}_ab, 0, ${cache.length});
|
|
target->Set(context,
|
|
FIXED_ONE_BYTE_STRING(isolate, "${key}"),
|
|
${defName}_array).FromJust();
|
|
`;
|
|
return {
|
|
definition, initializer
|
|
};
|
|
}
|
|
|
|
const cacheDefinitions = [];
|
|
const cacheInitializers = [];
|
|
let totalCacheSize = 0;
|
|
|
|
|
|
for (const key of cachableBuiltins) {
|
|
const cachedData = getCodeCache(key);
|
|
if (!cachedData.length) {
|
|
console.error(`Failed to generate code cache for '${key}'`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const length = cachedData.length;
|
|
totalCacheSize += length;
|
|
const { definition, initializer } = getInitalizer(key, cachedData);
|
|
cacheDefinitions.push(definition);
|
|
cacheInitializers.push(initializer);
|
|
console.log(`Generated cache for '${key}', size = ${formatSize(length)}` +
|
|
`, total = ${formatSize(totalCacheSize)}`);
|
|
}
|
|
|
|
const result = `#include "node.h"
|
|
#include "node_code_cache.h"
|
|
#include "v8.h"
|
|
#include "env.h"
|
|
#include "env-inl.h"
|
|
|
|
// This file is generated by tools/generate_code_cache.js
|
|
// and is used when configure is run with \`--code-cache-path\`
|
|
|
|
namespace node {
|
|
|
|
${cacheDefinitions.join('\n\n')}
|
|
|
|
// The target here will be returned as \`internalBinding('code_cache')\`
|
|
void DefineCodeCache(Environment* env, v8::Local<v8::Object> target) {
|
|
v8::Isolate* isolate = env->isolate();
|
|
v8::Local<v8::Context> context = env->context();
|
|
${cacheInitializers.join('\n')}
|
|
}
|
|
|
|
} // namespace node
|
|
`;
|
|
|
|
fs.writeFileSync(resultPath, result);
|
|
console.log(`Generated code cache C++ file to ${resultPath}`);
|