aboutsummaryrefslogtreecommitdiff
path: root/include/data.s
blob: 452018ebef475f30074e0862574c3e13c6859efc (plain)
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

.ifndef _data_s_file
_data_s_file:
	nop # avoid confusing gdb

# 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)

# Blackhole (contains the original thunkptr for debugging purposes)
# | ptr | orig_thunkptr |
BLE_evacuate:
	pushq 010(%rbp)
	pushq $BLE_code
	mov %rsp,%rbp
	jmp _gc_evacuate_ret
BLE_scavenge:
	add $020, %rbp
	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.
	mov 0, %rax
	jmp BLE_code
	# this might eventually generate an actual IO-style exception or something.

# 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:
	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), %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:
	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, %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), %r13 # r13 = count of arguments (for looping)
	mov %rbp, %r15 # r15 = scavengee ptr
	lea 020(%rbp, %r13, 010), %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
	lea 020(%rbp, %r14, 010), %rbp
	jmp _gc_scavenge_ret

.endif # _data_s_file