PageEntry
Description
Per-live-allocation descriptor. The byte count is the rounded mmap length (a multiple of the OS page size), which is what munmap / VirtualFree need. The user pointer is the mmap’d base address.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Page.h:39:
void *ptr;
size bytes;
} PageEntry;
///
- In
Page.h:80:
Allocator base;
size cached_page_size;
PageEntry *entries;
u32 len;
u32 cap;- In
Page.h:84:
u32 cap;
size entries_bytes;
PageEntry *free_entries;
u32 free_len;
u32 free_cap;- In
Page.c:70:
LOG_FATAL("PageAllocator: entries / entries_bytes mismatch");
}
if (pg->entries && pg->entries_bytes < (size)pg->cap * sizeof(PageEntry)) {
LOG_FATAL(
"PageAllocator: entries_bytes {} too small for cap {} (need {})",- In
Page.c:75:
(u64)pg->entries_bytes,
(u64)pg->cap,
(u64)((size)pg->cap * sizeof(PageEntry))
);
}- In
Page.c:165:
// detection on the live-region path; the retained-region table is
// sorted by `bytes` and uses `page_free_find_size_match` instead.
static u32 page_find_idx_sorted(const PageEntry *arr, u32 len, const void *ptr) {
u32 lo = 0, hi = len;
while (lo < hi) {- In
Page.c:185:
// field pointers so the same helper grows either `entries` or
// `free_entries`. Returns false on OS-allocation failure or overflow.
static bool page_table_grow_into(PageAllocator *page, PageEntry **arr_p, u32 *len_p, u32 *cap_p, size *bytes_p) {
size page_size = PageAllocatorPageSize(page);
size want_bytes;- In
Page.c:199:
return false;
}
PageEntry *new_table = (PageEntry *)os_page_map(&page->base, new_rounded);
if (!new_table) {
return false;- In
Page.c:204:
}
if (*arr_p) {
MemCopy(new_table, *arr_p, (size)*len_p * sizeof(PageEntry));
os_page_unmap(&page->base, *arr_p, *bytes_p);
}- In
Page.c:209:
*arr_p = new_table;
*bytes_p = new_rounded;
*cap_p = (u32)(new_rounded / sizeof(PageEntry));
PAGE_MARK_DIRTY(page);
return true;- In
Page.c:218:
static bool page_table_insert_sorted(
PageAllocator *page,
PageEntry **arr_p,
u32 *len_p,
u32 *cap_p,- In
Page.c:228:
return false;
}
PageEntry *arr = *arr_p;
u32 lo = 0;
u32 hi = *len_p;- In
Page.c:242:
u32 to_move = *len_p - ins;
if (to_move > 0u) {
MemMove(&arr[ins + 1u], &arr[ins], (size)to_move * sizeof(PageEntry));
}
arr[ins].ptr = ptr;- In
Page.c:253:
// down by one. Order in both `entries` and `free_entries` IS load-bearing
// because we binary-search both.
static void page_table_remove_sorted_at(PageEntry *arr, u32 *len_p, u32 idx) {
*len_p -= 1u;
u32 to_move = *len_p - idx;- In
Page.c:257:
u32 to_move = *len_p - idx;
if (to_move > 0u) {
MemMove(&arr[idx], &arr[idx + 1u], (size)to_move * sizeof(PageEntry));
}
}- In
Page.c:289:
return false;
}
PageEntry *arr = page->free_entries;
u32 lo = 0;
u32 hi = page->free_len;- In
Page.c:303:
u32 to_move = page->free_len - ins;
if (to_move > 0u) {
MemMove(&arr[ins + 1u], &arr[ins], (size)to_move * sizeof(PageEntry));
}
arr[ins].ptr = ptr;
Last updated on