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



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to