summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Zhang <charleszhang99@yahoo.com>2024-09-21 15:56:07 +0200
committerCharles Zhang <charleszhang99@yahoo.com>2024-09-21 18:25:23 +0200
commit6af10c6f02ffb1037178cedccaef5c71cde7f5cd (patch)
tree54635503350889975ad1b54e611d016858a649d6
parent64d4c04a9e786f03f19579a176d12296f027300c (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.lisp9
-rw-r--r--src/runtime/arm64-assem.S6
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