6 ms·
I don't understand the "in-place binary patching" bit. Does it literally mean that the compiler opens the existing binary in a write-but-do-not truncate mode, l
by tom_mellior 6y ago
I don't understand the "in-place binary patching" bit. Does it literally mean that the compiler opens the existing binary in a write-but-do-not truncate mode, leaves most bits in place, and only changes others in certain places? Is this expected to be that much faster than writing the whole binary anew? What other benefits is this supposed to have? The article doesn't seem to say.
Also, how does this relate to the observation just above that "the right-most box is always invalidated ... the final executable is always re-linked from scratch ... since the final executable depends on everything else"? Does linking somehow get faster or easier with in-place patching?
- kristoff_it 6y ago> Does it literally mean that the compiler opens the existing binary in a write-but-do-not truncate mode, leaves most bits in place, and only changes others in certain places? Yes. > Does it literally mean that the compiler opens the existing binary in a write-but-do-not truncate mode, leaves most bits in place, and only changes others in certain places? I'm not an expert, but I believe the point is mostly about other computation required for "normal" linking, not just writing fewer bytes to disk. > What other benefits is this supposed to have? It makes the edit-compile-run loop faster when developing. > Does linking somehow get faster or easier with in-place patching? That's the idea. When code isn't position independent, moving a chunk of code requires recomputing a bunch of offsets, and similarly the linker needs to do more work when you don't have an indirect way of referring to functions etc.
- ikskuh 6y agoYes, you understood that right. The existing executable file is not written completly anew. And yes, it will be faster. The way Zig does this is by only recompiling and modifying the parts of the executable where the source has changed. Imagine a project like chromium, where your executable is 150 MB large. Now you change a single function. Classic linking would require the whole linking process and the write of 150 MB of code. Zig will only compile and patch a single function (when lucky: less than 1kB) and emit this. Less I/O, less overall work to do.
- tom_mellior 6y ago> Now you change a single function. Classic linking would require the whole linking process and the write of 150 MB of code. Zig will only compile and patch a single function (when lucky: less than 1kB) and emit this. I see, thanks. I think I was misled by the article's "the final executable depends on everything else and so any meaningful change to the code will invalidate it". My understanding now is that, since the Zig compiler knows exactly what has changed, unlike a traditional linker it will not invalidate the parts that haven't changed. Is that correct?
- dnautics 6y ago> the final executable depends on everything else and so any meaningful change to the code will invalidate it If I'm not mistaken that refers to in traditional compiled languages.
- rictic 6y agoWhat if the machine code for the function is larger after than before? I guess even worst case, writing 151MB to disk is fast if you have the data ready. Very fast with a modern SSD.
- AndyKelley 6y agoThis is a fascinating topic that I hope to follow up with a more technical blog post. The short summary is that there is room for functions to grow, and if they still exceed the padding, they get moved around to a new location in both virtual memory and in the file. Because of indirect function calls this means callsites remain the same; only the GOT entry has to get updated. The actual function body is moved with the copy_file_range syscall, where available.
- alexnask 6y agoYes, the compiler will open the binary and only emit modified/new code and possibly change some values in a global offset table. As noted in the article, the same strategy will be used for hot code swapping, which is one of the benefits of doing this. This is indeed faster than generating new object files and relinking the whole executable. The video linked in the article shows a simple example with the current ELF incremental linker, where compiling the example program takes 1.5 ms while changing a string literal and updating the executable takes about 0.5 ms
- AndyKelley 6y ago> Does linking somehow get faster or easier with in-place patching? Check out that 5 min demo video! I think it's pretty exciting.
- bigbizisverywyz 6y agoGlad you asked that question, I was wondering the same - and good answers. I guess this is all in the pursuit of reducing link time, but a clean build will write the whole binary from scratch in a more compressed way?