diff options
author | Charles Zhang <charleszhang99@yahoo.com> | 2024-09-21 15:56:07 +0200 |
---|---|---|
committer | Charles Zhang <charleszhang99@yahoo.com> | 2024-09-21 18:25:23 +0200 |
commit | 6af10c6f02ffb1037178cedccaef5c71cde7f5cd (patch) | |
tree | 54635503350889975ad1b54e611d016858a649d6 | |
parent | 64d4c04a9e786f03f19579a176d12296f027300c (diff) |
arm64: Blank all descriptors, not just C volatile registers.
This is to avoid call-out keeping stale Lisp pointers hanging
around. This fixes crashes with immobile space on arm64 Linux, and
likely latent issues present even without immobile space.
Apparently r9 (cfunc) was causing the issue, though I don't completely
understand why given that it should be saved and restored by C and
also doesn't have a pointer value.
-rw-r--r-- | src/compiler/arm64/c-call.lisp | 9 | ||||
-rw-r--r-- | src/runtime/arm64-assem.S | 6 |
2 files changed, 13 insertions, 2 deletions
diff --git a/src/compiler/arm64/c-call.lisp b/src/compiler/arm64/c-call.lisp index 6a3f0ba31..0d3f45b8b 100644 --- a/src/compiler/arm64/c-call.lisp +++ b/src/compiler/arm64/c-call.lisp @@ -252,7 +252,14 @@ (sap-stack (load-stack-offset cfunc cur-nfp function))) (inst blr cfunc))) - (loop for reg in (intersection descriptor-regs +destroyed-c-registers+) + ;; Blank all boxed registers that potentially contain Lisp + ;; pointers, not just volatile ones, since GC could + ;; potentially observe stale pointers otherwise. FIXME: There + ;; is some suboptimality here; instead of blanking all boxed + ;; pointers, we can just blank the ones which are both qsaved + ;; and restored by C and known to not contain a Lisp pointer + ;; (i.e. can be moved). + (loop for reg in descriptor-regs do (inst mov (make-random-tn :kind :normal diff --git a/src/runtime/arm64-assem.S b/src/runtime/arm64-assem.S index 21e5bf5a6..1f545edc1 100644 --- a/src/runtime/arm64-assem.S +++ b/src/runtime/arm64-assem.S @@ -330,7 +330,9 @@ GNAME(call_into_c): // to where Lisp expects it, and to re-establish the Lisp // environment. - // Blank the boxed registers. + // Blank the boxed registers. reg_LEXENV doesn't need to be + // blanked because its saved and restored by C and also known + // to not be a Lisp pointer here. mov reg_R0, #0 mov reg_R1, #0 mov reg_R2, #0 @@ -339,6 +341,8 @@ GNAME(call_into_c): mov reg_R5, #0 mov reg_R6, #0 mov reg_R7, #0 + mov reg_R8, #0 + mov reg_R9, #0 #ifndef LISP_FEATURE_DARWIN mov reg_R10,#0 #ifndef LISP_FEATURE_SB_THREAD |