aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMirek Kratochvil <exa.exa@gmail.com>2023-10-31 21:07:03 +0100
committerMirek Kratochvil <exa.exa@gmail.com>2023-10-31 21:07:03 +0100
commitfbc57cad5622039654b95590ab1efb464984c71b (patch)
treebcc251ff37486ae297615723faf45bbb5e92bedb /include
parent2bc3d9a3815a6cd172b3b4f7696c46a006021b13 (diff)
downloaduskel-fbc57cad5622039654b95590ab1efb464984c71b.tar.gz
uskel-fbc57cad5622039654b95590ab1efb464984c71b.tar.bz2
debug the gc
Diffstat (limited to 'include')
-rw-r--r--include/data.s80
-rw-r--r--include/gc.s35
-rw-r--r--include/main_exit.s7
3 files changed, 67 insertions, 55 deletions
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