summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/generate_code_cache.js124
-rwxr-xr-xtools/test.py1
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',