[libcxx] r205139 - ARM64: compare RTTI names as strings
Dmitri Gribenko
gribozavr at gmail.com
Sun Mar 30 07:18:36 PDT 2014
On Sun, Mar 30, 2014 at 12:34 PM, Tim Northover <tnorthover at apple.com> wrote:
> Author: tnorthover
> Date: Sun Mar 30 06:34:26 2014
> New Revision: 205139
>
> URL: http://llvm.org/viewvc/llvm-project?rev=205139&view=rev
> Log:
> ARM64: compare RTTI names as strings
>
> ARM64 generates RTTI with hidden visibility, which means that typeinfo
> must be compared char-by-char since it's not guaranteed to be uniqued
> across the whole program.
>
> Modified:
> libcxx/trunk/include/__config
> libcxx/trunk/include/typeinfo
>
> Modified: libcxx/trunk/include/__config
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=205139&r1=205138&r2=205139&view=diff
> ==============================================================================
> --- libcxx/trunk/include/__config (original)
> +++ libcxx/trunk/include/__config Sun Mar 30 06:34:26 2014
> @@ -568,6 +568,10 @@ template <unsigned> struct __static_asse
> #define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
> #endif
>
> +#if __APPLE__ && defined(__LP64__) && !defined(__x86_64__)
> +#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63)
> +#endif
> +
> #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
> #define _LIBCPP_LOCALE__L_EXTENSIONS 1
> #endif
>
> Modified: libcxx/trunk/include/typeinfo
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/typeinfo?rev=205139&r1=205138&r2=205139&view=diff
> ==============================================================================
> --- libcxx/trunk/include/typeinfo (original)
> +++ libcxx/trunk/include/typeinfo Sun Mar 30 06:34:26 2014
> @@ -60,6 +60,7 @@ public:
> #include <__config>
> #include <exception>
> #include <cstddef>
> +#include <cstdint>
>
> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
> #pragma GCC system_header
> @@ -73,32 +74,83 @@ class _LIBCPP_EXCEPTION_ABI type_info
> type_info& operator=(const type_info&);
> type_info(const type_info&);
> protected:
> +#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
> const char* __type_name;
> +#else
> + // A const char* with the non-unique RTTI bit possibly set.
> + uintptr_t __type_name;
> +#endif
>
> _LIBCPP_INLINE_VISIBILITY
> explicit type_info(const char* __n)
> +#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
> : __type_name(__n) {}
> +#else
> + : __type_name(reinterpret_cast<uintptr_t>(__n)) {}
> +#endif
>
> public:
> virtual ~type_info();
>
> _LIBCPP_INLINE_VISIBILITY
> - const char* name() const _NOEXCEPT {return __type_name;}
> + const char* name() const _NOEXCEPT
> +#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
> + {return __type_name;}
> +#else
> + {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}
> +#endif
>
> _LIBCPP_INLINE_VISIBILITY
> bool before(const type_info& __arg) const _NOEXCEPT
> +#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
> {return __type_name < __arg.__type_name;}
> +#else
> + {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
> + return __type_name < __arg.__type_name;
> + return __compare_nonunique_names(__arg) < 0;}
> +#endif
> +
> _LIBCPP_INLINE_VISIBILITY
> size_t hash_code() const _NOEXCEPT
> +#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
> {return *reinterpret_cast<const size_t*>(&__type_name);}
I know this code was there before, but it looks like there is an
aliasing violation. It would be better phrased as:
return reinterpret_cast<size_t>(__type_name);
> +#else
> + {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
> + const char *__ptr = __name_for_load();
> + size_t __hash = 5381;
> + while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
> + __hash = (__hash * 33) ^ __c;
> + return __hash;}
> +#endif
>
> _LIBCPP_INLINE_VISIBILITY
> bool operator==(const type_info& __arg) const _NOEXCEPT
> +#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
> {return __type_name == __arg.__type_name;}
> +#else
> + {if (__type_name == __arg.__type_name) return true;
> + if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
> + return false;
> + return __compare_nonunique_names(__arg) == 0;}
> +#endif
> _LIBCPP_INLINE_VISIBILITY
> bool operator!=(const type_info& __arg) const _NOEXCEPT
> {return !operator==(__arg);}
>
> +#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
> + private:
> + _LIBCPP_INLINE_VISIBILITY
> + int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
> + {return __builtin_strcmp(__name_for_load(), __arg.__name_for_load());}
> +
> + _LIBCPP_INLINE_VISIBILITY
> + const char *__name_for_load() const _NOEXCEPT
> + {uintptr_t __data = __type_name;
> +#if 1
> + __data &= ~_LIBCPP_NONUNIQUE_RTTI_BIT;
> +#endif
Spurious #if 1? Also, this function (__name_for_load) seems to be
identical to name(), am I missing something?
Dmitri
--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/
More information about the cfe-commits
mailing list