HEAP_BUCKET_NONE
Description
Sentinel for “no bucket” / “list end” in the hash table and warm lists. 0xFFFFFFFFu is unreachable as a real bucket index since pages_cap is bounded well below 2^32.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Heap.c:240:
static FORCE_INLINE u32 heap_hash_lookup(const HeapPage *pages, u32 mask, void *page_base) {
if (!pages)
return HEAP_BUCKET_NONE;
u32 idx = heap_hash_bucket((u64)page_base, mask);
while (pages[idx].page) {- In
Heap.c:247:
idx = (idx + 1u) & mask;
}
return HEAP_BUCKET_NONE;
}- In
Heap.c:266:
HeapPage *pages = heap->pages;
u32 head = heap->class_warm_head[cls];
pages[idx].prev_warm = HEAP_BUCKET_NONE;
pages[idx].next_warm = head;
if (head != HEAP_BUCKET_NONE) {- In
Heap.c:268:
pages[idx].prev_warm = HEAP_BUCKET_NONE;
pages[idx].next_warm = head;
if (head != HEAP_BUCKET_NONE) {
pages[head].prev_warm = idx;
}- In
Heap.c:279:
u32 prev = pages[idx].prev_warm;
u32 next = pages[idx].next_warm;
if (prev != HEAP_BUCKET_NONE) {
pages[prev].next_warm = next;
} else {- In
Heap.c:284:
heap->class_warm_head[cls] = next;
}
if (next != HEAP_BUCKET_NONE) {
pages[next].prev_warm = prev;
}- In
Heap.c:287:
pages[next].prev_warm = prev;
}
pages[idx].prev_warm = HEAP_BUCKET_NONE;
pages[idx].next_warm = HEAP_BUCKET_NONE;
}- In
Heap.c:288:
}
pages[idx].prev_warm = HEAP_BUCKET_NONE;
pages[idx].next_warm = HEAP_BUCKET_NONE;
}- In
Heap.c:315:
HeapPage *moved = &pages[idx];
u8 cls = moved->class_idx;
if (moved->prev_warm != HEAP_BUCKET_NONE) {
pages[moved->prev_warm].next_warm = idx;
} else if (heap->class_warm_head[cls] == cursor) {- In
Heap.c:320:
heap->class_warm_head[cls] = idx;
}
if (moved->next_warm != HEAP_BUCKET_NONE) {
pages[moved->next_warm].prev_warm = idx;
}- In
Heap.c:349:
// Rebuild warm heads from scratch as we reinsert.
for (u32 c = 0; c < HEAP_NUM_CLASSES; c++) {
heap->class_warm_head[c] = HEAP_BUCKET_NONE;
}- In
Heap.c:367:
// Has free slots -> belongs at warm-list head for its class.
u32 head = heap->class_warm_head[cls];
desc.prev_warm = HEAP_BUCKET_NONE;
desc.next_warm = head;
fresh[ins] = desc;- In
Heap.c:370:
desc.next_warm = head;
fresh[ins] = desc;
if (head != HEAP_BUCKET_NONE) {
fresh[head].prev_warm = ins;
}- In
Heap.c:376:
} else {
// Full page -> not in any warm list.
desc.prev_warm = HEAP_BUCKET_NONE;
desc.next_warm = HEAP_BUCKET_NONE;
fresh[ins] = desc;- In
Heap.c:377:
// Full page -> not in any warm list.
desc.prev_warm = HEAP_BUCKET_NONE;
desc.next_warm = HEAP_BUCKET_NONE;
fresh[ins] = desc;
}- In
Heap.c:443:
return i;
}
return HEAP_BUCKET_NONE;
}- In
Heap.c:455:
return i;
}
return HEAP_BUCKET_NONE;
}- In
Heap.c:554:
// IS the warm one the next alloc will use, so we keep it. If there's
// any other warm page already, reclaiming this one is safe.
if (heap->class_warm_head[cls] == idx && d->next_warm == HEAP_BUCKET_NONE) {
return;
}- In
Heap.c:667:
u32 new_cap = heap->pages_cap ? heap->pages_cap * 2u : HEAP_PAGES_INITIAL_CAP;
if (!heap_hash_resize(heap, new_cap)) {
return HEAP_BUCKET_NONE;
}
}- In
Heap.c:678:
base = os_page_map(&heap->base, HEAP_OS_PAGE_SIZE);
if (!base)
return HEAP_BUCKET_NONE;
}
// Recycled pages keep whatever bytes the previous user wrote into
- In
Heap.c:696:
.used_count = 0u,
.class_idx = cls,
.prev_warm = HEAP_BUCKET_NONE,
.next_warm = HEAP_BUCKET_NONE,
};- In
Heap.c:697:
.class_idx = cls,
.prev_warm = HEAP_BUCKET_NONE,
.next_warm = HEAP_BUCKET_NONE,
};
heap_set_tail_bits(desc.bitmap, slots, bm_words);- In
Heap.c:733:
// Try to reclaim a retained mapping of the same os_pages count.
u32 fr_idx = heap_xl_freed_find_match(heap, (u32)os_pages);
if (fr_idx != HEAP_BUCKET_NONE) {
HeapPageXL ent = heap_xl_freed_swap_remove(heap, fr_idx);
ptr = ent.page;- In
Heap.c:801:
// head is guaranteed to have a free slot.
u32 idx = self->class_warm_head[cls];
if (idx == HEAP_BUCKET_NONE) {
idx = heap_grow_class(self, cls);
if (idx == HEAP_BUCKET_NONE) {- In
Heap.c:803:
if (idx == HEAP_BUCKET_NONE) {
idx = heap_grow_class(self, cls);
if (idx == HEAP_BUCKET_NONE) {
#if FEATURE_ALLOC_STATS
self->base.stats.failed_allocations += 1u;- In
Heap.c:840:
// branch on it to choose the right free path.
static size heap_recover_size(HeapAllocator *heap, void *ptr, u32 *idx_out, bool *is_xl_out) {
*idx_out = HEAP_BUCKET_NONE;
*is_xl_out = false;
if (!ptr)- In
Heap.c:850:
// trip the foreign-ptr abort, not silently fix up to the base.
u32 xi = heap_xl_in_use_find(heap, ptr);
if (xi != HEAP_BUCKET_NONE) {
*idx_out = xi;
*is_xl_out = true;- In
Heap.c:858:
void *page_base = (void *)((u64)ptr & ~(u64)(HEAP_PAGE_SIZE - 1u));
u32 b = heap_hash_lookup(heap->pages, heap->pages_cap - 1u, page_base);
if (b != HEAP_BUCKET_NONE) {
*idx_out = b;
return (size)heap_class_size[heap->pages[b].class_idx];- In
Heap.h:372:
// drift.
#define HEAP_CLASS_WARM_HEAD_NONE \
{HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \- In
Heap.h:373:
#define HEAP_CLASS_WARM_HEAD_NONE \
{HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \- In
Heap.h:374:
{HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
- In
Heap.h:375:
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
- In
Heap.h:376:
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
- In
Heap.h:377:
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE}- In
Heap.h:378:
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE}
_Static_assert(HEAP_NUM_CLASSES == 8, "HEAP_CLASS_WARM_HEAD_NONE has 8 entries; sync with HEAP_NUM_CLASSES");- In
Heap.h:379:
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE, \
HEAP_BUCKET_NONE}
_Static_assert(HEAP_NUM_CLASSES == 8, "HEAP_CLASS_WARM_HEAD_NONE has 8 entries; sync with HEAP_NUM_CLASSES");
Last updated on