...
This commit is contained in:
@@ -42,6 +42,7 @@ public class Generator
|
|||||||
{
|
{
|
||||||
_builder.AppendLine("global _start");
|
_builder.AppendLine("global _start");
|
||||||
|
|
||||||
|
_builder.AppendLine("extern gc_init");
|
||||||
_builder.AppendLine("extern gc_alloc");
|
_builder.AppendLine("extern gc_alloc");
|
||||||
_builder.AppendLine("extern str_cmp");
|
_builder.AppendLine("extern str_cmp");
|
||||||
foreach (var externFuncDefinition in _definitions.OfType<ExternFuncDefinitionNode>())
|
foreach (var externFuncDefinition in _definitions.OfType<ExternFuncDefinitionNode>())
|
||||||
@@ -51,11 +52,12 @@ public class Generator
|
|||||||
|
|
||||||
_builder.AppendLine();
|
_builder.AppendLine();
|
||||||
_builder.AppendLine("section .text");
|
_builder.AppendLine("section .text");
|
||||||
|
|
||||||
// TODO: Only add start label if entrypoint is present, otherwise assume library
|
// TODO: Only add start label if entrypoint is present, otherwise assume library
|
||||||
var main = _symbolTable.ResolveLocalFunc(Entrypoint, []);
|
var main = _symbolTable.ResolveLocalFunc(Entrypoint, []);
|
||||||
|
|
||||||
_builder.AppendLine("_start:");
|
_builder.AppendLine("_start:");
|
||||||
|
_builder.AppendLine(" call gc_init");
|
||||||
_builder.AppendLine($" call {main.StartLabel}");
|
_builder.AppendLine($" call {main.StartLabel}");
|
||||||
|
|
||||||
_builder.AppendLine(main.ReturnType.HasValue
|
_builder.AppendLine(main.ReturnType.HasValue
|
||||||
|
|||||||
@@ -1,75 +1,28 @@
|
|||||||
global gc_init, gc_alloc, gc_free, gc_collect
|
global gc_init, gc_alloc
|
||||||
extern itoa
|
|
||||||
extern str_len
|
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
alloc_list: resq 1
|
alloc_list: resq 1
|
||||||
stack_start: resq 1
|
stack_start: resq 1
|
||||||
|
total_alloc: resq 1
|
||||||
; TMP
|
|
||||||
|
|
||||||
section .data
|
section .data
|
||||||
newline: db 10, 0
|
gc_threshold: dq 4096 ; default of 4096 bytes, this will scale when gc_collect is ran
|
||||||
start_mark: db "Starting to mark", 0
|
|
||||||
marked: db "Marked object", 0
|
|
||||||
|
|
||||||
; /TMP
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
; TMP
|
|
||||||
|
|
||||||
print_int:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
sub rsp, 8
|
|
||||||
mov [rbp - 8], rdi
|
|
||||||
mov rax, [rbp - 8]
|
|
||||||
push rax
|
|
||||||
pop rdi
|
|
||||||
call itoa
|
|
||||||
push rax
|
|
||||||
pop rdi
|
|
||||||
call print
|
|
||||||
mov rdi, newline
|
|
||||||
call print
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
|
|
||||||
print:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
sub rsp, 8
|
|
||||||
mov [rbp - 8], rdi
|
|
||||||
mov rax, 1
|
|
||||||
push rax
|
|
||||||
mov rax, 1
|
|
||||||
push rax
|
|
||||||
mov rax, [rbp - 8]
|
|
||||||
push rax
|
|
||||||
mov rax, [rbp - 8]
|
|
||||||
push rax
|
|
||||||
pop rdi
|
|
||||||
call str_len
|
|
||||||
push rax
|
|
||||||
pop rdx
|
|
||||||
pop rsi
|
|
||||||
pop rdi
|
|
||||||
pop rax
|
|
||||||
syscall
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
|
|
||||||
; /TMP
|
|
||||||
|
|
||||||
gc_init:
|
gc_init:
|
||||||
mov [stack_start], rsp
|
mov [stack_start], rsp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
gc_alloc:
|
gc_alloc:
|
||||||
add rdi, 17 ; add space for metadata
|
add rdi, 17 ; add space for metadata
|
||||||
|
mov rdx, [total_alloc] ; load total allocation
|
||||||
|
cmp rdx, [gc_threshold] ; has total exceeded threshold?
|
||||||
|
jb .no_collect ; no? skip
|
||||||
|
push rdi
|
||||||
|
call gc_collect
|
||||||
|
pop rdi
|
||||||
|
.no_collect:
|
||||||
|
add [total_alloc], rdi ; save total allocation
|
||||||
push rdi
|
push rdi
|
||||||
call sys_mmap ; allocate size + metadata
|
call sys_mmap ; allocate size + metadata
|
||||||
pop rdi
|
pop rdi
|
||||||
@@ -106,6 +59,7 @@ gc_free:
|
|||||||
mov [rsi + 9], rdx ; Bypass rdi in the list
|
mov [rsi + 9], rdx ; Bypass rdi in the list
|
||||||
.free_memory:
|
.free_memory:
|
||||||
mov rsi, [rdi + 1] ; Get object size
|
mov rsi, [rdi + 1] ; Get object size
|
||||||
|
sub [total_alloc], rsi ; save total allocation
|
||||||
call sys_munmap ; Free memory
|
call sys_munmap ; Free memory
|
||||||
ret
|
ret
|
||||||
.not_found:
|
.not_found:
|
||||||
@@ -114,6 +68,12 @@ gc_free:
|
|||||||
gc_collect:
|
gc_collect:
|
||||||
call gc_mark_stack
|
call gc_mark_stack
|
||||||
call gc_sweep
|
call gc_sweep
|
||||||
|
; next threshold will be double of used memory or 4096, whichever is higher
|
||||||
|
mov rdi, [total_alloc]
|
||||||
|
shl rdi, 1
|
||||||
|
mov rsi, 4096
|
||||||
|
call max
|
||||||
|
mov qword [gc_threshold], rax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
gc_mark_stack:
|
gc_mark_stack:
|
||||||
@@ -147,7 +107,7 @@ gc_mark:
|
|||||||
jnz .done ; yes? return
|
jnz .done ; yes? return
|
||||||
mov byte [rdi - 17], 1 ; mark object
|
mov byte [rdi - 17], 1 ; mark object
|
||||||
mov rcx, [rdi + 1] ; load object size
|
mov rcx, [rdi + 1] ; load object size
|
||||||
lea rdx, [rdi + 17] ; start of data
|
mov rdx, rdi ; start of data
|
||||||
add rcx, rdx ; end of data
|
add rcx, rdx ; end of data
|
||||||
.scan_object:
|
.scan_object:
|
||||||
cmp rdx, rcx ; done scanning?
|
cmp rdx, rcx ; done scanning?
|
||||||
@@ -168,13 +128,13 @@ gc_sweep:
|
|||||||
test al, al ; is object marked?
|
test al, al ; is object marked?
|
||||||
jz .free ; no? free it
|
jz .free ; no? free it
|
||||||
mov byte [rdi], 0 ; yes? clear mark for next scan
|
mov byte [rdi], 0 ; yes? clear mark for next scan
|
||||||
mov rdi, [rdi + 9]
|
mov rdi, [rdi + 9] ; load the next object in the list
|
||||||
jmp .loop
|
jmp .loop ; repeat
|
||||||
.free:
|
.free:
|
||||||
mov rcx, [rdi + 9]
|
mov rcx, [rdi + 9] ; save address of next object in list
|
||||||
push rcx
|
push rcx
|
||||||
call gc_free
|
call gc_free
|
||||||
pop rdi
|
pop rdi ; [rdi + 9] is deallocated now, and would throw a segfault unless we used the stack
|
||||||
jmp .loop
|
jmp .loop
|
||||||
.done:
|
.done:
|
||||||
ret
|
ret
|
||||||
@@ -205,4 +165,13 @@ sys_munmap:
|
|||||||
.error:
|
.error:
|
||||||
mov rax, 60
|
mov rax, 60
|
||||||
mov rdi, 1
|
mov rdi, 1
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
|
max:
|
||||||
|
cmp rdi, rsi
|
||||||
|
jae .left
|
||||||
|
mov rax, rsi
|
||||||
|
ret
|
||||||
|
.left:
|
||||||
|
mov rax, rdi
|
||||||
|
ret
|
||||||
Reference in New Issue
Block a user