xref: /llvm-project-15.0.7/libcxx/src/debug.cpp (revision fc88dbd2)
1f554add5SHoward Hinnant //===-------------------------- debug.cpp ---------------------------------===//
2f554add5SHoward Hinnant //
3f554add5SHoward Hinnant //                     The LLVM Compiler Infrastructure
4f554add5SHoward Hinnant //
5f554add5SHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open
6f554add5SHoward Hinnant // Source Licenses. See LICENSE.TXT for details.
7f554add5SHoward Hinnant //
8f554add5SHoward Hinnant //===----------------------------------------------------------------------===//
9f554add5SHoward Hinnant 
10cec9af9eSHoward Hinnant #define _LIBCPP_DEBUG2 1
11cec9af9eSHoward Hinnant #include "__config"
12f554add5SHoward Hinnant #include "__debug"
13f554add5SHoward Hinnant #include "functional"
14f554add5SHoward Hinnant #include "algorithm"
15f554add5SHoward Hinnant #include "__hash_table"
16f554add5SHoward Hinnant #include "mutex"
17f554add5SHoward Hinnant 
18f554add5SHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD
19f554add5SHoward Hinnant 
206e41256fSHoward Hinnant _LIBCPP_FUNC_VIS
21f554add5SHoward Hinnant __libcpp_db*
22f554add5SHoward Hinnant __get_db()
23f554add5SHoward Hinnant {
24f554add5SHoward Hinnant     static __libcpp_db db;
25f554add5SHoward Hinnant     return &db;
26267e3e1eSHoward Hinnant }
27f554add5SHoward Hinnant 
286e41256fSHoward Hinnant _LIBCPP_FUNC_VIS
29f554add5SHoward Hinnant const __libcpp_db*
30f554add5SHoward Hinnant __get_const_db()
31f554add5SHoward Hinnant {
32f554add5SHoward Hinnant     return __get_db();
33f554add5SHoward Hinnant }
34f554add5SHoward Hinnant 
35f554add5SHoward Hinnant namespace
36f554add5SHoward Hinnant {
37f554add5SHoward Hinnant 
38f554add5SHoward Hinnant typedef mutex mutex_type;
39f554add5SHoward Hinnant typedef lock_guard<mutex_type> WLock;
40f554add5SHoward Hinnant typedef lock_guard<mutex_type> RLock;
41f554add5SHoward Hinnant 
42f554add5SHoward Hinnant mutex_type&
43f554add5SHoward Hinnant mut()
44f554add5SHoward Hinnant {
45f554add5SHoward Hinnant     static mutex_type m;
46f554add5SHoward Hinnant     return m;
47f554add5SHoward Hinnant }
48f554add5SHoward Hinnant 
49f554add5SHoward Hinnant }  // unnamed namespace
50f554add5SHoward Hinnant 
51f554add5SHoward Hinnant __i_node::~__i_node()
52f554add5SHoward Hinnant {
53f554add5SHoward Hinnant     if (__next_)
54f554add5SHoward Hinnant     {
55f554add5SHoward Hinnant         __next_->~__i_node();
56f554add5SHoward Hinnant         free(__next_);
57f554add5SHoward Hinnant     }
58f554add5SHoward Hinnant }
59f554add5SHoward Hinnant 
60f554add5SHoward Hinnant __c_node::~__c_node()
61f554add5SHoward Hinnant {
62f554add5SHoward Hinnant     free(beg_);
63f554add5SHoward Hinnant     if (__next_)
64f554add5SHoward Hinnant     {
65f554add5SHoward Hinnant         __next_->~__c_node();
66f554add5SHoward Hinnant         free(__next_);
67f554add5SHoward Hinnant     }
68f554add5SHoward Hinnant }
69f554add5SHoward Hinnant 
70f554add5SHoward Hinnant __libcpp_db::__libcpp_db()
71f554add5SHoward Hinnant     : __cbeg_(nullptr),
72f554add5SHoward Hinnant       __cend_(nullptr),
73f554add5SHoward Hinnant       __csz_(0),
74f554add5SHoward Hinnant       __ibeg_(nullptr),
75f554add5SHoward Hinnant       __iend_(nullptr),
76f554add5SHoward Hinnant       __isz_(0)
77f554add5SHoward Hinnant {
78f554add5SHoward Hinnant }
79f554add5SHoward Hinnant 
80f554add5SHoward Hinnant __libcpp_db::~__libcpp_db()
81f554add5SHoward Hinnant {
82f554add5SHoward Hinnant     if (__cbeg_)
83f554add5SHoward Hinnant     {
84f554add5SHoward Hinnant         for (__c_node** p = __cbeg_; p != __cend_; ++p)
85f554add5SHoward Hinnant         {
86f554add5SHoward Hinnant             if (*p != nullptr)
87f554add5SHoward Hinnant             {
88f554add5SHoward Hinnant                 (*p)->~__c_node();
89f554add5SHoward Hinnant                 free(*p);
90f554add5SHoward Hinnant             }
91f554add5SHoward Hinnant         }
92f554add5SHoward Hinnant         free(__cbeg_);
93f554add5SHoward Hinnant     }
94f554add5SHoward Hinnant     if (__ibeg_)
95f554add5SHoward Hinnant     {
96f554add5SHoward Hinnant         for (__i_node** p = __ibeg_; p != __iend_; ++p)
97f554add5SHoward Hinnant         {
98f554add5SHoward Hinnant             if (*p != nullptr)
99f554add5SHoward Hinnant             {
100f554add5SHoward Hinnant                 (*p)->~__i_node();
101f554add5SHoward Hinnant                 free(*p);
102f554add5SHoward Hinnant             }
103f554add5SHoward Hinnant         }
104f554add5SHoward Hinnant         free(__ibeg_);
105f554add5SHoward Hinnant     }
106f554add5SHoward Hinnant }
107f554add5SHoward Hinnant 
108f554add5SHoward Hinnant void*
109f554add5SHoward Hinnant __libcpp_db::__find_c_from_i(void* __i) const
110f554add5SHoward Hinnant {
111f554add5SHoward Hinnant     RLock _(mut());
112f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
113f7509231SHoward Hinnant     _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
114c36bfc49SHoward Hinnant     return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
115f554add5SHoward Hinnant }
116f554add5SHoward Hinnant 
117f554add5SHoward Hinnant void
118f554add5SHoward Hinnant __libcpp_db::__insert_ic(void* __i, const void* __c)
119f554add5SHoward Hinnant {
120f554add5SHoward Hinnant     WLock _(mut());
121*fc88dbd2SHoward Hinnant     if (__cbeg_ == __cend_)
122*fc88dbd2SHoward Hinnant         return;
123c206366fSHoward Hinnant     size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
124f554add5SHoward Hinnant     __c_node* c = __cbeg_[hc];
125*fc88dbd2SHoward Hinnant     if (c == nullptr)
126*fc88dbd2SHoward Hinnant         return;
127f554add5SHoward Hinnant     while (c->__c_ != __c)
128f554add5SHoward Hinnant     {
129f554add5SHoward Hinnant         c = c->__next_;
130*fc88dbd2SHoward Hinnant         if (c == nullptr)
131*fc88dbd2SHoward Hinnant             return;
132f554add5SHoward Hinnant     }
133*fc88dbd2SHoward Hinnant     __i_node* i = __insert_iterator(__i);
134f554add5SHoward Hinnant     c->__add(i);
135f554add5SHoward Hinnant     i->__c_ = c;
136f554add5SHoward Hinnant }
137f554add5SHoward Hinnant 
138f554add5SHoward Hinnant __c_node*
139f554add5SHoward Hinnant __libcpp_db::__insert_c(void* __c)
140f554add5SHoward Hinnant {
141f554add5SHoward Hinnant     WLock _(mut());
142c206366fSHoward Hinnant     if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
143f554add5SHoward Hinnant     {
144c206366fSHoward Hinnant         size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
14585ad6c99SJoerg Sonnenberger         __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(void*)));
146f554add5SHoward Hinnant         if (cbeg == nullptr)
1477b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
148f554add5SHoward Hinnant             throw bad_alloc();
1497b838f53SHoward Hinnant #else
1507b838f53SHoward Hinnant             abort();
1517b838f53SHoward Hinnant #endif
152f554add5SHoward Hinnant         for (__c_node** p = __cbeg_; p != __cend_; ++p)
153f554add5SHoward Hinnant         {
154f554add5SHoward Hinnant             __c_node* q = *p;
155f554add5SHoward Hinnant             while (q != nullptr)
156f554add5SHoward Hinnant             {
157f554add5SHoward Hinnant                 size_t h = hash<void*>()(q->__c_) % nc;
158f554add5SHoward Hinnant                 __c_node* r = q->__next_;
159f554add5SHoward Hinnant                 q->__next_ = cbeg[h];
160f554add5SHoward Hinnant                 cbeg[h] = q;
161f554add5SHoward Hinnant                 q = r;
162f554add5SHoward Hinnant             }
163f554add5SHoward Hinnant         }
164f554add5SHoward Hinnant         free(__cbeg_);
165f554add5SHoward Hinnant         __cbeg_ = cbeg;
166f554add5SHoward Hinnant         __cend_ = __cbeg_ + nc;
167f554add5SHoward Hinnant     }
168c206366fSHoward Hinnant     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
169f554add5SHoward Hinnant     __c_node* p = __cbeg_[hc];
17085ad6c99SJoerg Sonnenberger     __c_node* r = __cbeg_[hc] =
17185ad6c99SJoerg Sonnenberger       static_cast<__c_node*>(malloc(sizeof(__c_node)));
172f554add5SHoward Hinnant     if (__cbeg_[hc] == nullptr)
1737b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
174f554add5SHoward Hinnant         throw bad_alloc();
1757b838f53SHoward Hinnant #else
1767b838f53SHoward Hinnant         abort();
1777b838f53SHoward Hinnant #endif
178f554add5SHoward Hinnant     r->__c_ = __c;
179f554add5SHoward Hinnant     r->__next_ = p;
180f554add5SHoward Hinnant     ++__csz_;
181f554add5SHoward Hinnant     return r;
182f554add5SHoward Hinnant }
183f554add5SHoward Hinnant 
184f554add5SHoward Hinnant void
185f554add5SHoward Hinnant __libcpp_db::__erase_i(void* __i)
186f554add5SHoward Hinnant {
187f554add5SHoward Hinnant     WLock _(mut());
188f554add5SHoward Hinnant     if (__ibeg_ != __iend_)
189f554add5SHoward Hinnant     {
190c206366fSHoward Hinnant         size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
191f554add5SHoward Hinnant         __i_node* p = __ibeg_[hi];
192f554add5SHoward Hinnant         if (p != nullptr)
193f554add5SHoward Hinnant         {
194f554add5SHoward Hinnant             __i_node* q = nullptr;
195f554add5SHoward Hinnant             while (p->__i_ != __i)
196f554add5SHoward Hinnant             {
197f554add5SHoward Hinnant                 q = p;
198f554add5SHoward Hinnant                 p = p->__next_;
199f554add5SHoward Hinnant                 if (p == nullptr)
200f554add5SHoward Hinnant                     return;
201f554add5SHoward Hinnant             }
202f554add5SHoward Hinnant             if (q == nullptr)
203f554add5SHoward Hinnant                 __ibeg_[hi] = p->__next_;
204f554add5SHoward Hinnant             else
205f554add5SHoward Hinnant                 q->__next_ = p->__next_;
206f554add5SHoward Hinnant             __c_node* c = p->__c_;
207f554add5SHoward Hinnant             free(p);
208f554add5SHoward Hinnant             --__isz_;
209f554add5SHoward Hinnant             if (c != nullptr)
210f554add5SHoward Hinnant                 c->__remove(p);
211f554add5SHoward Hinnant         }
212f554add5SHoward Hinnant     }
213f554add5SHoward Hinnant }
214f554add5SHoward Hinnant 
215f554add5SHoward Hinnant void
216f554add5SHoward Hinnant __libcpp_db::__invalidate_all(void* __c)
217f554add5SHoward Hinnant {
218f554add5SHoward Hinnant     WLock _(mut());
219*fc88dbd2SHoward Hinnant     if (__cend_ != __cbeg_)
220*fc88dbd2SHoward Hinnant     {
221c206366fSHoward Hinnant         size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
222f554add5SHoward Hinnant         __c_node* p = __cbeg_[hc];
223*fc88dbd2SHoward Hinnant         if (p == nullptr)
224*fc88dbd2SHoward Hinnant             return;
225f554add5SHoward Hinnant         while (p->__c_ != __c)
226f554add5SHoward Hinnant         {
227f554add5SHoward Hinnant             p = p->__next_;
228*fc88dbd2SHoward Hinnant             if (p == nullptr)
229*fc88dbd2SHoward Hinnant                 return;
230f554add5SHoward Hinnant         }
231f554add5SHoward Hinnant         while (p->end_ != p->beg_)
232f554add5SHoward Hinnant         {
233f554add5SHoward Hinnant             --p->end_;
234f554add5SHoward Hinnant             (*p->end_)->__c_ = nullptr;
235f554add5SHoward Hinnant         }
236f554add5SHoward Hinnant     }
237*fc88dbd2SHoward Hinnant }
238f554add5SHoward Hinnant 
239f554add5SHoward Hinnant __c_node*
240f554add5SHoward Hinnant __libcpp_db::__find_c_and_lock(void* __c) const
241f554add5SHoward Hinnant {
242f554add5SHoward Hinnant     mut().lock();
243*fc88dbd2SHoward Hinnant     if (__cend_ == __cbeg_)
244*fc88dbd2SHoward Hinnant     {
245*fc88dbd2SHoward Hinnant         mut().unlock();
246*fc88dbd2SHoward Hinnant         return nullptr;
247*fc88dbd2SHoward Hinnant     }
248c206366fSHoward Hinnant     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
249f554add5SHoward Hinnant     __c_node* p = __cbeg_[hc];
250*fc88dbd2SHoward Hinnant     if (p == nullptr)
251*fc88dbd2SHoward Hinnant     {
252*fc88dbd2SHoward Hinnant         mut().unlock();
253*fc88dbd2SHoward Hinnant         return nullptr;
254*fc88dbd2SHoward Hinnant     }
255f554add5SHoward Hinnant     while (p->__c_ != __c)
256f554add5SHoward Hinnant     {
257f554add5SHoward Hinnant         p = p->__next_;
258*fc88dbd2SHoward Hinnant         if (p == nullptr)
259*fc88dbd2SHoward Hinnant         {
260*fc88dbd2SHoward Hinnant             mut().unlock();
261*fc88dbd2SHoward Hinnant             return nullptr;
262*fc88dbd2SHoward Hinnant         }
263f554add5SHoward Hinnant     }
264f554add5SHoward Hinnant     return p;
265f554add5SHoward Hinnant }
266f554add5SHoward Hinnant 
267920b56caSHoward Hinnant __c_node*
268920b56caSHoward Hinnant __libcpp_db::__find_c(void* __c) const
269920b56caSHoward Hinnant {
270c206366fSHoward Hinnant     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
271920b56caSHoward Hinnant     __c_node* p = __cbeg_[hc];
272920b56caSHoward Hinnant     _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
273920b56caSHoward Hinnant     while (p->__c_ != __c)
274920b56caSHoward Hinnant     {
275920b56caSHoward Hinnant         p = p->__next_;
276920b56caSHoward Hinnant         _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
277920b56caSHoward Hinnant     }
278920b56caSHoward Hinnant     return p;
279920b56caSHoward Hinnant }
280920b56caSHoward Hinnant 
281f554add5SHoward Hinnant void
282f554add5SHoward Hinnant __libcpp_db::unlock() const
283f554add5SHoward Hinnant {
284f554add5SHoward Hinnant     mut().unlock();
285f554add5SHoward Hinnant }
286f554add5SHoward Hinnant 
287f554add5SHoward Hinnant void
288f554add5SHoward Hinnant __libcpp_db::__erase_c(void* __c)
289f554add5SHoward Hinnant {
290f554add5SHoward Hinnant     WLock _(mut());
291*fc88dbd2SHoward Hinnant     if (__cend_ != __cbeg_)
292*fc88dbd2SHoward Hinnant     {
293c206366fSHoward Hinnant         size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
294f554add5SHoward Hinnant         __c_node* p = __cbeg_[hc];
295*fc88dbd2SHoward Hinnant         if (p == nullptr)
296*fc88dbd2SHoward Hinnant             return;
297f554add5SHoward Hinnant         __c_node* q = nullptr;
298f554add5SHoward Hinnant         _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
299f554add5SHoward Hinnant         while (p->__c_ != __c)
300f554add5SHoward Hinnant         {
301f554add5SHoward Hinnant             q = p;
302f554add5SHoward Hinnant             p = p->__next_;
303*fc88dbd2SHoward Hinnant             if (p == nullptr)
304*fc88dbd2SHoward Hinnant                 return;
305f554add5SHoward Hinnant             _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
306f554add5SHoward Hinnant         }
307f554add5SHoward Hinnant         if (q == nullptr)
308f554add5SHoward Hinnant             __cbeg_[hc] = p->__next_;
309f554add5SHoward Hinnant         else
310f554add5SHoward Hinnant             q->__next_ = p->__next_;
311f554add5SHoward Hinnant         while (p->end_ != p->beg_)
312f554add5SHoward Hinnant         {
313f554add5SHoward Hinnant             --p->end_;
314f554add5SHoward Hinnant             (*p->end_)->__c_ = nullptr;
315f554add5SHoward Hinnant         }
316f554add5SHoward Hinnant         free(p->beg_);
317f554add5SHoward Hinnant         free(p);
318f554add5SHoward Hinnant         --__csz_;
319f554add5SHoward Hinnant     }
320*fc88dbd2SHoward Hinnant }
321f554add5SHoward Hinnant 
322f554add5SHoward Hinnant void
323f554add5SHoward Hinnant __libcpp_db::__iterator_copy(void* __i, const void* __i0)
324f554add5SHoward Hinnant {
325f554add5SHoward Hinnant     WLock _(mut());
326f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
327f554add5SHoward Hinnant     __i_node* i0 = __find_iterator(__i0);
328f554add5SHoward Hinnant     __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
329f7509231SHoward Hinnant     if (i == nullptr && i0 != nullptr)
330f554add5SHoward Hinnant         i = __insert_iterator(__i);
331f554add5SHoward Hinnant     __c_node* c = i != nullptr ? i->__c_ : nullptr;
332f554add5SHoward Hinnant     if (c != c0)
333f554add5SHoward Hinnant     {
334f554add5SHoward Hinnant         if (c != nullptr)
335f554add5SHoward Hinnant             c->__remove(i);
336f554add5SHoward Hinnant         if (i != nullptr)
337f554add5SHoward Hinnant         {
338f554add5SHoward Hinnant             i->__c_ = nullptr;
339f554add5SHoward Hinnant             if (c0 != nullptr)
340f554add5SHoward Hinnant             {
341f554add5SHoward Hinnant                 i->__c_ = c0;
342f554add5SHoward Hinnant                 i->__c_->__add(i);
343f554add5SHoward Hinnant             }
344f554add5SHoward Hinnant         }
345f554add5SHoward Hinnant     }
346f554add5SHoward Hinnant }
347f554add5SHoward Hinnant 
348f554add5SHoward Hinnant bool
349f554add5SHoward Hinnant __libcpp_db::__dereferenceable(const void* __i) const
350f554add5SHoward Hinnant {
351f554add5SHoward Hinnant     RLock _(mut());
352f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
353f554add5SHoward Hinnant     return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
354f554add5SHoward Hinnant }
355f554add5SHoward Hinnant 
356f554add5SHoward Hinnant bool
357f554add5SHoward Hinnant __libcpp_db::__decrementable(const void* __i) const
358f554add5SHoward Hinnant {
359f554add5SHoward Hinnant     RLock _(mut());
360f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
361f554add5SHoward Hinnant     return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
362f554add5SHoward Hinnant }
363f554add5SHoward Hinnant 
364f554add5SHoward Hinnant bool
365f554add5SHoward Hinnant __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
366f554add5SHoward Hinnant {
367f554add5SHoward Hinnant     RLock _(mut());
368f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
369f554add5SHoward Hinnant     return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
370f554add5SHoward Hinnant }
371f554add5SHoward Hinnant 
372f554add5SHoward Hinnant bool
373f554add5SHoward Hinnant __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
374f554add5SHoward Hinnant {
375f554add5SHoward Hinnant     RLock _(mut());
376f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
377f554add5SHoward Hinnant     return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
378f554add5SHoward Hinnant }
379f554add5SHoward Hinnant 
380f554add5SHoward Hinnant bool
38142a3046eSHoward Hinnant __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
382f554add5SHoward Hinnant {
383f554add5SHoward Hinnant     RLock _(mut());
384f554add5SHoward Hinnant     __i_node* i = __find_iterator(__i);
385f554add5SHoward Hinnant     __i_node* j = __find_iterator(__j);
386f554add5SHoward Hinnant     __c_node* ci = i != nullptr ? i->__c_ : nullptr;
387f554add5SHoward Hinnant     __c_node* cj = j != nullptr ? j->__c_ : nullptr;
388f554add5SHoward Hinnant     return ci != nullptr && ci == cj;
389f554add5SHoward Hinnant }
390f554add5SHoward Hinnant 
391f554add5SHoward Hinnant void
392f554add5SHoward Hinnant __libcpp_db::swap(void* c1, void* c2)
393f554add5SHoward Hinnant {
394f554add5SHoward Hinnant     WLock _(mut());
395c206366fSHoward Hinnant     size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
396f554add5SHoward Hinnant     __c_node* p1 = __cbeg_[hc];
397f554add5SHoward Hinnant     _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
398f554add5SHoward Hinnant     while (p1->__c_ != c1)
399f554add5SHoward Hinnant     {
400f554add5SHoward Hinnant         p1 = p1->__next_;
401f554add5SHoward Hinnant         _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
402f554add5SHoward Hinnant     }
403c206366fSHoward Hinnant     hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
404f554add5SHoward Hinnant     __c_node* p2 = __cbeg_[hc];
405f554add5SHoward Hinnant     _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
406f554add5SHoward Hinnant     while (p2->__c_ != c2)
407f554add5SHoward Hinnant     {
408f554add5SHoward Hinnant         p2 = p2->__next_;
409f554add5SHoward Hinnant         _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
410f554add5SHoward Hinnant     }
411f554add5SHoward Hinnant     std::swap(p1->beg_, p2->beg_);
412f554add5SHoward Hinnant     std::swap(p1->end_, p2->end_);
413f554add5SHoward Hinnant     std::swap(p1->cap_, p2->cap_);
414f554add5SHoward Hinnant     for (__i_node** p = p1->beg_; p != p1->end_; ++p)
415f554add5SHoward Hinnant         (*p)->__c_ = p1;
416f554add5SHoward Hinnant     for (__i_node** p = p2->beg_; p != p2->end_; ++p)
417f554add5SHoward Hinnant         (*p)->__c_ = p2;
418f554add5SHoward Hinnant }
419f554add5SHoward Hinnant 
420c36bfc49SHoward Hinnant void
421c36bfc49SHoward Hinnant __libcpp_db::__insert_i(void* __i)
422c36bfc49SHoward Hinnant {
423c36bfc49SHoward Hinnant     WLock _(mut());
424c36bfc49SHoward Hinnant     __insert_iterator(__i);
425c36bfc49SHoward Hinnant }
426c36bfc49SHoward Hinnant 
427920b56caSHoward Hinnant void
428920b56caSHoward Hinnant __c_node::__add(__i_node* i)
429920b56caSHoward Hinnant {
430920b56caSHoward Hinnant     if (end_ == cap_)
431920b56caSHoward Hinnant     {
432c206366fSHoward Hinnant         size_t nc = 2*static_cast<size_t>(cap_ - beg_);
433920b56caSHoward Hinnant         if (nc == 0)
434920b56caSHoward Hinnant             nc = 1;
43585ad6c99SJoerg Sonnenberger         __i_node** beg =
43685ad6c99SJoerg Sonnenberger            static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));
437920b56caSHoward Hinnant         if (beg == nullptr)
4387b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
439920b56caSHoward Hinnant             throw bad_alloc();
4407b838f53SHoward Hinnant #else
4417b838f53SHoward Hinnant             abort();
4427b838f53SHoward Hinnant #endif
443920b56caSHoward Hinnant         if (nc > 1)
444920b56caSHoward Hinnant             memcpy(beg, beg_, nc/2*sizeof(__i_node*));
445920b56caSHoward Hinnant         free(beg_);
446920b56caSHoward Hinnant         beg_ = beg;
447920b56caSHoward Hinnant         end_ = beg_ + nc/2;
448920b56caSHoward Hinnant         cap_ = beg_ + nc;
449920b56caSHoward Hinnant     }
450920b56caSHoward Hinnant     *end_++ = i;
451920b56caSHoward Hinnant }
452920b56caSHoward Hinnant 
453f554add5SHoward Hinnant // private api
454f554add5SHoward Hinnant 
455f554add5SHoward Hinnant _LIBCPP_HIDDEN
456f554add5SHoward Hinnant __i_node*
457f554add5SHoward Hinnant __libcpp_db::__insert_iterator(void* __i)
458f554add5SHoward Hinnant {
459c206366fSHoward Hinnant     if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
460f554add5SHoward Hinnant     {
461c206366fSHoward Hinnant         size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
46285ad6c99SJoerg Sonnenberger         __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(void*)));
463f554add5SHoward Hinnant         if (ibeg == nullptr)
4647b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
465f554add5SHoward Hinnant             throw bad_alloc();
4667b838f53SHoward Hinnant #else
4677b838f53SHoward Hinnant             abort();
4687b838f53SHoward Hinnant #endif
469f554add5SHoward Hinnant         for (__i_node** p = __ibeg_; p != __iend_; ++p)
470f554add5SHoward Hinnant         {
471f554add5SHoward Hinnant             __i_node* q = *p;
472f554add5SHoward Hinnant             while (q != nullptr)
473f554add5SHoward Hinnant             {
474f554add5SHoward Hinnant                 size_t h = hash<void*>()(q->__i_) % nc;
475f554add5SHoward Hinnant                 __i_node* r = q->__next_;
476f554add5SHoward Hinnant                 q->__next_ = ibeg[h];
477f554add5SHoward Hinnant                 ibeg[h] = q;
478f554add5SHoward Hinnant                 q = r;
479f554add5SHoward Hinnant             }
480f554add5SHoward Hinnant         }
481f554add5SHoward Hinnant         free(__ibeg_);
482f554add5SHoward Hinnant         __ibeg_ = ibeg;
483f554add5SHoward Hinnant         __iend_ = __ibeg_ + nc;
484f554add5SHoward Hinnant     }
485c206366fSHoward Hinnant     size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
486f554add5SHoward Hinnant     __i_node* p = __ibeg_[hi];
48785ad6c99SJoerg Sonnenberger     __i_node* r = __ibeg_[hi] =
48885ad6c99SJoerg Sonnenberger       static_cast<__i_node*>(malloc(sizeof(__i_node)));
489f554add5SHoward Hinnant     if (r == nullptr)
4907b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
491f554add5SHoward Hinnant         throw bad_alloc();
4927b838f53SHoward Hinnant #else
4937b838f53SHoward Hinnant         abort();
4947b838f53SHoward Hinnant #endif
495f554add5SHoward Hinnant     ::new(r) __i_node(__i, p, nullptr);
496f554add5SHoward Hinnant     ++__isz_;
497f554add5SHoward Hinnant     return r;
498f554add5SHoward Hinnant }
499f554add5SHoward Hinnant 
500f554add5SHoward Hinnant _LIBCPP_HIDDEN
501f554add5SHoward Hinnant __i_node*
502f554add5SHoward Hinnant __libcpp_db::__find_iterator(const void* __i) const
503f554add5SHoward Hinnant {
504f554add5SHoward Hinnant     __i_node* r = nullptr;
505f554add5SHoward Hinnant     if (__ibeg_ != __iend_)
506f554add5SHoward Hinnant     {
507c206366fSHoward Hinnant         size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
508f554add5SHoward Hinnant         for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
509f554add5SHoward Hinnant         {
510f554add5SHoward Hinnant             if (nd->__i_ == __i)
511f554add5SHoward Hinnant             {
512f554add5SHoward Hinnant                 r = nd;
513f554add5SHoward Hinnant                 break;
514f554add5SHoward Hinnant             }
515f554add5SHoward Hinnant         }
516f554add5SHoward Hinnant     }
517f554add5SHoward Hinnant     return r;
518f554add5SHoward Hinnant }
519f554add5SHoward Hinnant 
520f554add5SHoward Hinnant _LIBCPP_HIDDEN
521f554add5SHoward Hinnant void
522f554add5SHoward Hinnant __c_node::__remove(__i_node* p)
523f554add5SHoward Hinnant {
524f554add5SHoward Hinnant     __i_node** r = find(beg_, end_, p);
525f554add5SHoward Hinnant     _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
526f554add5SHoward Hinnant     if (--end_ != r)
527c206366fSHoward Hinnant         memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
528f554add5SHoward Hinnant }
529f554add5SHoward Hinnant 
530f554add5SHoward Hinnant _LIBCPP_END_NAMESPACE_STD
531