Improved dynamic linking ABIs
Improved dynamic linking ABIs
Posted Feb 21, 2025 22:43 UTC (Fri) by ras (subscriber, #33059)In reply to: Improved dynamic linking ABIs by farnz
Parent article: Rewriting essential Linux packages in Rust
I'm not an expert, but I'm guessing there are 3 things Vec has to know. Yes the size of an element and the capacity are two. The current length doesn't count because it's not encoded in the type. Neither of those two are particularly problematic.
The 3rd is one you didn't mention: drop. That is more difficult. C++ would use a vtable, which alters the binary format of the element. The alternative solution is embed a pointer to the items drop in the Vec along with the capacity and element length. I don't know Rust well enough to know if it can do that. Well, I'm sure it can with some helper macros but's that an admission the language doesn't support it well.
> For Vec, crABI is unlikely to give up much performance
Actually, the big speed gains from monomorphization come from small types. Consider Vec.get() for Vec<u32>. If get() doesn't know the length it's probably going to be implemented using memcpy(), but memcpy() is orders of magnitude slower than "mov %rax,nnn(%rbp,%rdx)". But if the u32 was a much bigger type the overhead imposed by implementing get() as a function that uses memcpy() rather than inline becomes tolerable.
That hints to the solution you see in C and C++: you need a mixture of monomorphization and shared libraries. C and C++ can do that with inline. For that to work you need separate .h, .c and .o (compiler output). Or perhaps the required information gets folded into the .o. In any case, the compiler gets two sorts of information from the library: the compiled code which can potentially be put in a dynamic library, and the parts the library author thinks need to be monomorphized like for speed, like Vec.get().
Rust has effectively dropped that separation. No one uses binary libraries because it's too hard . The result is everything is monomorphized. But is reality, in a large library the bits that need to be monomorphized for speed are a very small percentage of the code. Given most Rust code a typical Rust program uses comes from these large libraries (interestingly the kernel will be a notable exception), this blows up the complied time of most small programs enormously. It also thawrts the current Linux distributions practice of fixing security holes in libraries by just shipping a new version of the .so. Now they have to ship every program that depends on it. As I said, on my laptop that means every time libc.so has a bug, I'd have to reinstall over 2,000 programs.
I consider this a major wart in the language. But as I said, it likely won't effect the kernel.
