From 1f8efb3fd750d7c4127ce938a53bf245f190546d Mon Sep 17 00:00:00 2001 From: Alastair Bridgewater Date: Sat, 7 Aug 2010 15:19:41 +0000 Subject: [PATCH] 1.0.41.24: ppc: Calling-convention fixes for entry-point handling during named-call. * For GC purposes, seven times never load reg_LIP before loading whatever register points to the object it refers to. * During named-call, load the function from the fdefn before loading the raw-addr (which ends up in reg_LIP). For simple-fun objects, this provides the reference base for reg_LIP. For other objects this doesn't matter because reg_LIP ends up pointing to either undefined_tramp or closure_tramp. * This still leaves a race condition when updating fdefinitions, but fixes the race condition surrounding function calling. * To fix the remaining race condition, we would need to alter the undefined function trampoline to appear to be a simple-fun object and adjust the fdefn-fun accessors to compensate, then arrange for "named" calls to load reg_LEXENV and do closure-fun access in the same manner as the closure_tramp and the "unnamed" call VOPs. This would add another instruction to the call path, but not another memory access (as we would trade off loading the fdefn-raw-addr for loading the closure-fun). --- src/compiler/ppc/call.lisp | 18 +++++++++++++----- version.lisp-expr | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/compiler/ppc/call.lisp b/src/compiler/ppc/call.lisp index 229a078..dd68db8 100644 --- a/src/compiler/ppc/call.lisp +++ b/src/compiler/ppc/call.lisp @@ -650,9 +650,8 @@ default-value-8 :from (:argument ,(if (eq return :tail) 0 1)) :to :eval) lexenv)) - ,@(unless named - '((:temporary (:scs (descriptor-reg) :from (:argument 0) :to :eval) - function))) + (:temporary (:scs (descriptor-reg) :from (:argument 0) :to :eval) + function) (:temporary (:sc any-reg :offset nargs-offset :to :eval) nargs-pass) @@ -784,8 +783,17 @@ default-value-8 ;; FUNCTION is loaded, but before ENTRY-POINT is ;; calculated. (insert-step-instrumenting name-pass) - (loadw entry-point name-pass fdefn-raw-addr-slot - other-pointer-lowtag) + ;; The raw-addr (ENTRY-POINT) will be one of: + ;; closure_tramp, undefined_tramp, or somewhere + ;; within a simple-fun object. If the latter, then + ;; it is essential (due to it being an interior + ;; pointer) that the function itself be in a + ;; register before the raw-addr is loaded. + (sb!assem:without-scheduling () + (loadw function name-pass fdefn-fun-slot + other-pointer-lowtag) + (loadw entry-point name-pass fdefn-raw-addr-slot + other-pointer-lowtag)) (do-next-filler)) `((sc-case arg-fun (descriptor-reg (move lexenv arg-fun)) diff --git a/version.lisp-expr b/version.lisp-expr index f356232..3064229 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.41.23" +"1.0.41.24" -- 1.7.10.4