1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
.ifndef _data_s_file
_data_s_file:
nop
# Format of the info tables:
# - code
# ----- code pointer
# - 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 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)
# List
# | ptr | 0 | # [] case
# | ptr | 1 | a | b | # (a:b) case
LIST_evacuate:
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:
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
cell 0
LIST_code:
continue
# FUN objects
# | ptr | thunkptr | args | arg[0] | arg[1] | ... | arg[args] |
FUN_evacuate:
#TODO
FUN_scavenge:
#TODO
#mov 020(%rbp), %rax
#add $3, %rax
#shl $3, %rax
#add %rax, %rsi
#retq
# Info tables for FUN objects.
FUN0_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 0
FUN0_code:
continue
FUN1_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 1
FUN1_code:
continue
FUN2_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 2
FUN2_code:
continue
FUN3_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 3
FUN3_code:
continue
FUN4_info_table:
cell FUN_evacuate
cell FUN_scavenge
cell 4
FUN4_code:
continue
# add more funN here as needed
# 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:
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 # 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), %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 $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
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
|