1.0.41.24: ppc: Calling-convention fixes for entry-point handling during named-call.
authorAlastair Bridgewater <lisphacker@users.sourceforge.net>
Sat, 7 Aug 2010 15:19:41 +0000 (15:19 +0000)
committerAlastair Bridgewater <lisphacker@users.sourceforge.net>
Sat, 7 Aug 2010 15:19:41 +0000 (15:19 +0000)
  * 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
version.lisp-expr

index 229a078..dd68db8 100644 (file)
@@ -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))
index f356232..3064229 100644 (file)
@@ -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"