From fbc57cad5622039654b95590ab1efb464984c71b Mon Sep 17 00:00:00 2001 From: Mirek Kratochvil Date: Tue, 31 Oct 2023 21:07:03 +0100 Subject: [PATCH] debug the gc --- apply.s | 2 +- apply_over.s | 2 +- fibs.s | 2 +- include/data.s | 80 ++++++++++++++++++++++++--------------------- include/gc.s | 35 ++++++++++++-------- include/main_exit.s | 7 ++-- print_123.s | 2 +- sum.s | 43 ++++++++++++++++++++++++ 8 files changed, 114 insertions(+), 59 deletions(-) create mode 100644 sum.s diff --git a/apply.s b/apply.s index 458822a..113122a 100644 --- a/apply.s +++ b/apply.s @@ -23,7 +23,7 @@ thunkto %r12, $print, $1, %r12 # make a continuation for main (exit) and set it for print call - thunkto %rsi, $main_exit, $1, %rsi + thunkto %rsi, $main_exit, $0 # start evaluating the print enter %r12 diff --git a/apply_over.s b/apply_over.s index 4e86d17..165b6f2 100644 --- a/apply_over.s +++ b/apply_over.s @@ -45,7 +45,7 @@ thunkto %r13, $print, $1, %r13 # make a continuation for main (exit) and set it for print call - thunkto %rsi, $main_exit, $1, %rsi + thunkto %rsi, $main_exit, $0 # start evaluating the print enter %r13 diff --git a/fibs.s b/fibs.s index f008dae..8c390fa 100644 --- a/fibs.s +++ b/fibs.s @@ -41,5 +41,5 @@ thunkto %r11, $INT_code, $20 thunkto %r11, $list_int_index, $2, %r11, %r12 thunkto %r11, $print, $1, %r11 - thunkto %rsi, $main_exit, $1, %rsi + thunkto %rsi, $main_exit, $0 enter %r11 diff --git a/include/data.s b/include/data.s index 3ee8213..575b4ae 100644 --- a/include/data.s +++ b/include/data.s @@ -1,6 +1,7 @@ .ifndef _data_s_file _data_s_file: + nop # Format of the info tables: # - code @@ -10,18 +11,21 @@ _data_s_file: # - 8B pointer to evacuate # # Evacuate interface: -# in: %rsi continuation, %rbp what to evacuate +# in: %rbp what to evacuate # out: %rbp where the thing is now +# ret: jump to _gc_evacuate_ret # Notes: # - IND thunks skip themselves on evacuate -# - checking if whether stuff is already in write region are managed by _gc_evacuate prelude +# - checking if whether stuff is already in write region are managed by +# _gc_evacuate prelude # # Scavenge interface: -# in: %rsi continuation, %rbp what to scavenge +# in: %rbp what to scavenge # out: %rbp next thing to scavenge in memory +# ret: jump to _gc_scavenge_ret # -# Saved registers by evacuate and scavenge -# - _uskel_gc needs to preserve %rdi now; that might increase +# Saved registers during the GC process: +# - _uskel_gc uses %r8-%r11 # - scavenges use %r12-%r15 # - %rax-%rdx is scratch and evacuate use @@ -31,10 +35,10 @@ INT_evacuate: pushq 010(%rbp) pushq $INT_code mov %rsp,%rbp - jmp *%rsi + jmp _gc_evacuate_ret INT_scavenge: add $020, %rbp - jmp *%rsi + jmp _gc_scavenge_ret INT_info_table: cell INT_evacuate @@ -49,7 +53,9 @@ IND_evacuate: mov 010(%rbp), %rbp jmp _gc_evacuate IND_scavenge: - jmp 0 # thou shalt not scavenge here + # this should never be triggered but let's play it safe + add $020, %rbp + jmp _gc_scavenge_ret IND_info: cell IND_evacuate @@ -69,17 +75,17 @@ LIST_evacuate: pushq $1 pushq $LIST_code mov %rsp, %rbp - jmp *%rsi + jmp _gc_evacuate_ret + LIST_evacuate_nil: pushq $0 pushq $LIST_code mov %rsp, %rbp - jmp *%rsi + jmp _gc_evacuate_ret LIST_scavenge: cmpq $0, 010(%rbp) je LIST_scavenge_nil mov %rbp, %r15 - mov %rsi, %r14 mov $LIST_scavenge1, %rsi mov 020(%r15), %rbp @@ -95,10 +101,11 @@ LIST_scavenge: mov %r15, %rbp add $040, %rbp - jmp *%r14 + jmp _gc_scavenge_ret + LIST_scavenge_nil: add $020, %rbp - jmp *%rsi + jmp _gc_scavenge_ret LIST_info_table: cell LIST_evacuate @@ -160,15 +167,14 @@ FUN4_code: # | ptr | args | arg[0] | arg[1] | ... | arg[args] | # args wouldn't need to be here but let's keep them for gc simplicity THU_evacuate: - mov 010(%rbp), %rbx - mov %rbx,%rdx - mov %rbx,%rcx + mov 010(%rbp), %rbx # rbx = count of arguments + mov %rbx, %rdx + mov %rbx, %rcx # rcx = count of arguments for later looping add $2, %rdx shl $3, %rdx - add %rbp, %rdx + add %rbp, %rdx # rdx = address of the argument THU_evacuate_one: - dec %rcx - cmp $0, %rcx + sub $1, %rcx jl THU_evacuate_fini sub $010, %rdx pushq (%rdx) @@ -177,32 +183,32 @@ THU_evacuate: pushq %rbx pushq 000(%rbp) mov %rsp, %rbp - jmp *%rsi + jmp _gc_evacuate_ret THU_scavenge: - mov 010(%rbp), %r12 - mov %rbp, %r15 - mov %rsi, %r14 - mov %r12,%r13 - add $2, %r13 - shl $3, %r13 - add %r15, %r13 + mov 010(%rbp), %r13 # r13 = count of arguments (for looping) + mov %rbp, %r15 # r15 = scavengee ptr + mov %r13,%r14 + add $2, %r14 + shl $3, %r14 + add %r15, %r14 # r14 = address of argument + THU_scavenge_one: - sub $010, %r13 - sub $1, %r12 + sub $1, %r13 jl THU_scavenge_fini - mov (%r13), %rbp + sub $010, %r14 + mov (%r14), %rbp mov $THU_scavenge_one_cont, %rsi jmp _gc_evacuate THU_scavenge_one_cont: - mov %rbp, (%r13) + mov %rbp, (%r14) jmp THU_scavenge_one THU_scavenge_fini: - mov %r15, %rbp - mov 010(%rbp), %r13 - add $2, %r13 - shl $3, %r13 - add %r13, %rbp - jmp *%r14 + mov %r15, %rbp # restore rbp + mov 010(%rbp), %r14 + add $2, %r14 + shl $3, %r14 # r14 is size of object + add %r14, %rbp # move rbp to next rbp + jmp _gc_scavenge_ret .endif # _data_s_file diff --git a/include/gc.s b/include/gc.s index 636a6a2..ae71d5c 100644 --- a/include/gc.s +++ b/include/gc.s @@ -74,6 +74,8 @@ _uskel_alloc: cmp %r14, %rax cmova %rax, %r14 + and $0xfffffffffffffff8, %r14 #align + alloc_goes_mmap: mov $9, %rax # mmap mov $0, %rdi # addr = NULL @@ -94,7 +96,7 @@ _uskel_alloc: _uskel_gc_init: mov %rsi, %r13 - movq $0x100, _gc_min_alloc + movq $0x100, _gc_min_alloc # must be higher than 2x the biggest thunk possible movq $0x180, _gc_grow_ratio movq $0x40, _gc_shrink_ratio mov $0, %rsp # fake original rsp for first alloc run @@ -121,7 +123,7 @@ _uskel_gc: # point the writer to the new memory area mov _write_region_end, %rsp - mov %rsp, %rdi # %rdi is "the last scavenged thing" + mov %rsp, %r8 # % r8 is the "last thing that was scavenged" # start by evacuating the thunk and cont mov _gc_backup_thunk, %rbp @@ -139,27 +141,26 @@ _uskel_gc: # scavenge everything _uskel_gc_scavenge: # start at what we wrote last - mov %rsp, %rbp + mov %rsp, %rbp # rbp is the iterator (conveniently) + mov %rsp, %r9 # % r9 stores where we started with this evacuate round # if the thing is already scavenged, we didn't write anything, mark done. - cmp %rbp, %rdi + cmp %rbp, %r8 jbe _uskel_gc_scavenge_end _uskel_gc_scavenge1: # if all ok, scavenge one thing (moving %rbp) and recheck - mov $_uskel_gc_scavenge1_ret, %rsi mov (%rbp), %rax jmp *-020(%rax) # scavenge position in infotable - _uskel_gc_scavenge1_ret: - cmp %rbp, %rdi + _gc_scavenge_ret: + cmp %rbp, %r8 ja _uskel_gc_scavenge1 - # everything above rsp is now scavenged, continue with next round - mov %rsp, %rdi + # everything above r9 is now scavenged, continue with next round + mov %r9, %r8 # we started at r9, so that is now "done" jmp _uskel_gc_scavenge _uskel_gc_scavenge_end: - # deallocate the old memory region mov $11, %rax # munmap mov _gc_region_end, %rsi @@ -188,14 +189,22 @@ _uskel_gc: _gc_evacuate: # check if we are really out of the target region cmp _write_region_start, %rbp - jb _gc_evacuate_ok + jb _gc_evacuate_go cmp _write_region_end, %rbp - jae _gc_evacuate_ok + jae _gc_evacuate_go + _gc_evacuate_skip: # if not, let's just jump to cont and leave %rbp as result jmp *%rsi - _gc_evacuate_ok: + _gc_evacuate_go: # if we should evacuate, jump to the evac routine + mov %rbp, %r10 mov (%rbp), %rax jmp *-030(%rax) + _gc_evacuate_ret: + # install the indirection + movq $IND_code, 000(%r10) + mov %rbp, 010(%r10) + jmp *%rsi + .endif #_gc_s_file diff --git a/include/main_exit.s b/include/main_exit.s index 1a38e5a..5ce6c76 100644 --- a/include/main_exit.s +++ b/include/main_exit.s @@ -1,13 +1,10 @@ .ifndef _main_exit_s_file _main_exit_s_file: -# exitcode -> | cont (unused, should be 0) | +# exitcode -> || .thunkcode main_exit - mov 010(%rsi), %rdi # result goes to syscall exitcode + mov 010(%rsi), %rdi # result INT goes to syscall exitcode mov $60, %rax # exit=60 syscall # exit %rdi -# TODO this is a "case" kind of thunk so it's quite likely that it really -# doesn't need the continuation. - .endif # _main_exit_s_file diff --git a/print_123.s b/print_123.s index 35c9cbe..c838d89 100644 --- a/print_123.s +++ b/print_123.s @@ -21,7 +21,7 @@ thunkto %r11, $print, $1, %r11 # push a cont thunk for main_exit and set continuation for main_exit - thunkto %rsi, $main_exit, $1, %rsi + thunkto %rsi, $main_exit, $0 # evaluate into main_exit enter %r11 diff --git a/sum.s b/sum.s new file mode 100644 index 0000000..4cc709f --- /dev/null +++ b/sum.s @@ -0,0 +1,43 @@ + + +.include "include/uskel.s" + +.include "include/data.s" +.include "include/io.s" +.include "include/intops.s" + +.primop1 sumn + needs_alloc $0110 + + mov 010(%rsi), %rax + test %rax, %rax + jz sumn_zero + + dec %rax + thunkto %r10, $INT_code, %rax + thunkto %r10, $sumn, $1, %r10 + thunkto %r10, $plus, $2, %rsi, %r10 #TODO try the other way? + primop1_cont_indirect %r10 + + sumn_zero: + primop1_ret_int $0 + +# || -> cont +.thunkcode main + needs_alloc $0160 + # push a new integer + thunkto %r11, $INT_code, $10000000 + + # push the plus + thunkto %r11, $sumn, $1, %r11 + + # push the print + thunkto %r11, $print, $1, %r11 + + # push a cont thunk for main_exit + thunkto %rsi, $main_exit, $0 + + # evaluate into main_exit + enter %r11 + +.include "include/main_exit.s"