aboutsummaryrefslogtreecommitdiff
path: root/include/data.s
diff options
context:
space:
mode:
Diffstat (limited to 'include/data.s')
-rw-r--r--include/data.s272
1 files changed, 217 insertions, 55 deletions
diff --git a/include/data.s b/include/data.s
index 2c512d4..35c4c8d 100644
--- a/include/data.s
+++ b/include/data.s
@@ -1,14 +1,7 @@
.ifndef _data_s_file
_data_s_file:
-
-# Simple values and boxed machine integers
-# | ptr | value |
-CON_evacuate1:
- retq # TODO
-CON_scavenge1:
- add $020, %rsi
- retq
+ nop # avoid confusing gdb
# Format of the info tables:
# - code
@@ -16,27 +9,160 @@ CON_scavenge1:
# - 8B helper information for eval/apply (generally this is 0, and only gets used for FUN/PAP)
# - 8B pointer to scavenge
# - 8B pointer to evacuate
+#
+# Evacuate interface:
+# 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
+#
+# Scavenge interface:
+# in: %rbp what to scavenge
+# out: %rbp next thing to scavenge in memory
+# ret: jump to _gc_scavenge_ret
+#
+# Saved registers during the GC process:
+# - _uskel_gc uses %r8-%r11
+# - scavenges use %r12-%r15
+# - %rax-%rdx is scratch and evacuate use
+
+# Simple values and boxed machine integers
+# | ptr | value |
+INT_evacuate:
+ pushq 010(%rbp)
+ pushq $INT_code
+ mov %rsp,%rbp
+ jmp _gc_evacuate_ret
+INT_scavenge:
+ add $020, %rbp
+ jmp _gc_scavenge_ret
INT_info_table:
- cell CON_evacuate1
- cell CON_scavenge1
+ cell INT_evacuate
+ cell INT_scavenge
cell 0
INT_code:
continue
+# Indirection
+# | ptr | indptr |
+IND_evacuate:
+ mov 010(%rbp), %rbp
+ jmp _gc_evacuate
+IND_scavenge:
+ # this should never be triggered but let's play it safe
+ add $020, %rbp
+ jmp _gc_scavenge_ret
+
+IND_info:
+ cell IND_evacuate
+ cell IND_scavenge
+ cell 0
+IND_code:
+ enter 010(%rbp)
+
+# Blackhole (contains the original thunkptr for debugging purposes)
+# | ptr | orig_thunkptr |
+BLE_evacuate:
+ jmp _gc_evacuate_ret
+BLE_scavenge:
+ jmp _gc_scavenge_ret
+
+BLE_info_table:
+ cell BLE_evacuate
+ cell BLE_scavenge
+ cell 0
+BLE_code:
+ # if we hit this, we've got a pure loop in a program, and it is never
+ # going to actually progress. So let's just shoot it down with a
+ # helpful message or so.
+ mov 010(%rbp), %r15
+
+ mov $1, %rdi #stdout
+
+ mov $14, %rdx
+ mov $BLE_msg, %rsi
+ mov $1, %rax #write
+ syscall
+
+ mov $1, %rdx
+ BLE_loop:
+ mov %r15, %rcx
+ and $0xf, %rcx
+ mov $BLE_hex, %rsi
+ add %rcx, %rsi
+ mov $1, %rax
+ syscall
+ shr $4, %r15
+ jnz BLE_loop
+
+ mov $BLE_nl, %rsi
+ mov $1, %rax
+ syscall
+
+ # shot self down (and retry if it doesn't succeed)
+ BLE_retry_sigkill:
+ mov $39, %rax
+ syscall # getpid
+ mov %rax, %rdi
+ mov $6, %rsi # SIGABRT
+ mov $62, %rax # kill
+ syscall
+ jmp BLE_retry_sigkill
+
+BLE_msg:
+ .ascii "diverged at 0x"
+BLE_hex:
+ .ascii "0123456789abcdef"
+BLE_nl:
+ .ascii "\n"
+
# List
-# | ptr | 0 |
-# | ptr | 1 | a | b |
+# | ptr | 0 | # [] case
+# | ptr | 1 | a | b | # (a:b) case
LIST_evacuate:
- # [] | a : b
- retq #TODO
+ cmpq $0, 010(%rbp)
+ je LIST_evacuate_nil
+ pushq 030(%rbp)
+ pushq 020(%rbp)
+ pushq $1
+ pushq $LIST_code
+ mov %rsp, %rbp
+ jmp _gc_evacuate_ret
+
+ LIST_evacuate_nil:
+ pushq $0
+ pushq $LIST_code
+ mov %rsp, %rbp
+ jmp _gc_evacuate_ret
LIST_scavenge:
- mov 010(%rbp), %rax
- shl $1, %rax
- add $2, %rax
- shl $3, %rax
- add %rax, %rsi
- retq
+ cmpq $0, 010(%rbp)
+ je LIST_scavenge_nil
+ mov %rbp, %r15
+
+ mov $LIST_scavenge1, %rsi
+ mov 020(%r15), %rbp
+ jmp _gc_evacuate
+ LIST_scavenge1:
+ mov %rbp, 020(%r15)
+
+ mov $LIST_scavenge2, %rsi
+ mov 030(%r15), %rbp
+ jmp _gc_evacuate
+ LIST_scavenge2:
+ mov %rbp, 030(%r15)
+
+ mov %r15, %rbp
+ add $040, %rbp
+ jmp _gc_scavenge_ret
+
+ LIST_scavenge_nil:
+ add $020, %rbp
+ jmp _gc_scavenge_ret
+
LIST_info_table:
cell LIST_evacuate
cell LIST_scavenge
@@ -47,13 +173,42 @@ LIST_code:
# FUN objects
# | ptr | thunkptr | args | arg[0] | arg[1] | ... | arg[args] |
FUN_evacuate:
- retq #TODO
+ mov 020(%rbp), %rbx # rbx = count of arguments
+ mov %rbx, %rcx # rcx = count of arguments for later looping
+ lea 030(%rbp, %rbx, 010), %rdx # rdx = address of the arguments
+ FUN_evacuate_one:
+ sub $1, %rcx
+ jl FUN_evacuate_fini
+ sub $010, %rdx
+ pushq (%rdx)
+ jmp FUN_evacuate_one
+ FUN_evacuate_fini:
+ pushq %rbx
+ pushq 010(%rbp)
+ pushq 000(%rbp)
+ mov %rsp, %rbp
+ jmp _gc_evacuate_ret
FUN_scavenge:
- mov 020(%rbp), %rax
- add $3, %rax
- shl $3, %rax
- add %rax, %rsi
- retq
+ mov 020(%rbp), %r13 # r13 = count of arguments (for looping)
+ mov %rbp, %r15 # r15 = scavengee ptr
+ lea 030(%rbp, %r13, 010), %r14 # r14 = address of argument
+
+ FUN_scavenge_one:
+ sub $1, %r13
+ jl FUN_scavenge_fini
+ sub $010, %r14
+ mov (%r14), %rbp
+ mov $FUN_scavenge_one_cont, %rsi
+ jmp _gc_evacuate
+ FUN_scavenge_one_cont:
+ mov %rbp, (%r14)
+ jmp FUN_scavenge_one
+
+ FUN_scavenge_fini:
+ mov %r15, %rbp # restore rbp
+ mov 020(%rbp), %r14
+ lea 030(%rbp, %r14, 010), %rbp
+ jmp _gc_scavenge_ret
# Info tables for FUN objects.
FUN0_info_table:
@@ -90,39 +245,46 @@ FUN4_info_table:
cell 4
FUN4_code:
continue
+# add more funN here as needed
-# TODO: add more funN here as needed
-
-# indirection (Q: how to recognize IND and THUNK on return?)
-# | ptr | indptr |
-IND_evacuate:
- retq #TODO
-IND_scavenge:
- add $020,%rsi
- retq
-IND_info:
- cell IND_evacuate
- cell IND_scavenge
- cell 0
-IND_code:
- enter 010(%rbp)
-
-# THU objects (gc implementation only, actual THUs are defined by functions)
+# THU objects (gc implementation only, actual THU data are created by functions)
# | 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:
- retq #TODO
+ mov 010(%rbp), %rbx # rbx = count of arguments
+ mov %rbx, %rcx # rcx = count of arguments for later looping
+ lea 020(%rbp, %rbx, 010), %rdx # rdx = address of the argument
+ THU_evacuate_one:
+ sub $1, %rcx
+ jl THU_evacuate_fini
+ sub $010, %rdx
+ pushq (%rdx)
+ jmp THU_evacuate_one
+ THU_evacuate_fini:
+ pushq %rbx
+ pushq 000(%rbp)
+ mov %rsp, %rbp
+ jmp _gc_evacuate_ret
THU_scavenge:
- mov 010(%rbp), %rax
- add $2,%rax
- shl $3,%rax
- add %rax,%rsi
- retq
+ mov 010(%rbp), %r13 # r13 = count of arguments (for looping)
+ mov %rbp, %r15 # r15 = scavengee ptr
+ lea 020(%rbp, %r13, 010), %r14 # r14 = address of argument
-.endif # _data_s_file
+ THU_scavenge_one:
+ sub $1, %r13
+ jl THU_scavenge_fini
+ sub $010, %r14
+ mov (%r14), %rbp
+ mov $THU_scavenge_one_cont, %rsi
+ jmp _gc_evacuate
+ THU_scavenge_one_cont:
+ mov %rbp, (%r14)
+ jmp THU_scavenge_one
+
+ THU_scavenge_fini:
+ mov %r15, %rbp # restore rbp
+ mov 010(%rbp), %r14
+ lea 020(%rbp, %r14, 010), %rbp
+ jmp _gc_scavenge_ret
-# evacuate and scavenge:
-# - evacuate just copies the object
-# - scavenge evacuates all children (to the new location IF they are in the old
-# location), changes the pointer, and moves the scavenge pointer to the next
-# object (because everything needs to be scavenged)
+.endif # _data_s_file