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

View file

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

View file

@ -2,6 +2,8 @@
// Auto-generated Rust bindings from assembly source // Auto-generated Rust bindings from assembly source
unsafe extern "C" { 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_func(ast: *mut Ast) -> u64;
pub unsafe fn parse_args(ast: *mut Ast) -> (*const u64, usize); pub unsafe fn parse_args(ast: *mut Ast) -> (*const u64, usize);
pub unsafe fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool); 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}; use util::{ffi::*, vec::Vec, BlobVec};
fn main() { fn main() {
unsafe {
util::defs::bump_init();
}
static mut DROPS: usize = 1; static mut DROPS: usize = 1;
fn get_drops() -> usize { fn get_drops() -> usize {
unsafe { (&raw const DROPS).read() } unsafe { (&raw const DROPS).read() }