Skip to content

Commit

Permalink
We need to always allocate debug proxies
Browse files Browse the repository at this point in the history
  • Loading branch information
miscco committed Dec 24, 2020
1 parent 2c99992 commit 6e347e9
Showing 1 changed file with 101 additions and 89 deletions.
190 changes: 101 additions & 89 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -1160,9 +1160,8 @@ struct _Iterator_base0 {
// CLASS _Container_proxy
struct _Container_base12;
struct _Container_proxy { // store head of iterator chain and back pointer
_CONSTEXPR20_DYNALLOC _Container_proxy() noexcept : _Mycont(nullptr), _Myfirstiter(nullptr) {}
_CONSTEXPR20_DYNALLOC _Container_proxy(_Container_base12* _Mycont_) noexcept
: _Mycont(_Mycont_), _Myfirstiter(nullptr) {}
_CONSTEXPR20 _Container_proxy() noexcept : _Mycont(nullptr), _Myfirstiter(nullptr) {}
_CONSTEXPR20 _Container_proxy(_Container_base12* _Mycont_) noexcept : _Mycont(_Mycont_), _Myfirstiter(nullptr) {}

const _Container_base12* _Mycont;
_Iterator_base12* _Myfirstiter;
Expand Down Expand Up @@ -1198,147 +1197,149 @@ public:
_Container_proxy* _Myproxy;

private:
inline void _Orphan_all_impl() noexcept;
inline void _Swap_proxy_and_iterators_impl(_Container_base12&) noexcept;
_CONSTEXPR20_DYNALLOC void _Orphan_all_unlocked() noexcept;
inline void _Orphan_all_locked() noexcept;
_CONSTEXPR20_DYNALLOC void _Swap_proxy_and_iterators_unlocked(_Container_base12&) noexcept;
inline void _Swap_proxy_and_iterators_locked(_Container_base12&) noexcept;
};

struct _Iterator_base12 { // store links to container proxy, next iterator
_CONSTEXPR20_DYNALLOC _Iterator_base12() noexcept
: _Myproxy(nullptr), _Mynextiter(nullptr) {} // construct orphaned iterator
_CONSTEXPR20 _Iterator_base12() noexcept : _Myproxy(nullptr), _Mynextiter(nullptr) {} // construct orphaned iterator

_CONSTEXPR20_DYNALLOC _Iterator_base12(const _Iterator_base12& _Right) noexcept
: _Myproxy(nullptr), _Mynextiter(nullptr) {
_CONSTEXPR20 _Iterator_base12(const _Iterator_base12& _Right) noexcept : _Myproxy(nullptr), _Mynextiter(nullptr) {
*this = _Right;
}

_CONSTEXPR20_DYNALLOC _Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
#endif // __cpp_lib_is_constant_evaluated
{
if (_Myproxy != _Right._Myproxy) {
if (_Right._Myproxy) {
_Adopt(_Right._Myproxy->_Mycont);
} else { // becoming invalid, disown current parent
_CONSTEXPR20 _Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
if (_Myproxy != _Right._Myproxy) {
if (_Right._Myproxy) {
_Adopt(_Right._Myproxy->_Mycont);
} else { // becoming invalid, disown current parent
#if _ITERATOR_DEBUG_LEVEL == 2
_Orphan_me();
_Orphan_me();
#else // _ITERATOR_DEBUG_LEVEL == 2
_Myproxy = nullptr;
_Myproxy = nullptr;
#endif // _ITERATOR_DEBUG_LEVEL == 2
}
}
}
return *this;
}

#if _ITERATOR_DEBUG_LEVEL == 2
_CONSTEXPR20_DYNALLOC ~_Iterator_base12() noexcept {
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
#endif // __cpp_lib_is_constant_evaluated
{
_Orphan_me();
}
#if _HAS_CXX20 && defined(__clang__) // TRANSITION: LLVM-XXXX
else {
[[maybe_unused]] volatile auto _Guard = _Myproxy;
_CONSTEXPR20 ~_Iterator_base12() noexcept {
_Orphan_me();
}

_CONSTEXPR20 void _Adopt_unlocked(_Container_proxy* _Parent_proxy) noexcept {
if (_Myproxy) { // adopted, remove self from list
_Orphan_me_unlocked();
}
#endif // _HAS_CXX20 && defined(__clang__)
_Mynextiter = _Parent_proxy->_Myfirstiter;
_Parent_proxy->_Myfirstiter = this;
_Myproxy = _Parent_proxy;
}
#endif // _ITERATOR_DEBUG_LEVEL == 2

#if _ITERATOR_DEBUG_LEVEL == 2
void _Adopt_impl(const _Container_base12* _Parent) noexcept {
if (_Parent) {
// have a parent, do adoption
void _Adopt_locked(_Container_proxy* _Parent_proxy) noexcept {
_Lockit _Lock(_LOCK_DEBUG);
_Adopt_unlocked(_Parent_proxy);
}

_CONSTEXPR20 void _Adopt(const _Container_base12* _Parent) noexcept {
if (_Parent) { // have a parent, do adoption
_Container_proxy* _Parent_proxy = _Parent->_Myproxy;
if (_Myproxy != _Parent_proxy) { // change parentage
_Orphan_me();
_Lockit _Lock(_LOCK_DEBUG);
_Mynextiter = _Parent_proxy->_Myfirstiter;
_Parent_proxy->_Myfirstiter = this;
_Myproxy = _Parent_proxy;
#ifdef __cpp_lib_is_constant_evaluated
if (_STD is_constant_evaluated()) {
_Adopt_unlocked(_Parent_proxy);
} else
#endif // __cpp_lib_is_constant_evaluated
{
_Adopt_locked(_Parent_proxy);
}
}
} else {
// no future parent, just disown current parent
} else { // no future parent, just disown current parent
_Orphan_me();
}
}

_CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
#endif // __cpp_lib_is_constant_evaluated
{
_Adopt_impl(_Parent);
}
}
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 ^^^ / vvv _ITERATOR_DEBUG_LEVEL != 2 vvv
_CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
if (_Parent) {
// have a parent, do adoption
_Container_proxy* _Parent_proxy = _Parent->_Myproxy;
_Myproxy = _Parent_proxy;
} else {
// no future parent, just disown current parent
_Myproxy = nullptr;
_CONSTEXPR20 void _Orphan_me_unlocked() noexcept {
_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter;
while (*_Pnext && *_Pnext != this) {
_Pnext = &(*_Pnext)->_Mynextiter;
}
}
#endif // _ITERATOR_DEBUG_LEVEL == 2

_CONSTEXPR20_DYNALLOC const _Container_base12* _Getcont() const noexcept {
return _Myproxy ? _Myproxy->_Mycont : nullptr;
_STL_VERIFY(*_Pnext, "ITERATOR LIST CORRUPTED!");
*_Pnext = _Mynextiter;
_Myproxy = nullptr;
}

#if _ITERATOR_DEBUG_LEVEL == 2
void _Orphan_me() noexcept {
void _Orphan_me_locked() noexcept {
_Lockit _Lock(_LOCK_DEBUG);
_Orphan_me_unlocked();
}

_CONSTEXPR20 void _Orphan_me() noexcept {
if (_Myproxy) { // adopted, remove self from list
_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter;
while (*_Pnext && *_Pnext != this) {
_Pnext = &(*_Pnext)->_Mynextiter;
#ifdef __cpp_lib_is_constant_evaluated
if (_STD is_constant_evaluated()) {
_Orphan_me_unlocked();
} else
#endif // __cpp_lib_is_constant_evaluated
{
_Orphan_me_locked();
}
}
}

_STL_VERIFY(*_Pnext, "ITERATOR LIST CORRUPTED!");
*_Pnext = _Mynextiter;
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 ^^^ / vvv _ITERATOR_DEBUG_LEVEL != 2 vvv
_CONSTEXPR20 void _Adopt(const _Container_base12* _Parent) noexcept {
if (_Parent) { // have a parent, do adoption
_Myproxy = _Parent->_Myproxy;
} else { // no future parent, just disown current parent
_Myproxy = nullptr;
}
}
#endif // _ITERATOR_DEBUG_LEVEL == 2

_CONSTEXPR20 const _Container_base12* _Getcont() const noexcept {
return _Myproxy ? _Myproxy->_Mycont : nullptr;
}

static constexpr bool _Unwrap_when_unverified = _ITERATOR_DEBUG_LEVEL == 0;

_Container_proxy* _Myproxy;
_Iterator_base12* _Mynextiter;
};

// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all_impl() noexcept {
if (_Myproxy) { // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);
for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
(*_Pnext)->_Myproxy = nullptr;
}

_Myproxy->_Myfirstiter = nullptr;
_CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all_unlocked() noexcept {
for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
(*_Pnext)->_Myproxy = nullptr;
}
_Myproxy->_Myfirstiter = nullptr;
}

inline void _Container_base12::_Orphan_all_locked() noexcept {
_Lockit _Lock(_LOCK_DEBUG);
_Orphan_all_unlocked();
}

_CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy) { // proxy allocated, drain it
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
if (_STD is_constant_evaluated()) {
_Orphan_all_unlocked();
} else
#endif // __cpp_lib_is_constant_evaluated
{
_Orphan_all_impl();
{
_Orphan_all_locked();
}
}
#endif // _ITERATOR_DEBUG_LEVEL == 2
}

inline void _Container_base12::_Swap_proxy_and_iterators_impl(_Container_base12& _Right) noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
_Lockit _Lock(_LOCK_DEBUG);
#endif // _ITERATOR_DEBUG_LEVEL == 2
_CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators_unlocked(_Container_base12& _Right) noexcept {
_Container_proxy* _Temp = _Myproxy;
_Myproxy = _Right._Myproxy;
_Right._Myproxy = _Temp;
Expand All @@ -1352,13 +1353,24 @@ inline void _Container_base12::_Swap_proxy_and_iterators_impl(_Container_base12&
}
}

inline void _Container_base12::_Swap_proxy_and_iterators_locked(_Container_base12& _Right) noexcept {
_Lockit _Lock(_LOCK_DEBUG);
_Swap_proxy_and_iterators_unlocked(_Right);
}

_CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators(_Container_base12& _Right) noexcept {
#if _ITERATOR_DEBUG_LEVEL != 2
_Swap_proxy_and_iterators_unlocked(_Right);
#else // ^^^ _ITERATOR_DEBUG_LEVEL != 2 ^^^ / vvv _ITERATOR_DEBUG_LEVEL == 2 vvv
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
if (_STD is_constant_evaluated()) {
_Swap_proxy_and_iterators_unlocked(_Right);
} else
#endif // __cpp_lib_is_constant_evaluated
{
_Swap_proxy_and_iterators_impl(_Right);
_Swap_proxy_and_iterators_locked(_Right);
}
#endif // _ITERATOR_DEBUG_LEVEL == 2
}

#if _ITERATOR_DEBUG_LEVEL == 0
Expand Down

0 comments on commit 6e347e9

Please sign in to comment.