gh-112532: Tag mimalloc heaps and pages (#113742)

* gh-112532: Tag mimalloc heaps and pages

Mimalloc pages are data structures that contain contiguous allocations
of the same block size. Note that they are distinct from operating
system pages. Mimalloc pages are contained in segments.

When a thread exits, it abandons any segments and contained pages that
have live allocations. These segments and pages may be later reclaimed
by another thread. To support GC and certain thread-safety guarantees in
free-threaded builds, we want pages to only be reclaimed by the
corresponding heap in the claimant thread. For example, we want pages
containing GC objects to only be claimed by GC heaps.

This allows heaps and pages to be tagged with an integer tag that is
used to ensure that abandoned pages are only claimed by heaps with the
same tag. Heaps can be initialized with a tag (0-15); any page allocated
by that heap copies the corresponding tag.

* Fix conversion warning
This commit is contained in:
Sam Gross 2024-01-05 15:08:50 -05:00 committed by GitHub
parent eb53750757
commit 0b7476080b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 16 deletions

View file

@ -14,7 +14,7 @@ terms of the MIT license. A copy of the license can be found in the file
// Empty page used to initialize the small free pages array
const mi_page_t _mi_page_empty = {
0, false, false, false,
0, false, false, false, 0,
0, // capacity
0, // reserved capacity
{ 0 }, // flags
@ -121,7 +121,8 @@ mi_decl_cache_align const mi_heap_t _mi_heap_empty = {
0, // page count
MI_BIN_FULL, 0, // page retired min/max
NULL, // next
false
false,
0
};
#define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats)))
@ -298,7 +299,7 @@ static bool _mi_heap_init(void) {
if (td == NULL) return false;
_mi_tld_init(&td->tld, &td->heap);
_mi_heap_init_ex(&td->heap, &td->tld, _mi_arena_id_none());
_mi_heap_init_ex(&td->heap, &td->tld, _mi_arena_id_none(), false, 0);
_mi_heap_set_default_direct(&td->heap);
}
return false;
@ -311,7 +312,6 @@ void _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap) {
tld->segments.abandoned = &_mi_abandoned_default;
tld->os.stats = &tld->stats;
tld->heap_backing = bheap;
tld->heaps = bheap;
}
// Free the thread local default heap (called from `mi_thread_done`)