Commit b9e94e32 authored by Christophe Rhodes's avatar Christophe Rhodes
Browse files

0.9.17.8:

	MORE THREADSAFE FUNCALLABLE-INSTANCE
	... in a threaded world, we can't set the function and lexenv
		of a funcallable instance separately, because some other
		thread might inconveniently funcall the object 'twixt
		the one and the other.
	... instead, make the funcallable-instance-function a
		fully-fledged slot, and give a funcallable-instance a
		trampoline which knows how to call it.
	... which means implementing this strategy for $n$
		architectures.  Tested on x86, x86-64, ppc, alpha and
		sparc; completely untested on mips, and unimplemented
		on hppa.

	This removes some of the complexity in calling closures (the
	closure-self slot is now redundant, as is the extra
	indirection).  Other miscellaneous fixes:
	* extract-fun-type worked only by accident;
	* new magic :init :funcallable-instance-tramp for primitive
	  objects
	* verify_space() need no longer worry its little brain about
	  undefined_tramp and closure_tramp (I think)
	* test case for threaded funcallable-instance interaction.
parent 1a3143cc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ changes in sbcl-0.9.18 (1.0.beta?) relative to sbcl-0.9.16:
    returns T (reported by Anton Kazennikov)
  * bug fix: the STORE-VALUE restart of CHECK-TYPE works correctly
    with non-variable places
  * bug fix: remove a race condition in the setting of
    funcallable-instance functions, this should make threaded CLOS
    code more stable against memory faults.
  * improvement: the debugger will now also display local variables that
    are only used once, for code compiled with a DEBUG optimization quality
    of 2 or higher.
+5 −8
Original line number Diff line number Diff line
@@ -337,6 +337,7 @@ of SBCL which maintained the CMU-CL-style split into two packages.)"
               "DEF-SETTER"
               "FIXED-ALLOC"
               "MAKE-UNBOUND-MARKER"
               "MAKE-FUNCALLABLE-INSTANCE-TRAMP"
               "RETURN-SINGLE"
               "NOTE-NEXT-INSTRUCTION"
               "SET-SLOT"
@@ -345,7 +346,6 @@ of SBCL which maintained the CMU-CL-style split into two packages.)"
               "BLOCK-NUMBER"
               "BACKEND"
               "IR2-BLOCK-BLOCK"
               "FUNCALLABLE-INSTANCE-LEXENV"
               "VOP-BLOCK"
               "*ASSEMBLY-OPTIMIZE*"
               "LARGE-ALLOC"
@@ -1154,8 +1154,7 @@ is a good idea, but see SB-SYS re. blurring of boundaries."
               "%RAW-INSTANCE-SET/COMPLEX-SINGLE"
               "%RAW-INSTANCE-REF/COMPLEX-DOUBLE"
               "%RAW-INSTANCE-SET/COMPLEX-DOUBLE"
               "%SET-ARRAY-DIMENSION" "%SET-FUNCALLABLE-INSTANCE-FUN"
               "%SET-FUNCALLABLE-INSTANCE-INFO"
               "%SET-ARRAY-DIMENSION" "%SET-FUNCALLABLE-INSTANCE-INFO"
               "%SET-RAW-BITS" "%SET-VECTOR-RAW-BITS"
               "%SET-SAP-REF-16" "%SET-SAP-REF-32" "%SET-SAP-REF-64"
               "%SET-SAP-REF-WORD" "%SET-SAP-REF-8" "%SET-SAP-REF-DOUBLE"
@@ -1546,8 +1545,8 @@ is a good idea, but see SB-SYS re. blurring of boundaries."
               "REGISTER-LAYOUT"
               "FUNCALLABLE-INSTANCE" "RANDOM-FIXNUM-MAX"
               "MAKE-STATIC-CLASSOID" "INSTANCE-LAMBDA"
               "%FUNCALLABLE-INSTANCE-LEXENV" "%MAKE-SYMBOL"
               "%FUNCALLABLE-INSTANCE-FUN" "SYMBOL-HASH"
               "%MAKE-SYMBOL"
               "%FUNCALLABLE-INSTANCE-FUNCTION" "SYMBOL-HASH"

               "BUILT-IN-CLASSOID" "CONDITION-CLASSOID-P"
               "CONDITION-CLASSOID-SLOTS" "MAKE-UNDEFINED-CLASSOID"
@@ -2162,7 +2161,7 @@ structure representations"
               "FORWARDING-POINTER-TYPE"
               "FP-CONSTANT-SC-NUMBER"
               "FP-DOUBLE-ZERO-SC-NUMBER" "FP-SINGLE-ZERO-SC-NUMBER"
               "FUNCALLABLE-INSTANCE-FUN-SLOT"
               "FUNCALLABLE-INSTANCE-TRAMPOLINE-SLOT"
               "FUNCALLABLE-INSTANCE-HEADER-WIDETAG"
               "FUNCALLABLE-INSTANCE-INFO-OFFSET"
               "SIMPLE-FUN-ARGLIST-SLOT" "SIMPLE-FUN-CODE-OFFSET"
@@ -2177,8 +2176,6 @@ structure representations"
               "FUN-POINTER-LOWTAG"
               "SIMPLE-FUN-SELF-SLOT"
               "SIMPLE-FUN-TYPE-SLOT"
               "FUNCALLABLE-INSTANCE-LAYOUT-SLOT"
               "FUNCALLABLE-INSTANCE-LEXENV-SLOT"
               "GENCGC-PAGE-SIZE"
               #!+ppc "PSEUDO-ATOMIC-INTERRUPTED-FLAG"
               #!+ppc "PSEUDO-ATOMIC-FLAG"
+2 −6
Original line number Diff line number Diff line
@@ -15,13 +15,9 @@

(macrolet ((def (name &optional (args '(x)))
             `(defun ,name ,args (,name ,@args))))
  (def %caller-frame-and-pc ())
  (def %code-code-size)
  (def %code-debug-info)
  (def %code-entry-points)
  (def %funcallable-instance-fun)
  (def %funcallable-instance-layout)
  (def %funcallable-instance-lexenv)
  (def %set-funcallable-instance-fun (fin new-val)))

(defun %caller-frame-and-pc ()
  (%caller-frame-and-pc))
  (def %set-funcallable-instance-layout (x new-value)))
+3 −30
Original line number Diff line number Diff line
@@ -147,37 +147,10 @@
  (%set-funcallable-instance-info fin i new-value))

(defun funcallable-instance-fun (fin)
  (%funcallable-instance-lexenv fin))

;;; The heart of the magic of funcallable instances ("FINs").  When
;;; called (as with any other function), we grab the code pointer, and
;;; call it, leaving the original function object in LEXENV (in case
;;; it was a closure).  If it is actually a FIN, then we need to do an
;;; extra indirection with funcallable-instance-lexenv to get at any
;;; closure environment.  This extra indirection is set up when
;;; accessing the closure environment of an INSTANCE-LAMBDA. Note that
;;; the original FIN pointer is lost, so if the called function wants
;;; to get at the original object to do some slot accesses, it must
;;; close over the FIN object.
;;;
;;; If we set the FIN function to be a FIN, we directly copy across
;;; both the code pointer and the lexenv, since that code pointer (for
;;; an instance-lambda) is expecting that lexenv to be accessed.  This
;;; effectively pre-flattens what would otherwise be a chain of
;;; indirections.  (That used to happen when PCL dispatch functions
;;; were byte-compiled; now that the byte compiler is gone, I can't
;;; think of another example offhand. -- WHN 2001-10-06)
;;;
;;; The only loss is that if someone accesses the
;;; FUNCALLABLE-INSTANCE-FUN, then won't get a FIN back.  This
;;; probably doesn't matter, since PCL only sets the FIN function.
  (%funcallable-instance-function fin))

(defun (setf funcallable-instance-fun) (new-value fin)
  (setf (%funcallable-instance-fun fin)
        (%closure-fun new-value))
  (setf (%funcallable-instance-lexenv fin)
        (if (funcallable-instance-p new-value)
            (%funcallable-instance-lexenv new-value)
            new-value)))
  (setf (%funcallable-instance-function fin) new-value))

;;; service function for structure constructors
(defun %make-instance-with-layout (layout)
+1 −5
Original line number Diff line number Diff line
@@ -143,10 +143,6 @@
  "Return the class of the supplied object, which may be any Lisp object, not
   just a CLOS STANDARD-OBJECT."
  (layout-classoid (layout-of object)))

;;; Pull the type specifier out of a function object.
(defun extract-fun-type (fun)
  (specifier-type (%simple-fun-type (%closure-fun fun))))

;;;; miscellaneous interfaces

@@ -182,7 +178,7 @@
    (function
     (if (funcallable-instance-p x)
         (classoid-of x)
         (extract-fun-type x)))
         (specifier-type (sb!impl::%fun-type x))))
    (symbol
     (make-member-type :members (list x)))
    (number
Loading