diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/generate_code_cache.js | 124 | ||||
-rwxr-xr-x | tools/test.py | 1 |
2 files changed, 125 insertions, 0 deletions
diff --git a/tools/generate_code_cache.js b/tools/generate_code_cache.js new file mode 100644 index 0000000000..8aab6bc286 --- /dev/null +++ b/tools/generate_code_cache.js @@ -0,0 +1,124 @@ +'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 { + nativeModuleWrap, + builtinSource, + cannotUseCache +} = require('internal/bootstrap/cache'); + +const vm = require('vm'); +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 Object.keys(builtinSource)) { + if (cannotUseCache.includes(key)) continue; + const code = nativeModuleWrap(builtinSource[key]); + + // Note that this must corresponds to the code in + // NativeModule.prototype.compile + const script = new vm.Script(code, { + filename: `${key}.js`, + produceCachedData: true + }); + + if (!script.cachedData) { + console.error(`Failed to generate code cache for '${key}'`); + process.exit(1); + } + + const length = script.cachedData.length; + totalCacheSize += length; + const { definition, initializer } = getInitalizer(key, script.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}`); diff --git a/tools/test.py b/tools/test.py index 5bda606cc8..c963196c69 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1549,6 +1549,7 @@ def PrintCrashed(code): IGNORED_SUITES = [ 'addons', 'addons-napi', + 'code-cache', 'doctool', 'gc', 'internet', |