update vec to use bump allocator, update bump allocator to use mmap for its vec growing

This commit is contained in:
janis 2025-11-04 01:54:51 +01:00
parent d276dd9d88
commit 22d85c1473
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
4 changed files with 105 additions and 33 deletions

View file

@ -15,6 +15,7 @@ extern allocate
extern vec_init
extern vec_push
extern vec_get
extern vec_try_grow_with
global bump_init
@ -29,14 +30,21 @@ mmap_alloc:
pop rbp
ret
;; define-fn: fn bump_init()
bump_init:
push rbp
mov rbp, rsp
lea rdi, [rel free_list]
mov rsi, 16
mov rdx, 0
call vec_init
mov rdi, 0x1000
call mmap_alloc
lea rdx, [rel free_list]
mov [rdx], rax
mov qword [rdx + 8], 0 ; size 0
mov rax, 0x1000
shr rax, 4 ; capacity in blocks of 16 bytes
mov qword [rdx + 16], rax ; capacity
mov qword [rdx + 24], 16 ; elem_size = 16
mov qword [rdx + 32], 0 ; drop = None
pop rbp
ret
@ -50,6 +58,20 @@ bump_new_block:
ja .mmap
mov rdi, 4096
.mmap:
push rdi
lea rdi, [rel free_list]
mov rsi, [rdi + 8]
mov rax, rsi
shr rax, 1
add rax, 1
add rsi, rax
mov rdx, mmap_alloc
call vec_try_grow_with
pop rdi
; next power of 2
lea rax, [rdi - 1]
lzcnt rax, rax
@ -75,8 +97,38 @@ bump_new_block:
pop rbp
ret
;; rdi: num
;; rsi: multiple
next_multiple_of:
test rsi, rsi
je .l1
mov rax, rdi
or rax, rsi
shr rax, 32
je .l2
mov rax, rdi
xor edx, edx
div rsi
jmp .l3
.l2:
mov eax, edi
xor edx, edx
div esi
.l3:
sub rsi, rdx
test rdx, rdx
cmove rsi, rdx
add rsi, rdi
mov rax, rsi
ret
.l1:
mov rax, rdi
ret
;; rdi: number of bytes to allocate
;; rsi: alignment
;; define-fn: fn bump_alloc(size: usize, alignment: usize) -> *mut u8
bump_alloc:
push rbp
mov rbp, rsp
@ -104,25 +156,21 @@ bump_alloc:
; check for space
; block_ptr.next_multiple_of(alignment) + size <= block_ptr + block_size
mov rcx, [rsp + 8] ; alignment
; let ptr = block_ptr | alignment
or rax, rcx ; align up
xor rdx, rdx ; clear high qword
; let rem = ptr % alignment
div rcx
; let diff = alignment - rem
sub rcx, rdx
mov rax, [rsp + 16] ; block+ptr
; let aligned_ptr = block_ptr + diff
add rax, rcx
; let aligned_end = aligned_ptr + size
add rax, [rsp] ; size
; let block_end = block_ptr + block_size
mov rdx, [rsp + 16] ; block_ptr
add rdx, [rsp + 24] ; block_ptr + block_size
; if aligned_end <= block_end
cmp rax, rdx
mov rdi, rdx
mov rsi, [rsp + 8] ; alignment
call next_multiple_of
; rax = aligned_ptr
mov rdx, rax
add rdx, qword [rsp] ; ptr + size
; rdx = new_end
mov rcx, [rsp + 16] ; block_ptr
add rcx, [rsp + 24] ; block_size
cmp rdx, rcx
jle .found_space
; else try next block
inc r13
jmp .alloc_loop
@ -136,13 +184,17 @@ bump_alloc:
dec r13
jmp .alloc_loop
.found_space:
sub rdx, rax ; remaining size in block
mov r13, [rsp + 32] ; block entry ptr
mov [r13], rax
mov rax, [rsp + 24] ; block_size
sub rax, rdx
mov [r13 + 8], rax
mov rax, [r13]
mov r12, [rsp + 32] ; block entry ptr
mov rcx, [r12] ; block_ptr
mov [r12], rdx ; update block_ptr
; new_end - old_ptr
sub rdx, rcx
mov rcx, [r12 + 8] ; block_size
sub rcx, rdx
mov [r12 + 8], rcx
add rsp, 0x28
pop r13
pop r12

View file

@ -8,7 +8,7 @@ extern memswap
extern oom
extern panic
extern eprint_str
extern allocate
extern bump_alloc
global vec_init
global vec_init_with
@ -26,6 +26,8 @@ global vec_insert
global vec_insert_many
global vec_insert_sorted
global vec_binary_search_by
global vec_try_grow
global vec_try_grow_with
global vec_tests
@ -57,7 +59,8 @@ vec_init:
push rdi
; (*vec).data = allocate(INIT_CAPACITY);
mov rdi, INIT_CAPACITY
call allocate
mov rsi, 8
call bump_alloc
pop r15
mov [r15], rax
; (*vec).len = 0;
@ -94,7 +97,8 @@ vec_init_with:
mov rax, rcx
mul rsi ; capacity * item_size
mov rdi, rax
call allocate
mov rsi, 8
call bump_alloc
pop r15
mov [r15], rax
; (*vec).len = 0;
@ -339,6 +343,16 @@ vec_remove:
;; rsi: desired size
;; fn vec_try_grow(vec: *mut Vec, new_size: usize) -> bool
vec_try_grow:
mov rdx, bump_alloc
call vec_try_grow_with
ret
;; essentially a reserve() function
;; rdi: pointer to Vec struct
;; rsi: desired size
;; rdx: allocate function pointer
;; fn vec_try_grow(vec: *mut Vec, new_size: usize) -> bool
vec_try_grow_with:
push rbp
mov rbp, rsp
push rbx
@ -366,7 +380,8 @@ vec_try_grow:
mul qword [rdi + 24] ; new_capacity * item_size
; new_data = allocate(new_capacity);
mov rdi, rax
call allocate
mov rsi, 8
call rdx
mov [rsp + 16], rax
mov rdi, [rsp]
; memcpy(new_data, old_data, len * vec.item_size);

View file

@ -2,6 +2,8 @@
// Auto-generated Rust bindings from assembly source
unsafe extern "C" {
pub unsafe fn bump_init();
pub unsafe fn bump_alloc(size: usize, alignment: usize) -> *mut u8;
pub unsafe fn parse_func(ast: *mut Ast) -> u64;
pub unsafe fn parse_args(ast: *mut Ast) -> (*const u64, usize);
pub unsafe fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool);

View file

@ -4,6 +4,9 @@ mod util;
use util::{ffi::*, vec::Vec, BlobVec};
fn main() {
unsafe {
util::defs::bump_init();
}
static mut DROPS: usize = 1;
fn get_drops() -> usize {
unsafe { (&raw const DROPS).read() }