Mark some std::string functions noinline. (#72869)
The intent of these particular functions, since their introduction, was to NOT be inlinable. However, the mechanism by which this was accomplished was non-obvious, and stopped working when string is compiled for C++20. A longstanding behavior specified by the C++ standard is that instantiation of the body of a template function is suppressed by an extern template declaration -- unless the function is explicitly marked either constexpr or inline. Of course, if the body is not instantiated, then it cannot possibly be inlined, and thus all the functions listed in libcxx/include/__string/extern_template_lists.h were uninlineable. But, in C++20 mode, string functions were annotated constexpr, which means they _are_ instantiated, and do become inlineable. And, in fact, they do get inlined, which has caused noticeable binary-size growth for users. For example, in C++17, `std::string f(std::string *in) { return *in; }` does not inline the copy-constructor call, and instead generates a call to the exported function defined in the libc++ shared library. I think we probably don't want to mark all functions that are currently in the extern template list as noinline, as many of them really are reasonable inlining candidates. Thus, I've restricted this change to only the few functions that were clearly intended to be outlined. See commits like b019c5c0 (and some others like it) for background, in which functions were removed from the extern template list in the unstable ABI in order to allow the short-string case to be inlined, while moving the long-string case to a separate function, added to the extern template list.
Loading
Please sign in to comment