-
-
Couldn't load subscription status.
- Fork 15
Description
See the discussion in nodejs/node#47741.
Measurements of injecting a 4KB resource into a Mach-O binary on an x86_64 macOS with Node.js v20.1.0:
-
Loading the Emscripten-generated script (https://github.com/emscripten-core/emscripten/blob/90d76db21200d42f5536bc3a01a22303e398d8b4/src/shell.js, https://github.com/emscripten-core/emscripten/blob/90d76db21200d42f5536bc3a01a22303e398d8b4/src/preamble.js, etc.):
Line 25 in 2481868
const postject = await loadPostjectModule();
takes ~50ms. -
Getting the executable format -
takes ~14ms for a 60KB hello-world executable. For the Node.js binary, which is 94MB, it takes ~13s.Line 32 in 2481868
const executableFormat = postject.getExecutableFormat(executable); - For injecting into large binaries like Node.js, , is the bottleneck here as it takes ~13s.
Line 24 in 2481868
std::vector<uint8_t> buffer = vec_from_val(executable);
- For injecting into large binaries like Node.js,
-
Injecting the resource -
takes ~35ms for a 60KB hello-world executable. For the Node.js binary, which is 94MB, it takes ~20s.Lines 53 to 59 in 2481868
({ result, data } = postject.injectIntoMachO( executable, machoSegmentName, sectionName, resourceData, overwrite )); - For injecting into large binaries like Node.js, just the
vec_from_valcall in, is one of the bottlenecks here as it takes ~12s.Line 96 in 2481868
LIEF::MachO::Parser::parse(vec_from_val(executable)); - The
parsecall intakes ~3s.Line 96 in 2481868
LIEF::MachO::Parser::parse(vec_from_val(executable)); - The remaining code takes ~2s.
- For injecting into large binaries like Node.js, just the
TLDR -
Lines 16 to 21 in 2481868
| std::vector<uint8_t> vec_from_val(const emscripten::val& value) { | |
| // TODO(dsanders11) - vecFromJSArray incurs a copy, so memory usage is higher | |
| // than it needs to be. Explore ways to access the memory | |
| // directly and avoid the copy. | |
| return emscripten::vecFromJSArray<uint8_t>(value); | |
| } |
Replacing the emscripten::vecFromJSArray<uint8_t>(value) call at
Line 20 in 2481868
| return emscripten::vecFromJSArray<uint8_t>(value); |
emscripten::vecFromJSArray<uint8_t>(value) reduces the time consumption from ~30s to ~6s.