quick jump to the end of executable image - reduces load time by 100ms
This commit is contained in:
parent
76c90cc24b
commit
4b7206f032
@ -348,7 +348,7 @@
|
||||
|
||||
--- node/src/node_javascript.cc
|
||||
+++ node/src/node_javascript.cc
|
||||
@@ -31,8 +31,58 @@
|
||||
@@ -31,8 +31,59 @@
|
||||
env->isolate(), reinterpret_cast<const char*>(native.source),
|
||||
NewStringType::kNormal, native.source_len).ToLocalChecked();
|
||||
target->Set(name, source);
|
||||
@ -359,7 +359,7 @@
|
||||
+ auto source = String::NewFromUtf8(env->isolate(),
|
||||
+ "var fs = require('fs');\n" \
|
||||
+ "var vm = require('vm');\n" \
|
||||
+ "function readPayload() {\n" \
|
||||
+ "function readPayload (fd) {\n" \
|
||||
+ " var position = process.env.PKG_PAYLOAD_POSITION;\n" \
|
||||
+ " if (position === undefined) {\n" \
|
||||
+ " // no payload - remove entrypoint from argv[1]\n" \
|
||||
@ -376,13 +376,11 @@
|
||||
+ " delete process.env.PKG_PAYLOAD_POSITION;\n" \
|
||||
+ " delete process.env.PKG_PAYLOAD_SIZE;\n" \
|
||||
+ " var cd = new Buffer(size);\n" \
|
||||
+ " var me = fs.openSync(process.execPath, 'r');\n" \
|
||||
+ " var read = fs.readSync(me, cd, 0, size, position);\n" \
|
||||
+ " var read = fs.readSync(fd, cd, 0, size, position);\n" \
|
||||
+ " if (read !== size) {\n" \
|
||||
+ " console.error('Pkg: Error reading from file.');\n" \
|
||||
+ " process.exit(1);\n" \
|
||||
+ " }\n" \
|
||||
+ " fs.closeSync(me);\n" \
|
||||
+ " var s = new vm.Script(undefined, {\n" \
|
||||
+ " cachedData: cd,\n" \
|
||||
+ " sourceless: true\n" \
|
||||
@ -394,14 +392,17 @@
|
||||
+ " var fn = s.runInThisContext();\n" \
|
||||
+ " return fn(process, require, console);\n" \
|
||||
+ "}\n" \
|
||||
+ "\n" \
|
||||
+ "var r = readPayload();\n" \
|
||||
+ "if (!r || r.undoPatch) {\n" \
|
||||
+ " // need to revert patch to node/lib/module.js\n" \
|
||||
+ " var bindingFs = process.binding('fs');\n" \
|
||||
+ " fs.internalModuleStat = bindingFs.internalModuleStat;\n" \
|
||||
+ " fs.internalModuleReadFile = bindingFs.internalModuleReadFile;\n" \
|
||||
+ "}\n"
|
||||
+ "(function () {\n" \
|
||||
+ " var fd = fs.openSync(process.execPath, 'r');\n" \
|
||||
+ " var r = readPayload(fd);\n" \
|
||||
+ " fs.closeSync(fd);\n" \
|
||||
+ " if (!r || r.undoPatch) {\n" \
|
||||
+ " // need to revert patch to node/lib/module.js\n" \
|
||||
+ " var bindingFs = process.binding('fs');\n" \
|
||||
+ " fs.internalModuleStat = bindingFs.internalModuleStat;\n" \
|
||||
+ " fs.internalModuleReadFile = bindingFs.internalModuleReadFile;\n" \
|
||||
+ " }\n" \
|
||||
+ "}())\n"
|
||||
+ );
|
||||
+ target->Set(name, source);
|
||||
}
|
||||
@ -409,13 +410,48 @@
|
||||
} // namespace node
|
||||
--- node/src/node_main.cc
|
||||
+++ node/src/node_main.cc
|
||||
@@ -1,7 +1,175 @@
|
||||
@@ -1,7 +1,208 @@
|
||||
#include "node.h"
|
||||
|
||||
+#include <string.h>
|
||||
+
|
||||
+#define BOUNDARY 4096
|
||||
+
|
||||
+int FindMeatEnd(FILE* file) {
|
||||
+
|
||||
+ int read;
|
||||
+ uint8_t buffer[1024];
|
||||
+ uint16_t* buffer16 = (uint16_t*) &buffer;
|
||||
+ uint32_t* buffer32 = (uint32_t*) &buffer;
|
||||
+
|
||||
+ if (fseek(file, 0, SEEK_SET) != 0) return 0;
|
||||
+ read = static_cast<int>(fread(&buffer, 1, sizeof(buffer), file));
|
||||
+ if (read != sizeof(buffer)) return 0;
|
||||
+
|
||||
+ if (buffer16[0 >> 1] == 0x5A4D) { // _IMAGE_DOS_HEADER.e_magic == MZ
|
||||
+
|
||||
+ uint32_t e_lfanew = buffer32[0x3c >> 2];
|
||||
+ uint16_t NumberOfSections = buffer16[(e_lfanew + 0x04 + 0x02) >> 1];
|
||||
+ uint16_t SizeOfOptionalHeader = buffer16[(e_lfanew + 0x04 + 0x10) >> 1];
|
||||
+ uint16_t Section = e_lfanew + 0x18 + SizeOfOptionalHeader;
|
||||
+
|
||||
+ uint32_t MaxEnd = 0;
|
||||
+ for (int i = 0; i < NumberOfSections; i += 1) {
|
||||
+ uint32_t RawOffset = buffer32[(Section + 0x14) >> 2];
|
||||
+ uint32_t RawSize = buffer32[(Section + 0x10) >> 2];
|
||||
+ uint32_t RawEnd = RawOffset + RawSize;
|
||||
+ if (RawEnd > MaxEnd) MaxEnd = RawEnd;
|
||||
+ Section += 0x28;
|
||||
+ }
|
||||
+
|
||||
+ return (MaxEnd / BOUNDARY) * BOUNDARY;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 6 * 1024 * 1024;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+bool GetSentryPosition(FILE* file, int start, uint32_t s1,
|
||||
+ uint32_t s12, uint32_t s3, int* pposition, int* psize
|
||||
+) {
|
||||
@ -423,10 +459,7 @@
|
||||
+ int read;
|
||||
+ uint32_t sentry, length;
|
||||
+
|
||||
+ // start of search
|
||||
+ if (file == NULL || fseek(file, start, SEEK_SET) != 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (fseek(file, start, SEEK_SET) != 0) return false;
|
||||
+
|
||||
+ while (true) {
|
||||
+ read = static_cast<int>(fread(&sentry, 1, sizeof(sentry), file));
|
||||
@ -456,6 +489,13 @@
|
||||
+}
|
||||
+
|
||||
+
|
||||
+#ifdef _WIN32
|
||||
+void setenv(const char* name, const char* value, int overwrite) {
|
||||
+ SetEnvironmentVariable(name, value);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+char* ReadOverlays(const char* filename) {
|
||||
+
|
||||
+ FILE* file = fopen(filename, "rb");
|
||||
@ -464,7 +504,8 @@
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ int position = 6 * 1024 * 1024; int size;
|
||||
+ char env[64];
|
||||
+ int position = FindMeatEnd(file); int size;
|
||||
+ char* bakery = NULL;
|
||||
+
|
||||
+ if (GetSentryPosition(file, position, 0x4818c4df,
|
||||
@ -478,6 +519,7 @@
|
||||
+ read = static_cast<int>(fread(&bakery[i], 1, size - i, file));
|
||||
+ if (ferror(file) != 0) {
|
||||
+ fprintf(stderr, "Pkg: Error reading from file.\n");
|
||||
+ fclose(file);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ i += read;
|
||||
@ -491,22 +533,14 @@
|
||||
+ 0x6713e24e, 0x3ea13ccf, &position, &size)
|
||||
+ ) {
|
||||
+
|
||||
+ char value[64];
|
||||
+ sprintf(value, "%d", position);
|
||||
+#ifdef _WIN32
|
||||
+ SetEnvironmentVariable("PKG_PAYLOAD_POSITION", value);
|
||||
+#else
|
||||
+ setenv("PKG_PAYLOAD_POSITION", value, 1);
|
||||
+#endif
|
||||
+ sprintf(value, "%d", size);
|
||||
+#ifdef _WIN32
|
||||
+ SetEnvironmentVariable("PKG_PAYLOAD_SIZE", value);
|
||||
+#else
|
||||
+ setenv("PKG_PAYLOAD_SIZE", value, 1);
|
||||
+#endif
|
||||
+ sprintf(env, "%d", position);
|
||||
+ setenv("PKG_PAYLOAD_POSITION", env, 1);
|
||||
+ sprintf(env, "%d", size);
|
||||
+ setenv("PKG_PAYLOAD_SIZE", env, 1);
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ fclose(file);
|
||||
+ return bakery;
|
||||
+
|
||||
+}
|
||||
@ -585,7 +619,7 @@
|
||||
|
||||
int wmain(int argc, wchar_t *wargv[]) {
|
||||
if (!IsWindows7OrGreater()) {
|
||||
@@ -43,17 +211,17 @@
|
||||
@@ -43,17 +244,17 @@
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user