Skip to content

Commit 6f1adb9

Browse files
Hashing etc.
1 parent 4f24849 commit 6f1adb9

File tree

5 files changed

+38
-16
lines changed

5 files changed

+38
-16
lines changed

libcxx/include/__stacktrace/basic_stacktrace.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ struct _Trace {
7676
_LIBCPP_EXPORTED_FROM_ABI ostream& write_to(ostream& __os) const;
7777
_LIBCPP_EXPORTED_FROM_ABI string to_string() const;
7878

79+
_LIBCPP_EXPORTED_FROM_ABI size_t hash() const;
80+
_LIBCPP_HIDE_FROM_ABI static _Trace& base(auto& __trace);
81+
_LIBCPP_HIDE_FROM_ABI static _Trace const& base(auto const& __trace);
82+
7983
# ifdef _WIN32
8084
// Windows impl uses dbghelp and psapi DLLs to do the full stacktrace operation.
8185
_LIBCPP_EXPORTED_FROM_ABI void windows_impl(size_t skip, size_t max_depth);
@@ -95,7 +99,6 @@ class stacktrace_entry;
9599

96100
template <class _Allocator>
97101
class basic_stacktrace : private __stacktrace::_Trace {
98-
friend struct hash<basic_stacktrace<_Allocator>>;
99102
friend struct __stacktrace::_Trace;
100103

101104
vector<stacktrace_entry, _Allocator> __entries_;
@@ -285,11 +288,7 @@ _LIBCPP_HIDE_FROM_ABI inline ostream& operator<<(ostream& __os, const basic_stac
285288
template <class _Allocator>
286289
struct hash<basic_stacktrace<_Allocator>> {
287290
_LIBCPP_HIDE_FROM_ABI size_t operator()(basic_stacktrace<_Allocator> const& __trace) const noexcept {
288-
size_t __ret = 0xc3a5c85c97cb3127ull; // just a big prime number; taken from __functional/hash.h
289-
for (stacktrace_entry const& __e : __trace.__entries_) {
290-
__ret = (__ret << 1) ^ __e.__base_.hash();
291-
}
292-
return __ret;
291+
return __stacktrace::_Trace::base(__trace).hash();
293292
}
294293
};
295294

@@ -337,6 +336,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE inline void _Trace::populate_addrs(s
337336

338337
# endif // _WIN32
339338

339+
_Trace& _Trace::base(auto& __trace) { return *static_cast<_Trace*>(&__trace); }
340+
_Trace const& _Trace::base(auto const& __trace) { return *static_cast<_Trace const*>(&__trace); }
341+
340342
} // namespace __stacktrace
341343
_LIBCPP_END_NAMESPACE_STD
342344

libcxx/include/__stacktrace/stacktrace_entry.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ struct _Entry {
8585
_LIBCPP_EXPORTED_FROM_ABI string to_string() const;
8686
# endif // _LIBCPP_HAS_LOCALIZATION
8787

88-
_LIBCPP_HIDE_FROM_ABI size_t hash() const { return std::__hash_memory(&__addr_, sizeof(uintptr_t)); }
88+
_LIBCPP_EXPORTED_FROM_ABI size_t hash() const;
89+
_LIBCPP_HIDE_FROM_ABI static _Entry& base(stacktrace_entry& __entry);
90+
_LIBCPP_HIDE_FROM_ABI static _Entry const& base(stacktrace_entry const& __entry);
8991

9092
_LIBCPP_HIDE_FROM_ABI uintptr_t adjusted_addr() const;
9193

@@ -97,13 +99,12 @@ struct _Entry {
9799
_LIBCPP_HIDE_FROM_ABI constexpr _Entry& operator=(_Entry&&) = default;
98100
};
99101

102+
struct _Trace;
103+
100104
} // namespace __stacktrace
101105

102106
class stacktrace_entry {
103-
friend _LIBCPP_HIDE_FROM_ABI inline ostream& operator<<(ostream& __os, std::stacktrace_entry const& __entry);
104-
friend _LIBCPP_HIDE_FROM_ABI inline string to_string(std::stacktrace_entry const& __entry);
105-
friend _LIBCPP_HIDE_FROM_ABI struct hash<stacktrace_entry>;
106-
107+
_LIBCPP_HIDE_FROM_ABI friend struct __stacktrace::_Entry;
107108
__stacktrace::_Entry __base_{};
108109

109110
public:
@@ -143,11 +144,11 @@ class stacktrace_entry {
143144
# if _LIBCPP_HAS_LOCALIZATION
144145

145146
_LIBCPP_HIDE_FROM_ABI inline string to_string(const std::stacktrace_entry& __entry) {
146-
return __entry.__base_.to_string();
147+
return __stacktrace::_Entry::base(__entry).to_string();
147148
}
148149

149-
_LIBCPP_HIDE_FROM_ABI inline ostream& operator<<(ostream& __os, const std::stacktrace_entry& __entry) {
150-
return __entry.__base_.write_to(__os);
150+
_LIBCPP_HIDE_FROM_ABI inline ostream& operator<<(ostream& __os, const stacktrace_entry& __entry) {
151+
return __stacktrace::_Entry::base(__entry).write_to(__os);
151152
}
152153

153154
# endif // _LIBCPP_HAS_LOCALIZATION
@@ -161,11 +162,18 @@ _LIBCPP_HIDE_FROM_ABI inline ostream& operator<<(ostream& __os, const std::stack
161162

162163
template <>
163164
struct hash<stacktrace_entry> {
164-
_LIBCPP_HIDE_FROM_ABI size_t operator()(stacktrace_entry const& __entry) const noexcept {
165-
return __entry.__base_.hash();
165+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const stacktrace_entry& __entry) const noexcept {
166+
return __stacktrace::_Entry::base(__entry).hash();
166167
}
167168
};
168169

170+
namespace __stacktrace {
171+
172+
_LIBCPP_HIDE_FROM_ABI inline _Entry& _Entry::base(stacktrace_entry& __entry) { return __entry.__base_; }
173+
_LIBCPP_HIDE_FROM_ABI inline _Entry const& _Entry::base(stacktrace_entry const& __entry) { return __entry.__base_; }
174+
175+
} // namespace __stacktrace
176+
169177
_LIBCPP_END_NAMESPACE_STD
170178

171179
#endif // _LIBCPP_STD_VER >= 23 && _LIBCPP_AVAILABILITY_HAS_STACKTRACE

libcxx/src/stacktrace/entry.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include <__config>
10+
#include <__functional/hash.h>
1011
#include <__stacktrace/basic_stacktrace.h>
1112
#include <__stacktrace/stacktrace_entry.h>
1213
#include <string>
@@ -55,6 +56,8 @@ _LIBCPP_HIDE_FROM_ABI uintptr_t _Entry::adjusted_addr() const {
5556
return __addr_ - sub;
5657
}
5758

59+
_LIBCPP_EXPORTED_FROM_ABI size_t _Entry::hash() const { return std::__hash_memory(&__addr_, sizeof(uintptr_t)); }
60+
5861
} // namespace __stacktrace
5962

6063
_LIBCPP_END_NAMESPACE_STD

libcxx/src/stacktrace/trace.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ _LIBCPP_EXPORTED_FROM_ABI string _Trace::to_string() const {
4949

5050
#endif // _LIBCPP_HAS_LOCALIZATION
5151

52+
_LIBCPP_EXPORTED_FROM_ABI size_t _Trace::hash() const {
53+
size_t __ret = 0xc3a5c85c97cb3127ull; // just a big prime number; taken from __functional/hash.h
54+
for (_Entry const& __e : __entry_iters_()) {
55+
__ret = (__ret << 1) ^ __e.hash();
56+
}
57+
return __ret;
58+
}
59+
5260
} // namespace __stacktrace
5361

5462
_LIBCPP_END_NAMESPACE_STD

libcxx/test/std/diagnostics/stacktrace/basic.hash.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
// REQUIRES: std-at-least-c++23
10+
// ADDITIONAL_COMPILE_FLAGS: -O0 -g
1011
// XFAIL: availability-stacktrace-missing
1112

1213
/*

0 commit comments

Comments
 (0)