From 3a9c8176173bda521470ea507cf5b14c4dbac79f Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 8 Dec 2023 18:13:43 +0100 Subject: [PATCH] Add primitive memory allocator --- std/str.alc | 77 ++++++++++++++++++++++++++++ std/sys/halloc.alc | 18 ------- std/sys/mem.alc | 125 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 18 deletions(-) delete mode 100644 std/sys/halloc.alc create mode 100644 std/sys/mem.alc diff --git a/std/str.alc b/std/str.alc index f7f8c54..24f2546 100644 --- a/std/str.alc +++ b/std/str.alc @@ -70,3 +70,80 @@ sub str_lower wend drop marine + +[Prints a numbers as a hex string] +[arg:int number to print] +[ret:void] +sub printx + swap + clone 2147483647 [32 bit signed max] > if + printx_64 + else + clone 65535 [16 bit signed max] > if + printx_32 + else + printx_16 + endif + endif +marine + +sub printx_16 + swap + mem 0 + 0 itoc write + mem 1 + 120 write + mem 2 + over 12 >> 15 & itoc write + mem 3 + over 8 >> 15 & itoc write + mem 4 + over 4 >> 15 & itoc write + mem 5 + over 0 >> 15 & itoc write + mem println + drop +marine + +sub printx_32 + swap + mem 0 + 0 itoc write + mem 1 + 120 write + mem 2 + over 28 >> 15 & itoc write + mem 3 + over 24 >> 15 & itoc write + mem 4 + over 20 >> 15 & itoc write + mem 5 + over 16 >> 15 & itoc write + mem 6 + over 12 >> 15 & itoc write + mem 7 + over 8 >> 15 & itoc write + mem 8 + over 4 >> 15 & itoc write + mem 9 + over 0 >> 15 & itoc write + mem println + drop +marine + +sub printx_64 + swap + mem 0 + 0 itoc write + mem 1 + 120 write + mem 2 + over 60 >> 15 & itoc write + mem 3 + over 56 >> 15 & itoc write + mem 4 + over 52 >> 15 & itoc write + mem 5 + over 48 >> 15 & itoc write + mem 6 + over 44 >> 15 & itoc write + mem 7 + over 40 >> 15 & itoc write + mem 8 + over 36 >> 15 & itoc write + mem 9 + over 32 >> 15 & itoc write + mem 10 + over 28 >> 15 & itoc write + mem 11 + over 24 >> 15 & itoc write + mem 12 + over 20 >> 15 & itoc write + mem 13 + over 16 >> 15 & itoc write + mem 14 + over 12 >> 15 & itoc write + mem 15 + over 8 >> 15 & itoc write + mem 16 + over 4 >> 15 & itoc write + mem 17 + over 0 >> 15 & itoc write + mem println + drop +marine + +[Converts an integer between 0-15 to the ASCII hex character] +[arg:int number to convert] +[ret:int ascii character] +sub itoc + swap clone 10 < if 48 + + else 55 + endif swap +marine + diff --git a/std/sys/halloc.alc b/std/sys/halloc.alc deleted file mode 100644 index 728b63f..0000000 --- a/std/sys/halloc.alc +++ /dev/null @@ -1,18 +0,0 @@ -include std.sys.panic -include std.io - -sub brk - swap 12 syscall1 sysread swap -marine - -sub curheap - 0 brk swap -marine - -sub halloc - swap curheap + brk - 0 < if - "Unable to increase heap memory" 1 1 syscall3 - 1 exit - endif -marine diff --git a/std/sys/mem.alc b/std/sys/mem.alc new file mode 100644 index 0000000..c47fa60 --- /dev/null +++ b/std/sys/mem.alc @@ -0,0 +1,125 @@ +include std.sys.call +include std.io +include std.math + +sub BLOCK_FREE 0 swap marine +sub BLOCK_USED 1 swap marine +sub PAGE_SIZE_BYTES 4096 swap marine +sub BLOCK_HEADER_SIZE 8 swap marine + +[Modifies the end address of the heap] +[arg:int New address in number of bytes] +[ret:ptr End address of heap] +sub brk + swap 12 syscall1 sysread swap +marine + +[Read the current end of the heap] +[ret:ptr End address of heap] +sub heap_end + 0 brk swap +marine + +[Increases the heap by a set amount of bytes.] +[arg:int number of bytes] +[ret:void] +sub incheap + swap heap_end + brk + 0 < if + "Unable to increase heap memory" println + 1 SYS_EXIT syscall1 + endif +marine + +[Initializes the memory allocator] +[ret:void] +sub mem_init + "Initializing heap allocator @ " print 0 brk printx + [Allocate first block (empty)] + [Dont allocate 0 bytes or this will break :)] + BLOCK_HEADER_SIZE incheap + heap_end BLOCK_HEADER_SIZE + BLOCK_FREE write + + 10000 incheap [Starting memory] + heap_end BLOCK_HEADER_SIZE - + BLOCK_FREE 10000 + BLOCK_HEADER_SIZE - BLOCK_HEADER_SIZE - write +marine + +[Coalesces adjacent free memory blocks] +[ret:void] +sub mem_coalesce +marine + + +[Allocates bytes on the heap] +[arg:int number of bytes to allocate] +[ret:ptr address of allocated block] +sub malloc + swap + heap_end BLOCK_HEADER_SIZE - + while 1 do + clone load 1 & BLOCK_FREE = if + [This block is free] + 2clone load < if + [This block is large enough] + clone load 18446744073709551614 & rev3 swap + 2clone swap BLOCK_USED + write + [Address magic] + swap clone rev3 swap - rev3 swap clone rev3 swap - swap rev3 swap over swap write + clone rev3 swap + clone + "New allocation:" println + " Header Address: " print printx + " Size: " print printx + + swap + return + else + [This block is too small] + clone load 18446744073709551614 & + clone 0 = if + "FATALERR Found last memory block. Not enough memory." println + 1 SYS_EXIT syscall1 + endif + - + endif + else + [This block is used] + clone load 18446744073709551614 & + clone 0 = if + "FATALERR Found last memory block. Not enough memory." println + 1 SYS_EXIT syscall1 + endif + - + endif + wend + [Should return early or exit with not enough memory] +marine + +[Deallocates a memory block on the heap] +[arg:ptr address of block header] +sub free + swap clone clone load 18446744073709551614 & write drop +marine + +sub mem_walk + "Starting memory walk at heap end: " print heap_end printx + heap_end BLOCK_HEADER_SIZE - + while 1 do + "Block: " print clone printx + clone load + " Free: " print + clone 1 & BLOCK_FREE = if + "Yes" println + else + "No" println + endif + " Size: " print clone 18446744073709551614 & printx + clone 18446744073709551614 & 0 = if + drop + drop + return + endif + " Next: " print 18446744073709551614 & - clone printx + wend + "==========" println +marine