ckennelly
If `rseq_cs` is no longer describing a relevant address, that is, the program counter has moved past it, the kernel just ignores it.
The code is executed by a single thread. Everything retires in program order. There is no need for a memory barrier between starting the critical section and its body.
Optimizing Optimization
* libstdc++ has an internal reference to its own address for the SSO. If the moved-from string was referencing its SSO buffer, the moved-to string needs to use its own address. The branch is differentiating the SSO state from a heap-allocated state.
* libc++ string move can be implemented this way, but the branch ends up happening on access to the string. It still needs to discard the old heap allocated buffer, if need-be as well.
Beware Microbenchmarks Bearing Gifts
On a stock kernel, it's 511. TCMalloc's docs recommend using max_ptes_none set to 0 for this reason: https://github.com/google/tcmalloc/blob/master/docs/tuning.m...
(Disclosure: I work on TCMalloc and authored the above doc.)
While there are still startup costs, the overhead of calling a function (especially via a PLT) and incurring instruction cache misses is hard to demonstrate in a microbenchmark, while rep movsb encodes more compactly than many flavors of call. In an actual application though, the "slower" but smaller implementation can often win (https://research.google/pubs/pub50338.pdf and https://research.google/pubs/pub48320.pdf)
Independent of inlining (with LTO, since the C++ language rules requires inhibit optimizing out "operator new"), the static call is far simpler.
"Profiling a warehouse-scale computer" (by S. Kanev, et. al.) showed several % of CPU usage allocating and deallocating memory. While a malloc and free does have some data dependencies, the indirect jump (by dynamically linking) is an avoidable cost on the critical path by statically linking.
gperftools includes a decade+ old copy of TCMalloc and several other things (a signal-based CPU profiler, a heap checker, etc.). The two have diverged significantly.
Announcing TCMalloc
To excerpt the most recent (8:14PM EDT) NYC office's discussion:
"As a result, expect most precipitation to be focused mainly during the evening hours. Hi-resolution models have been suggesting that the overnight hours could be mainly if not entirely dry. This is due to 850 hPa warm front lifting to the north by around 6z and a dry slot moving in from the SW (DC/PHI area). For now, have just lowered pops to chance. If trends in the high resolution models hold, pops will need to be lowered further if not removed for the overnight hours with future updates."
To go through your points:
* If the "wrong" GPG binary is loaded, the game is likely already up: If an attacker has that degree of control over your machine, they're already on the other side of this airtight hatchway. They can attach to your running programs, read memory contents, and so forth, so compromising the GPG binary isn't necessary.
* Keys are handled by GPG, which normally should mlock key material.
* Part of my plan to switch to handling pages (rather than allowing data to be managed via a std::string) was to be able to use mlock() properly. I'll be adding that soon.
* Since the GPG binary is running as you, it could do Bad Things to the underlying filesystem (or filesystem exported by FUSE), but you do raise a point about closing file descriptors for general cleanliness.