Skip to content

Commit 17d0569

Browse files
authored
[libc++] Instantiate hash function externally (#127040)
This has multiple benefits: - There is a single instance of our hash function, reducing object file size - The hash implementation isn't instantiated in every TU anymore, reducing compile times - Behind an ABI configuration macro it would be possible to salt the hash
1 parent ac09b78 commit 17d0569

14 files changed

+54
-5
lines changed

Diff for: libcxx/include/__configuration/availability.h

+13
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
// in all versions of the library are available.
7979
#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
8080

81+
# define _LIBCPP_INTRODUCED_IN_LLVM_21 1
82+
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE /* nothing */
83+
8184
# define _LIBCPP_INTRODUCED_IN_LLVM_20 1
8285
# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE /* nothing */
8386

@@ -114,6 +117,11 @@
114117

115118
// clang-format off
116119

120+
// LLVM 21
121+
// TODO: Fill this in
122+
# define _LIBCPP_INTRODUCED_IN_LLVM_21 0
123+
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE __attribute__((unavailable))
124+
117125
// LLVM 20
118126
// TODO: Fill this in
119127
# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
@@ -359,6 +367,11 @@
359367
#define _LIBCPP_AVAILABILITY_HAS_FROM_CHARS_FLOATING_POINT _LIBCPP_INTRODUCED_IN_LLVM_20
360368
#define _LIBCPP_AVAILABILITY_FROM_CHARS_FLOATING_POINT _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE
361369

370+
// This controls whether `std::__hash_memory` is available in the dylib, which
371+
// is used for some `std::hash` specializations.
372+
#define _LIBCPP_AVAILABILITY_HAS_HASH_MEMORY _LIBCPP_INTRODUCED_IN_LLVM_21
373+
// No attribute, since we've had hash in the headers before
374+
362375
// Define availability attributes that depend on _LIBCPP_HAS_EXCEPTIONS.
363376
// Those are defined in terms of the availability attributes above, and
364377
// should not be vendor-specific.

Diff for: libcxx/include/__functional/hash.h

+12-4
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,14 @@ struct __murmur2_or_cityhash<_Size, 64> {
238238
}
239239
};
240240

241+
#if _LIBCPP_AVAILABILITY_HAS_HASH_MEMORY
242+
[[__gnu__::__pure__]] _LIBCPP_EXPORTED_FROM_ABI size_t __hash_memory(_LIBCPP_NOESCAPE const void*, size_t) _NOEXCEPT;
243+
#else
244+
_LIBCPP_HIDE_FROM_ABI inline size_t __hash_memory(const void* __ptr, size_t __size) _NOEXCEPT {
245+
return __murmur2_or_cityhash<size_t>()(__ptr, __size);
246+
}
247+
#endif
248+
241249
template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
242250
struct __scalar_hash;
243251

@@ -277,7 +285,7 @@ struct __scalar_hash<_Tp, 2> : public __unary_function<_Tp, size_t> {
277285
} __s;
278286
} __u;
279287
__u.__t = __v;
280-
return __murmur2_or_cityhash<size_t>()(std::addressof(__u), sizeof(__u));
288+
return std::__hash_memory(std::addressof(__u), sizeof(__u));
281289
}
282290
};
283291

@@ -293,7 +301,7 @@ struct __scalar_hash<_Tp, 3> : public __unary_function<_Tp, size_t> {
293301
} __s;
294302
} __u;
295303
__u.__t = __v;
296-
return __murmur2_or_cityhash<size_t>()(std::addressof(__u), sizeof(__u));
304+
return std::__hash_memory(std::addressof(__u), sizeof(__u));
297305
}
298306
};
299307

@@ -310,7 +318,7 @@ struct __scalar_hash<_Tp, 4> : public __unary_function<_Tp, size_t> {
310318
} __s;
311319
} __u;
312320
__u.__t = __v;
313-
return __murmur2_or_cityhash<size_t>()(std::addressof(__u), sizeof(__u));
321+
return std::__hash_memory(std::addressof(__u), sizeof(__u));
314322
}
315323
};
316324

@@ -333,7 +341,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> : public __unary_function<_Tp*, size_t> {
333341
size_t __a;
334342
} __u;
335343
__u.__t = __v;
336-
return __murmur2_or_cityhash<size_t>()(std::addressof(__u), sizeof(__u));
344+
return std::__hash_memory(std::addressof(__u), sizeof(__u));
337345
}
338346
};
339347

Diff for: libcxx/include/__string/char_traits.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ __str_find_last_not_of(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos)
534534
template <class _Ptr>
535535
inline _LIBCPP_HIDE_FROM_ABI size_t __do_string_hash(_Ptr __p, _Ptr __e) {
536536
typedef typename iterator_traits<_Ptr>::value_type value_type;
537-
return __murmur2_or_cityhash<size_t>()(__p, (__e - __p) * sizeof(value_type));
537+
return std::__hash_memory(__p, (__e - __p) * sizeof(value_type));
538538
}
539539

540540
_LIBCPP_END_NAMESPACE_STD

Diff for: libcxx/lib/abi/CHANGELOG.TXT

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ To generate a summary, re-generate the new ABI list using the
1212

1313
New entries should be added directly below the "Version" header.
1414

15+
------------
16+
Version 21.0
17+
------------
18+
19+
* [libc++] Instantiate hash function externally
20+
21+
This has multiple benefits:
22+
- There is a single instance of our hash function, reducing object file size
23+
- The hash implementation isn't instantiated in every TU anymore, reducing compile times
24+
- Behind an ABI configuration macro, it would be possible to salt the hash
25+
26+
All platforms
27+
-------------
28+
Symbol added: _ZNSt3__113__hash_memoryEPKvm
29+
1530
------------
1631
Version 20.0
1732
------------

Diff for: libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,7 @@
13051305
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
13061306
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
13071307
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
1308+
{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
13081309
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
13091310
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'}
13101311
{'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@
941941
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'}
942942
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'}
943943
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
944+
{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'}
944945
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
945946
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
946947
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@
418418
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
419419
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
420420
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
421+
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
421422
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
422423
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
423424
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@
418418
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
419419
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
420420
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
421+
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
421422
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
422423
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
423424
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,7 @@
13051305
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
13061306
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
13071307
{'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
1308+
{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
13081309
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
13091310
{'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'}
13101311
{'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@
941941
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'}
942942
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'}
943943
{'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
944+
{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'}
944945
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
945946
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
946947
{'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,7 @@
956956
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
957957
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
958958
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
959+
{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
959960
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
960961
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
961962
{'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@
954954
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
955955
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
956956
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
957+
{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
957958
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
958959
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
959960
{'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}

Diff for: libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,7 @@
924924
{'is_defined': True, 'name': '_ZNSt3__113random_deviceclEv', 'type': 'FUNC'}
925925
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
926926
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
927+
{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
927928
{'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
928929
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
929930
{'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}

Diff for: libcxx/src/functional.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ bad_function_call::~bad_function_call() noexcept {}
1616
const char* bad_function_call::what() const noexcept { return "std::bad_function_call"; }
1717
#endif
1818

19+
size_t __hash_memory(_LIBCPP_NOESCAPE const void* ptr, size_t size) noexcept {
20+
return __murmur2_or_cityhash<size_t>()(ptr, size);
21+
}
22+
1923
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)