[PATCH] D47092: downgrade strong type info names to weak_odr linkage

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri May 18 19:27:49 PDT 2018


rjmccall added inline comments.


================
Comment at: test/CodeGenCXX/arm64.cpp:48
   void A::foo() {}
-  // CHECK-GLOBALS-DAG: @_ZTSN5test21AE = constant [11 x i8]
+  // CHECK-GLOBALS-DAG: @_ZTSN5test21AE = weak_odr constant [11 x i8]
   // CHECK-GLOBALS-DAG: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) }
----------------
rsmith wrote:
> rjmccall wrote:
> > The way the Darwin ARM64 ABI handles non-unique RTTI is by setting a flag indicating that clients should do string comparisons/hashes; it does not rely on the type name symbols being uniqued.  So this should stay external and the _ZTI definition should change to set the bit.
> OK. I was trying to avoid introducing more cases where we do string comparisons, but if you prefer string comparisons over link-time deduplication in all cases for that target, that seems easy enough to support.
> 
> (Out of curiosity, does the link-time deduplication not reliably work on that platform? If so, how do you deal with the other cases that require deduplication? If not, what's the motivation for using string comparisons?)
Static and dynamic linking work the same on ARM64 as on any other Mach-O platform.  As you say, there are language features that depend on symbols resolving to the same object; we haven't changed that.  The issue is that, while deduplication in the *static* linker is great, deduplication in the *dynamic* linker means extra, unavoidable work at load time — mostly, paging in a bunch of data from the symbol table.  For an implicitly-activated language feature like RTTI, that can add up to a lot of overhead, which hits you regardless of whether you actually ever use any of the language features that depend on it.  On Darwin we really like dynamic libraries, and we really like processes to launch quickly.  So the ARM64 ABI says that RTTI which would otherwise need to be potentially deduplicated across a dynamic-library boundary (because the type is external and not hidden) is instead hidden and must be compared using the string data — a classic load-time vs. execution-time trade-off, in this case easy to make because the features that depend on dynamic type matching are rarely used and generally slow anyway.

The GCC type_info ABI uses string comparisons for a completely different purpose: they assume that users can't be trusted to mark visibility correctly on types, so they use string comparisons as a fallback.  Darwin ARM64 is still as strict about type visibility as we are on every other platform, so if you use -fvisibility=hidden and forget to mark a type as visible, dynamic_cast and EH will fail across library boundaries.

It occurs to me that all this might be unnecessary, though:

1. It's never possible to ask for the `type_info` of an incomplete class type directly.
2. The features that use RTTI which can actually do pointer conversions don't allow pointers to incomplete class types, either — at best, you can have pointers-to-pointers.
3. As far as I know, none of those features would ever depend on the pointee type_info object of a pointer-to-pointer.  For example, you cannot do a `dynamic_cast` from a `Base**` to a `Derived**`.  They only care about the direct pointee type, which cannot be incomplete.
4. I think the only feature that allows a pointer to an incomplete class type is `typeid`.
5. None of the standard operations on a `type_info` actually cares about the pointee `type_info`.  They care about the name symbol for the pointer type, but that already has to be deduplicated (modulo the ARM64 trick) because we don't eagerly emit RTTI for pointer types.
6. You can get at the pointee `type_info` with the `cxxabi.h` interface, but I would argue that we should not make the ABI worse solely for the benefit of clients of the `cxxabi.h` interface, especially in a corner case of a corner case (a pointer to an incomplete type which would have turned out to be a dynamic class with a key function).
7. So I think we could actually get away with always using internal linkage for the ZTSes of incomplete class types, as long as we continue to use the standard rule for the ZTSes of *pointers* to incomplete class types, because the only thing that would break would be the `cxxabi.h` interface.
8. And if we find a way to convince LLVM / ASan to let us use weak linkage even if there might also be a strong definition out there, we don't even have that problem long-term.


Repository:
  rC Clang

https://reviews.llvm.org/D47092





More information about the cfe-commits mailing list