Store sharer and eraser in function prefix
This reduces the size of frame headers for faster PushFrame/Return. Non-linear handlers get slower though, because now there is an additional indirection for sharers/erasers.
I also moved vtables to function prefixes. This removes one indirection for the first operator of an object.
Here are some benchmark results:
How does this lead to an additional indirection? I would have assumed it would just be an additional offset computation.
Previously it was: Load stack pointer -> add offset -> load sharer address
Now it is: Load stack pointer -> add offset -> load return address -> add offset -> load sharer address
Hmm... I expected it to be
Load stack pointer -> add offset -> load return address -> add offset
but maybe my mental model of how LLVM works is just off here, or you implemented a different variant than I had in mind (where the sharers and erasers are always placed at a particular offset of the return address in code).
I didn't see an easy way to place functions relative to each other. I placed function pointers relative to the return address.
ok, then the additional indirection makes sense, thanks for the explanation
Is there a way to make the linker happy?
This should be ready now. It turns out the linker doesn't like pie :) Do we want to give up on position independence though?
Are the benchmark results from above still up to date?
What are the most important down sides in your opinion of giving up position independence?
Updated benchmarks:
I don't know really know about the downsides. According to claude, there are some security vulnerabilities with position dependence. There might also be issues if we ever want to compile to shared libraries.
Without -no-pie the linker complains, but the tests still succeed.
/usr/bin/ld: /tmp/lto-llvm-1c61d0.o: warning: relocation in read-only section `.text.returnAddress_1616'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE