Skip to content

Commit c3dc79f

Browse files
refactor; rework alloc/dealloc, strings; don't use pmr
1 parent 442b2a2 commit c3dc79f

30 files changed

+830
-841
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,9 +727,13 @@ set(files
727727
__ranges/views.h
728728
__ranges/zip_view.h
729729
__split_buffer
730-
__stacktrace/basic_stacktrace.h
731-
__stacktrace/impl.h
732-
__stacktrace/stacktrace_entry.h
730+
__stacktrace/base.h
731+
__stacktrace/basic.h
732+
__stacktrace/entry.h
733+
__stacktrace/format.h
734+
__stacktrace/hash.h
735+
__stacktrace/nonmem.h
736+
__stacktrace/to_string.h
733737
__std_mbstate_t.h
734738
__stop_token/atomic_unique_lock.h
735739
__stop_token/intrusive_list_view.h

libcxx/include/__stacktrace/base.h

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP_STACKTRACE_BUILDER
11+
#define _LIBCPP_STACKTRACE_BUILDER
12+
13+
#include <__config>
14+
#include <__cstddef/byte.h>
15+
#include <__cstddef/size_t.h>
16+
#include <__functional/function.h>
17+
#include <__fwd/format.h>
18+
#include <__fwd/ostream.h>
19+
#include <__memory/allocator_traits.h>
20+
#include <__vector/vector.h>
21+
#include <cstddef>
22+
#include <cstdint>
23+
#include <list>
24+
#include <optional>
25+
#include <string>
26+
27+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
28+
# pragma GCC system_header
29+
#endif
30+
31+
_LIBCPP_PUSH_MACROS
32+
#include <__undef_macros>
33+
34+
_LIBCPP_BEGIN_NAMESPACE_STD
35+
36+
class stacktrace_entry;
37+
38+
namespace __stacktrace {
39+
40+
struct _LIBCPP_HIDE_FROM_ABI alloc final {
41+
function<byte*(size_t)> __alloc_bytes_;
42+
function<void(byte*, size_t)> __dealloc_bytes_;
43+
44+
template <class _Allocator>
45+
alloc(_Allocator __alloc) {
46+
using _AT = allocator_traits<_Allocator>;
47+
using _BA = typename _AT::template rebind_alloc<byte>;
48+
auto __ba = _BA(__alloc);
49+
__alloc_bytes_ = [__ba](size_t __sz) mutable { return __ba.allocate(__sz); };
50+
__dealloc_bytes_ = [__ba](void* __ptr, size_t __sz) mutable { __ba.deallocate((byte*)__ptr, __sz); };
51+
}
52+
53+
template <typename _Tp>
54+
struct Alloc {
55+
function<byte*(size_t)> __alloc_bytes_;
56+
function<void(byte*, size_t)> __dealloc_bytes_;
57+
58+
Alloc(function<byte*(size_t)> __alloc_bytes, function<void(byte*, size_t)> __dealloc_bytes)
59+
: __alloc_bytes_(__alloc_bytes), __dealloc_bytes_(__dealloc_bytes) {}
60+
61+
template <typename _T2 = _Tp>
62+
Alloc(Alloc<_T2> const& __rhs) : Alloc(__rhs.__alloc_bytes_, __rhs.__dealloc_bytes_) {}
63+
64+
using value_type = _Tp;
65+
[[nodiscard]] _Tp* allocate(size_t __sz) { return (_Tp*)__alloc_bytes_(__sz * sizeof(_Tp)); }
66+
void deallocate(_Tp* __ptr, size_t __sz) { __dealloc_bytes_((byte*)__ptr, __sz * sizeof(_Tp)); }
67+
68+
template <typename _A2>
69+
bool operator==(_A2 const& __rhs) const {
70+
return &__rhs == this;
71+
}
72+
};
73+
74+
template <typename _Tp>
75+
Alloc<_Tp> make_alloc() {
76+
return {__alloc_bytes_, __dealloc_bytes_};
77+
}
78+
79+
using str = basic_string<char, char_traits<char>, Alloc<char>>;
80+
81+
template <typename... _Args>
82+
str make_str(_Args... __args) {
83+
return str(std::forward<_Args>(__args)..., make_alloc<char>());
84+
}
85+
86+
template <typename _Tp>
87+
using vec = vector<_Tp, Alloc<_Tp>>;
88+
89+
template <typename _Tp, typename... _Args>
90+
vec<_Tp> make_vec(_Args... __args) {
91+
return vec(std::forward<_Args>(__args)..., make_alloc<_Tp>());
92+
}
93+
94+
template <typename _Tp>
95+
using list = ::std::list<_Tp, Alloc<_Tp>>;
96+
97+
template <typename _Tp, typename... _Args>
98+
list<_Tp> make_list(_Args... __args) {
99+
return list(std::forward<_Args>(__args)..., make_alloc<_Tp>());
100+
}
101+
};
102+
103+
struct _LIBCPP_HIDE_FROM_ABI entry_base {
104+
uintptr_t __addr_actual_{}; // this address, as observed in this current process
105+
uintptr_t __addr_unslid_{}; // address adjusted for ASLR
106+
optional<__stacktrace::alloc::str> __desc_{}; // uses wrapped _Allocator from caller
107+
optional<__stacktrace::alloc::str> __file_{}; // uses wrapped _Allocator from caller
108+
uint_least32_t __line_{};
109+
110+
stacktrace_entry to_stacktrace_entry() const;
111+
};
112+
113+
struct _LIBCPP_HIDE_FROM_ABI builder final {
114+
alloc __alloc_; // wraps the caller-provided allocator
115+
alloc::vec<entry_base> __entries_;
116+
alloc::str __main_prog_path_;
117+
118+
template <class _Allocator>
119+
explicit builder(_Allocator __alloc)
120+
: __alloc_(__alloc), __entries_(__alloc_.make_vec<entry_base>()), __main_prog_path_(__alloc_.make_str()) {}
121+
122+
_LIBCPP_NO_TAIL_CALLS _LIBCPP_NOINLINE _LIBCPP_EXPORTED_FROM_ABI void
123+
build_stacktrace(size_t __skip, size_t __max_depth);
124+
};
125+
126+
} // namespace __stacktrace
127+
_LIBCPP_END_NAMESPACE_STD
128+
129+
_LIBCPP_POP_MACROS
130+
131+
#endif // _LIBCPP_STACKTRACE_BUILDER

libcxx/include/__stacktrace/basic_stacktrace.h renamed to libcxx/include/__stacktrace/basic.h

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,19 @@
1010
#ifndef _LIBCPP_BASIC_STACKTRACE
1111
#define _LIBCPP_BASIC_STACKTRACE
1212

13-
#include <__stacktrace/impl.h>
14-
#include <__stacktrace/stacktrace_entry.h>
15-
1613
#include <__config>
17-
#include <__format/formatter.h>
18-
#include <__functional/function.h>
1914
#include <__functional/hash.h>
2015
#include <__fwd/format.h>
21-
#include <__fwd/sstream.h>
2216
#include <__iterator/iterator.h>
23-
#include <__iterator/iterator_traits.h>
24-
#include <__iterator/reverse_access.h>
2517
#include <__iterator/reverse_iterator.h>
26-
#include <__memory/allocator.h>
2718
#include <__memory/allocator_traits.h>
28-
#include <__memory_resource/memory_resource.h>
2919
#include <__memory_resource/polymorphic_allocator.h>
30-
#include <__ostream/basic_ostream.h>
31-
#include <__utility/move.h>
32-
#include <__vector/pmr.h>
33-
#include <__vector/swap.h>
20+
#include <__stacktrace/base.h>
21+
#include <__stacktrace/entry.h>
22+
#include <__stacktrace/to_string.h>
23+
#include <__type_traits/is_nothrow_constructible.h>
3424
#include <__vector/vector.h>
35-
#include <cstddef>
36-
#include <memory>
25+
#include <utility>
3726

3827
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3928
# pragma GCC system_header
@@ -63,12 +52,10 @@ class _LIBCPP_EXPORTED_FROM_ABI basic_stacktrace {
6352
constexpr static bool __kNoThrowAlloc =
6453
noexcept(noexcept(_Allocator().allocate(1)) && noexcept(_Allocator().allocate_at_least(1)));
6554

66-
using __entry_vec _LIBCPP_NODEBUG = vector<stacktrace_entry, _Allocator>;
67-
6855
[[no_unique_address]] _Allocator __alloc_;
69-
__entry_vec __entries_;
7056

71-
// _LIBCPP_HIDE_FROM_ABI basic_stacktrace(const _Allocator& __alloc, std::pmr::list<stacktrace_entry>&& __vec);
57+
using __entry_vec = vector<stacktrace_entry, _Allocator>;
58+
__entry_vec __entries_;
7259

7360
public:
7461
// (19.6.4.1)
@@ -80,7 +67,7 @@ class _LIBCPP_EXPORTED_FROM_ABI basic_stacktrace {
8067
using difference_type = ptrdiff_t;
8168
using size_type = size_t;
8269
using allocator_type = _Allocator;
83-
using const_iterator = decltype(__entries_)::const_iterator;
70+
using const_iterator = __entry_vec::const_iterator;
8471
using iterator = const_iterator;
8572

8673
using reverse_iterator = std::reverse_iterator<basic_stacktrace::iterator>;
@@ -103,13 +90,13 @@ class _LIBCPP_EXPORTED_FROM_ABI basic_stacktrace {
10390
current(size_type __skip,
10491
size_type __max_depth,
10592
const allocator_type& __caller_alloc = allocator_type()) noexcept(__kNoThrowAlloc) {
93+
__stacktrace::builder __builder(__caller_alloc);
94+
__builder.build_stacktrace(__skip + 1, __max_depth);
10695
basic_stacktrace<_Allocator> __ret{__caller_alloc};
107-
__stacktrace::alloc __alloc(__caller_alloc);
108-
auto __resize = [&__ret](size_t __sz) { __ret.__entries_.resize(__sz); };
109-
auto __assign = [&__ret](size_t __index, stacktrace_entry&& __entry) {
110-
__ret.__entries_.at(__index) = std::move(__entry);
111-
};
112-
__stacktrace::__impl(__skip + 1, __max_depth, __alloc, __resize, __assign);
96+
__ret.__entries_.reserve(__builder.__entries_.size());
97+
for (auto& __base : __builder.__entries_) {
98+
__ret.__entries_.emplace_back(__base.to_stacktrace_entry());
99+
}
113100
return __ret;
114101
}
115102

@@ -252,48 +239,6 @@ namespace pmr {
252239
using stacktrace = basic_stacktrace<polymorphic_allocator<stacktrace_entry>>;
253240
} // namespace pmr
254241

255-
// (19.6.4.6)
256-
// Non-member functions [stacktrace.basic.nonmem]
257-
258-
template <class _Allocator>
259-
_LIBCPP_EXPORTED_FROM_ABI inline void
260-
swap(basic_stacktrace<_Allocator>& __a, basic_stacktrace<_Allocator>& __b) noexcept(noexcept(__a.swap(__b))) {
261-
__a.swap(__b);
262-
}
263-
264-
template <class _Allocator>
265-
_LIBCPP_EXPORTED_FROM_ABI inline string to_string(const basic_stacktrace<_Allocator>& __stacktrace) {
266-
return __stacktrace::__to_string()(__stacktrace);
267-
}
268-
269-
template <class _Allocator>
270-
_LIBCPP_EXPORTED_FROM_ABI inline ostream& operator<<(ostream& __os, const basic_stacktrace<_Allocator>& __stacktrace) {
271-
auto __str = __stacktrace::__to_string()(__stacktrace);
272-
return __os << __str;
273-
}
274-
275-
// (19.6.5)
276-
// Formatting support [stacktrace.format]
277-
278-
// TODO: stacktrace formatter: https://github.com/llvm/llvm-project/issues/105257
279-
template <class _Allocator>
280-
struct _LIBCPP_EXPORTED_FROM_ABI formatter<basic_stacktrace<_Allocator>>;
281-
282-
// (19.6.6)
283-
// Hash support [stacktrace.basic.hash]
284-
285-
template <class _Allocator>
286-
struct _LIBCPP_EXPORTED_FROM_ABI hash<basic_stacktrace<_Allocator>> {
287-
[[nodiscard]] size_t operator()(basic_stacktrace<_Allocator> const& __context) const noexcept {
288-
size_t __ret = 1;
289-
for (auto const& __entry : __context.__entries_) {
290-
__ret += hash<uintptr_t>()(__entry.native_handle());
291-
__ret *= 3001;
292-
}
293-
return __ret;
294-
}
295-
};
296-
297242
_LIBCPP_END_NAMESPACE_STD
298243

299244
_LIBCPP_POP_MACROS

libcxx/include/__stacktrace/stacktrace_entry.h renamed to libcxx/include/__stacktrace/entry.h

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,16 @@
1010
#ifndef _LIBCPP_STACKTRACE_ENTRY
1111
#define _LIBCPP_STACKTRACE_ENTRY
1212

13-
#include <__cstddef/byte.h>
14-
#include <__cstddef/ptrdiff_t.h>
15-
#include <__cstddef/size_t.h>
16-
#include <__format/formatter.h>
17-
#include <__functional/function.h>
18-
#include <__functional/hash.h>
13+
#include <__config>
1914
#include <__fwd/format.h>
2015
#include <__fwd/ostream.h>
21-
#include <__fwd/sstream.h>
22-
#include <__fwd/vector.h>
23-
#include <__iterator/iterator.h>
24-
#include <__iterator/iterator_traits.h>
25-
#include <__iterator/reverse_access.h>
26-
#include <__iterator/reverse_iterator.h>
27-
#include <__memory/allocator.h>
28-
#include <__memory/allocator_traits.h>
29-
#include <__utility/move.h>
30-
#include <__vector/pmr.h>
31-
#include <__vector/swap.h>
32-
#include <__vector/vector.h>
16+
#include <cstddef>
3317
#include <cstdint>
18+
#include <optional>
3419
#include <string>
3520

21+
#include <__stacktrace/base.h>
22+
3623
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3724
# pragma GCC system_header
3825
#endif
@@ -42,11 +29,10 @@ _LIBCPP_PUSH_MACROS
4229

4330
_LIBCPP_BEGIN_NAMESPACE_STD
4431

45-
namespace __stacktrace {
46-
struct entry;
47-
} // namespace __stacktrace
32+
class _LIBCPP_EXPORTED_FROM_ABI stacktrace_entry : private __stacktrace::entry_base {
33+
friend struct __stacktrace::entry_base;
34+
stacktrace_entry(entry_base const& __base) : entry_base(__base) {}
4835

49-
class _LIBCPP_EXPORTED_FROM_ABI stacktrace_entry {
5036
public:
5137
// (19.6.3.1) Overview [stacktrace.entry.overview]
5238
using native_handle_type = uintptr_t;
@@ -59,15 +45,25 @@ class _LIBCPP_EXPORTED_FROM_ABI stacktrace_entry {
5945

6046
// (19.6.3.3) [stacktrace.entry.obs], observers
6147
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI constexpr native_handle_type native_handle() const noexcept {
62-
return __addr_;
48+
return __addr_actual_;
6349
}
6450
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI constexpr explicit operator bool() const noexcept {
6551
return native_handle() != 0;
6652
}
6753

6854
// (19.6.3.4) [stacktrace.entry.query], query
69-
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string description() const { return __desc_; }
70-
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string source_file() const { return __file_; }
55+
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string description() const {
56+
if (__desc_->empty()) {
57+
return "";
58+
}
59+
return {__desc_->data(), __desc_->size()};
60+
}
61+
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string source_file() const {
62+
if (__desc_->empty()) {
63+
return "";
64+
}
65+
return {__file_->data(), __file_->size()};
66+
}
7167
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI uint_least32_t source_line() const { return __line_; }
7268

7369
// (19.6.3.5) [stacktrace.entry.cmp], comparison
@@ -80,20 +76,12 @@ class _LIBCPP_EXPORTED_FROM_ABI stacktrace_entry {
8076
operator<=>(const stacktrace_entry& __x, const stacktrace_entry& __y) noexcept {
8177
return __x.native_handle() <=> __y.native_handle();
8278
}
83-
84-
private:
85-
friend struct __stacktrace::entry;
86-
87-
uintptr_t __addr_{};
88-
std::string __desc_{};
89-
std::string __file_{};
90-
uint_least32_t __line_{};
9179
};
9280

9381
// (19.6.4.6)
9482
// Non-member functions [stacktrace.basic.nonmem]
9583

96-
_LIBCPP_EXPORTED_FROM_ABI string to_string(const stacktrace_entry& __entry);
84+
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string to_string(const stacktrace_entry& __entry);
9785
_LIBCPP_EXPORTED_FROM_ABI ostream& operator<<(ostream& __os, const stacktrace_entry& __entry);
9886

9987
// (19.6.5)
@@ -114,6 +102,10 @@ struct _LIBCPP_EXPORTED_FROM_ABI hash<stacktrace_entry> {
114102
}
115103
};
116104

105+
namespace __stacktrace {
106+
inline stacktrace_entry entry_base::to_stacktrace_entry() const { return {*this}; }
107+
} // namespace __stacktrace
108+
117109
_LIBCPP_END_NAMESPACE_STD
118110

119111
_LIBCPP_POP_MACROS

0 commit comments

Comments
 (0)