heap-libc.ha (1711B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 // A group of blocks that were allocated together. 5 export type chunk = union { 6 padding: size, // TODO: track number of active allocations here 7 data: [*]u8, 8 }; 9 10 // Metadata for a block. 11 export type meta = struct { 12 union { 13 sz: size, 14 next: uintptr, 15 }, 16 user: [*]u8, 17 }; 18 19 export type memory_heap = struct { 20 // Number of allocations currently in flight. 21 cur_allocs: size, 22 // Freelists for blocks up to 2048 bytes. 23 bins: [9]nullable *meta, 24 // The chunk to allocate from if there are no blocks available in the 25 // right freelist. 26 cur_chunk: (*chunk, size), 27 }; 28 29 // An empty memory heap, used to initialize a [[memory_heap]] for use with 30 // [[setheap]]. 31 export def EMPTY_HEAP = memory_heap { 32 cur_allocs = 0, 33 bins = [null...], 34 cur_chunk = (null: *chunk, CHUNKSZ), 35 }; 36 37 let static_heap = EMPTY_HEAP; 38 let heap = &static_heap; 39 40 // Switches the internal runtime allocator to a new memory heap. The caller 41 // should provision a [[memory_heap]] initialized to [[EMPTY_HEAP]] somehow 42 // (statically, or in a second memory_heap, or even on the stack if you're brave 43 // enough) and pass it to this function to enable it. Returns a pointer to the 44 // heap which was previously in use, should you wish to restore it later. 45 // 46 // The caller is responsible for ensuring that any use of free() or delete() 47 // makes use of an object which was allocated (via alloc(), insert(), or 48 // append()) from the same heap. 49 // 50 // This function is designed for debugging use, and exists in particular to 51 // satisfy the needs of [[debug::]]. 52 export fn setheap(new_heap: *memory_heap) *memory_heap = { 53 const old = heap; 54 heap = new_heap; 55 return old; 56 };