1 //===-------------------------- debug.cpp ---------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define _LIBCPP_DEBUG 1
15 #include "__hash_table"
18 _LIBCPP_BEGIN_NAMESPACE_STD
24 static __libcpp_db db
;
38 typedef mutex mutex_type
;
39 typedef lock_guard
<mutex_type
> WLock
;
40 typedef lock_guard
<mutex_type
> RLock
;
49 } // unnamed namespace
70 __libcpp_db::__libcpp_db()
80 __libcpp_db::~__libcpp_db()
84 for (__c_node
** p
= __cbeg_
; p
!= __cend_
; ++p
)
96 for (__i_node
** p
= __ibeg_
; p
!= __iend_
; ++p
)
109 __libcpp_db::__find_c_from_i(void* __i
) const
112 __i_node
* i
= __find_iterator(__i
);
113 _LIBCPP_ASSERT(i
!= nullptr, "iterator not found in debug database.");
114 return i
->__c_
!= nullptr ? i
->__c_
->__c_
: nullptr;
118 __libcpp_db::__insert_ic(void* __i
, const void* __c
)
121 if (__cbeg_
== __cend_
)
123 size_t hc
= hash
<const void*>()(__c
) % static_cast<size_t>(__cend_
- __cbeg_
);
124 __c_node
* c
= __cbeg_
[hc
];
127 while (c
->__c_
!= __c
)
133 __i_node
* i
= __insert_iterator(__i
);
139 __libcpp_db::__insert_c(void* __c
)
142 if (__csz_
+ 1 > static_cast<size_t>(__cend_
- __cbeg_
))
144 size_t nc
= __next_prime(2*static_cast<size_t>(__cend_
- __cbeg_
) + 1);
145 __c_node
** cbeg
= static_cast<__c_node
**>(calloc(nc
, sizeof(void*)));
147 #ifndef _LIBCPP_NO_EXCEPTIONS
152 for (__c_node
** p
= __cbeg_
; p
!= __cend_
; ++p
)
157 size_t h
= hash
<void*>()(q
->__c_
) % nc
;
158 __c_node
* r
= q
->__next_
;
159 q
->__next_
= cbeg
[h
];
166 __cend_
= __cbeg_
+ nc
;
168 size_t hc
= hash
<void*>()(__c
) % static_cast<size_t>(__cend_
- __cbeg_
);
169 __c_node
* p
= __cbeg_
[hc
];
170 __c_node
* r
= __cbeg_
[hc
] =
171 static_cast<__c_node
*>(malloc(sizeof(__c_node
)));
172 if (__cbeg_
[hc
] == nullptr)
173 #ifndef _LIBCPP_NO_EXCEPTIONS
185 __libcpp_db::__erase_i(void* __i
)
188 if (__ibeg_
!= __iend_
)
190 size_t hi
= hash
<void*>()(__i
) % static_cast<size_t>(__iend_
- __ibeg_
);
191 __i_node
* p
= __ibeg_
[hi
];
194 __i_node
* q
= nullptr;
195 while (p
->__i_
!= __i
)
203 __ibeg_
[hi
] = p
->__next_
;
205 q
->__next_
= p
->__next_
;
206 __c_node
* c
= p
->__c_
;
216 __libcpp_db::__invalidate_all(void* __c
)
219 if (__cend_
!= __cbeg_
)
221 size_t hc
= hash
<void*>()(__c
) % static_cast<size_t>(__cend_
- __cbeg_
);
222 __c_node
* p
= __cbeg_
[hc
];
225 while (p
->__c_
!= __c
)
231 while (p
->end_
!= p
->beg_
)
234 (*p
->end_
)->__c_
= nullptr;
240 __libcpp_db::__find_c_and_lock(void* __c
) const
243 if (__cend_
== __cbeg_
)
248 size_t hc
= hash
<void*>()(__c
) % static_cast<size_t>(__cend_
- __cbeg_
);
249 __c_node
* p
= __cbeg_
[hc
];
255 while (p
->__c_
!= __c
)
268 __libcpp_db::__find_c(void* __c
) const
270 size_t hc
= hash
<void*>()(__c
) % static_cast<size_t>(__cend_
- __cbeg_
);
271 __c_node
* p
= __cbeg_
[hc
];
272 _LIBCPP_ASSERT(p
!= nullptr, "debug mode internal logic error __find_c A");
273 while (p
->__c_
!= __c
)
276 _LIBCPP_ASSERT(p
!= nullptr, "debug mode internal logic error __find_c B");
282 __libcpp_db::unlock() const
288 __libcpp_db::__erase_c(void* __c
)
291 if (__cend_
!= __cbeg_
)
293 size_t hc
= hash
<void*>()(__c
) % static_cast<size_t>(__cend_
- __cbeg_
);
294 __c_node
* p
= __cbeg_
[hc
];
297 __c_node
* q
= nullptr;
298 _LIBCPP_ASSERT(p
!= nullptr, "debug mode internal logic error __erase_c A");
299 while (p
->__c_
!= __c
)
305 _LIBCPP_ASSERT(p
!= nullptr, "debug mode internal logic error __erase_c B");
308 __cbeg_
[hc
] = p
->__next_
;
310 q
->__next_
= p
->__next_
;
311 while (p
->end_
!= p
->beg_
)
314 (*p
->end_
)->__c_
= nullptr;
323 __libcpp_db::__iterator_copy(void* __i
, const void* __i0
)
326 __i_node
* i
= __find_iterator(__i
);
327 __i_node
* i0
= __find_iterator(__i0
);
328 __c_node
* c0
= i0
!= nullptr ? i0
->__c_
: nullptr;
329 if (i
== nullptr && i0
!= nullptr)
330 i
= __insert_iterator(__i
);
331 __c_node
* c
= i
!= nullptr ? i
->__c_
: nullptr;
349 __libcpp_db::__dereferenceable(const void* __i
) const
352 __i_node
* i
= __find_iterator(__i
);
353 return i
!= nullptr && i
->__c_
!= nullptr && i
->__c_
->__dereferenceable(__i
);
357 __libcpp_db::__decrementable(const void* __i
) const
360 __i_node
* i
= __find_iterator(__i
);
361 return i
!= nullptr && i
->__c_
!= nullptr && i
->__c_
->__decrementable(__i
);
365 __libcpp_db::__addable(const void* __i
, ptrdiff_t __n
) const
368 __i_node
* i
= __find_iterator(__i
);
369 return i
!= nullptr && i
->__c_
!= nullptr && i
->__c_
->__addable(__i
, __n
);
373 __libcpp_db::__subscriptable(const void* __i
, ptrdiff_t __n
) const
376 __i_node
* i
= __find_iterator(__i
);
377 return i
!= nullptr && i
->__c_
!= nullptr && i
->__c_
->__subscriptable(__i
, __n
);
381 __libcpp_db::__less_than_comparable(const void* __i
, const void* __j
) const
384 __i_node
* i
= __find_iterator(__i
);
385 __i_node
* j
= __find_iterator(__j
);
386 __c_node
* ci
= i
!= nullptr ? i
->__c_
: nullptr;
387 __c_node
* cj
= j
!= nullptr ? j
->__c_
: nullptr;
388 return ci
!= nullptr && ci
== cj
;
392 __libcpp_db::swap(void* c1
, void* c2
)
395 size_t hc
= hash
<void*>()(c1
) % static_cast<size_t>(__cend_
- __cbeg_
);
396 __c_node
* p1
= __cbeg_
[hc
];
397 _LIBCPP_ASSERT(p1
!= nullptr, "debug mode internal logic error swap A");
398 while (p1
->__c_
!= c1
)
401 _LIBCPP_ASSERT(p1
!= nullptr, "debug mode internal logic error swap B");
403 hc
= hash
<void*>()(c2
) % static_cast<size_t>(__cend_
- __cbeg_
);
404 __c_node
* p2
= __cbeg_
[hc
];
405 _LIBCPP_ASSERT(p2
!= nullptr, "debug mode internal logic error swap C");
406 while (p2
->__c_
!= c2
)
409 _LIBCPP_ASSERT(p2
!= nullptr, "debug mode internal logic error swap D");
411 std::swap(p1
->beg_
, p2
->beg_
);
412 std::swap(p1
->end_
, p2
->end_
);
413 std::swap(p1
->cap_
, p2
->cap_
);
414 for (__i_node
** p
= p1
->beg_
; p
!= p1
->end_
; ++p
)
416 for (__i_node
** p
= p2
->beg_
; p
!= p2
->end_
; ++p
)
421 __libcpp_db::__insert_i(void* __i
)
424 __insert_iterator(__i
);
428 __c_node::__add(__i_node
* i
)
432 size_t nc
= 2*static_cast<size_t>(cap_
- beg_
);
436 static_cast<__i_node
**>(malloc(nc
* sizeof(__i_node
*)));
438 #ifndef _LIBCPP_NO_EXCEPTIONS
444 memcpy(beg
, beg_
, nc
/2*sizeof(__i_node
*));
457 __libcpp_db::__insert_iterator(void* __i
)
459 if (__isz_
+ 1 > static_cast<size_t>(__iend_
- __ibeg_
))
461 size_t nc
= __next_prime(2*static_cast<size_t>(__iend_
- __ibeg_
) + 1);
462 __i_node
** ibeg
= static_cast<__i_node
**>(calloc(nc
, sizeof(void*)));
464 #ifndef _LIBCPP_NO_EXCEPTIONS
469 for (__i_node
** p
= __ibeg_
; p
!= __iend_
; ++p
)
474 size_t h
= hash
<void*>()(q
->__i_
) % nc
;
475 __i_node
* r
= q
->__next_
;
476 q
->__next_
= ibeg
[h
];
483 __iend_
= __ibeg_
+ nc
;
485 size_t hi
= hash
<void*>()(__i
) % static_cast<size_t>(__iend_
- __ibeg_
);
486 __i_node
* p
= __ibeg_
[hi
];
487 __i_node
* r
= __ibeg_
[hi
] =
488 static_cast<__i_node
*>(malloc(sizeof(__i_node
)));
490 #ifndef _LIBCPP_NO_EXCEPTIONS
495 ::new(r
) __i_node(__i
, p
, nullptr);
502 __libcpp_db::__find_iterator(const void* __i
) const
504 __i_node
* r
= nullptr;
505 if (__ibeg_
!= __iend_
)
507 size_t h
= hash
<const void*>()(__i
) % static_cast<size_t>(__iend_
- __ibeg_
);
508 for (__i_node
* nd
= __ibeg_
[h
]; nd
!= nullptr; nd
= nd
->__next_
)
522 __c_node::__remove(__i_node
* p
)
524 __i_node
** r
= find(beg_
, end_
, p
);
525 _LIBCPP_ASSERT(r
!= end_
, "debug mode internal logic error __c_node::__remove");
527 memmove(r
, r
+1, static_cast<size_t>(end_
- r
)*sizeof(__i_node
*));
530 _LIBCPP_END_NAMESPACE_STD