Skip to content

Commit 7774e80

Browse files
committed
dont visit full pages on a collection, issue #1220
1 parent 57f131c commit 7774e80

1 file changed

Lines changed: 10 additions & 9 deletions

File tree

src/heap.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ terms of the MIT license. A copy of the license can be found in the file
2424
typedef bool (heap_page_visitor_fun)(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2);
2525

2626
// Visit all pages in a heap; returns `false` if break was called.
27-
static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void* arg1, void* arg2)
27+
static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, bool include_full, void* arg1, void* arg2)
2828
{
2929
if (heap==NULL || heap->page_count==0) return 0;
3030

@@ -34,7 +34,8 @@ static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void
3434
size_t count = 0;
3535
#endif
3636

37-
for (size_t i = 0; i <= MI_BIN_FULL; i++) {
37+
const size_t max_bin = (include_full ? MI_BIN_FULL : MI_BIN_FULL - 1);
38+
for (size_t i = 0; i <= max_bin; i++) {
3839
mi_page_queue_t* pq = &heap->pages[i];
3940
mi_page_t* page = pq->first;
4041
while(page != NULL) {
@@ -47,7 +48,7 @@ static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void
4748
page = next; // and continue
4849
}
4950
}
50-
mi_assert_internal(count == total);
51+
mi_assert_internal(!include_full || count == total);
5152
return true;
5253
}
5354

@@ -67,7 +68,7 @@ static bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_
6768
#if MI_DEBUG>=3
6869
static bool mi_heap_is_valid(mi_heap_t* heap) {
6970
mi_assert_internal(heap!=NULL);
70-
mi_heap_visit_pages(heap, &mi_heap_page_is_valid, NULL, NULL);
71+
mi_heap_visit_pages(heap, &mi_heap_page_is_valid, true, NULL, NULL);
7172
return true;
7273
}
7374
#endif
@@ -143,7 +144,7 @@ static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect)
143144

144145
// if abandoning, mark all pages to no longer add to delayed_free
145146
if (collect == MI_ABANDON) {
146-
mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, NULL, NULL);
147+
mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, true, NULL, NULL);
147148
}
148149

149150
// free all current thread delayed blocks.
@@ -154,7 +155,7 @@ static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect)
154155
_mi_heap_collect_retired(heap, force);
155156

156157
// collect all pages owned by this thread
157-
mi_heap_visit_pages(heap, &mi_heap_page_collect, &collect, NULL);
158+
mi_heap_visit_pages(heap, &mi_heap_page_collect, (collect!=MI_NORMAL), &collect, NULL); // normally don't visit full pages, issue #1220
158159
mi_assert_internal( collect != MI_ABANDON || mi_atomic_load_ptr_acquire(mi_block_t,&heap->thread_delayed_free) == NULL );
159160

160161
// collect segments (purge pages, this can be expensive so don't force on abandonment)
@@ -359,7 +360,7 @@ static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_
359360
}
360361

361362
void _mi_heap_destroy_pages(mi_heap_t* heap) {
362-
mi_heap_visit_pages(heap, &_mi_heap_page_destroy, NULL, NULL);
363+
mi_heap_visit_pages(heap, &_mi_heap_page_destroy, true, NULL, NULL);
363364
mi_heap_reset_pages(heap);
364365
}
365366

@@ -530,7 +531,7 @@ bool mi_heap_check_owned(mi_heap_t* heap, const void* p) {
530531
if (heap==NULL || !mi_heap_is_initialized(heap)) return false;
531532
if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false; // only aligned pointers
532533
bool found = false;
533-
mi_heap_visit_pages(heap, &mi_heap_page_check_owned, (void*)p, &found);
534+
mi_heap_visit_pages(heap, &mi_heap_page_check_owned, true, (void*)p, &found);
534535
return found;
535536
}
536537

@@ -696,7 +697,7 @@ static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_pa
696697
// Visit all heap pages as areas
697698
static bool mi_heap_visit_areas(const mi_heap_t* heap, mi_heap_area_visit_fun* visitor, void* arg) {
698699
if (visitor == NULL) return false;
699-
return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, (void*)(visitor), arg); // note: function pointer to void* :-{
700+
return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, true, (void*)(visitor), arg); // note: function pointer to void* :-{
700701
}
701702

702703
// Just to pass arguments

0 commit comments

Comments
 (0)