Get garbage collector working on aarch64

Garbage collection will now happen on arm64 when a function returns,
rather than kicking the can down the road to when the process exits.
This change also does some code cleanup and incorporates suggestions
This commit is contained in:
Justine Tunney 2023-06-07 03:34:45 -07:00
parent 9793d3524f
commit 01fd655097
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
16 changed files with 144 additions and 323 deletions

View file

@ -33,13 +33,14 @@
// @param rax,rdx,xmm0,xmm1,st0,st1 is return value
// @see test/libc/runtime/gc_test.c
// @threadsafe
__gc:
.ftrace1
__gc: .ftrace2
#ifdef __x86_64__
mov %fs:0,%rcx // __get_tls()
mov 0x18(%rcx),%rcx // tls::garbages
decl (%rcx) // ++g->i
decl (%rcx) // --g->i
mov (%rcx),%r8d // r8 = g->i
mov 8(%rcx),%r9 // r9 = g->p
js 9f
@ -65,18 +66,40 @@ __gc:
#elif defined(__aarch64__)
stp x29,x30,[sp,-80]!
sub x8,x28,#1152 // __get_tls()
ldr x9,[x8,0x18] // tib::garbages
ldr x10,[x9] // g->i
ldr x8,[x9,8] // g->p
sub x10,x10,#1 //
str x10,[x9] //
sbfiz x10,x10,5,32 //
add x8,x8,x10 // g->p+i
ldr x9,[x8,#8] // g->p[i].fn
ldr x10,[x8,#16] // g->p[i].arg
ldr x11,[x8,#24] // g->p[i].ret
stp x29,x11,[sp,-208]!
mov x29,sp
stp x0,x1,[sp,16]
stp x2,x3,[sp,32]
stp x4,x5,[sp,48]
stp x6,x7,[sp,64]
// todo jart
ldp x0,x1,[sp,16]
ldp x2,x3,[sp,32]
ldp x4,x5,[sp,48]
stp q0,q1,[sp,80]
stp q2,q3,[sp,112]
stp q4,q5,[sp,144]
stp q6,q7,[sp,176]
mov x1,x10
bl CheckStackIsAligned
blr x9
ldp q6,q7,[sp,176]
ldp q4,q5,[sp,144]
ldp q2,q3,[sp,112]
ldp q0,q1,[sp,80]
ldp x6,x7,[sp,64]
ldp x29,x30,[sp],80
ldp x4,x5,[sp,48]
ldp x2,x3,[sp,32]
ldp x0,x1,[sp,16]
ldp x29,x30,[sp],208
ret
#endif /* __x86_64__ */

View file

@ -36,27 +36,27 @@ _gclongjmp:
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov %fs:0,%r12 # __get_tls()
mov 0x18(%r12),%r12 # Tls::garbages
mov %fs:0,%r12 // __get_tls()
mov 0x18(%r12),%r12 // Tls::garbages
test %r12,%r12
jz 0f
movl (%r12),%r13d # garbages.i
movl (%r12),%r13d // garbages.i
test %r13d,%r13d
jnz .L.unwind.destructors
0: jmp longjmp
.L.unwind.destructors:
push %rdi
push %rsi
mov 8(%r12),%r14 # garbages.p
mov (%rdi),%r15 # jmp_buf[0] is new %rsp
shl $5,%r13 # log2(sizeof(struct Garbage))
1: sub $32,%r13 # 𝑖--
mov 8(%r12),%r14 // garbages.p
mov (%rdi),%r15 // jmp_buf[0] is new %rsp
shl $5,%r13 // log2(sizeof(struct Garbage))
1: sub $32,%r13 // 𝑖--
js 2f
cmp (%r14,%r13),%r15 # new %rsp > garbages.p[𝑖].frame
cmp (%r14,%r13),%r15 // new %rsp > garbages.p[𝑖].frame
jbe 2f
mov 16(%r14,%r13),%rdi # garbages.p[𝑖].arg
callq *8(%r14,%r13) # garbages.p[𝑖].fn
decl (%r12) # garbages.i--
mov 16(%r14,%r13),%rdi // garbages.p[𝑖].arg
callq *8(%r14,%r13) // garbages.p[𝑖].fn
decl (%r12) // garbages.i--
jmp 1b
2: pop %rsi
pop %rdi

View file

@ -60,6 +60,8 @@ o/$(MODE)/libc/nexgen32e/threaded.o: private \
$(NO_MAGIC)
# these assembly files are safe to build on aarch64
o/$(MODE)/libc/nexgen32e/gc.o: libc/nexgen32e/gc.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/zip.o: libc/nexgen32e/zip.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/mcount.o: libc/nexgen32e/mcount.S