(define-primitive-object (closure :lowtag fun-pointer-lowtag
:widetag closure-header-widetag)
(fun :init :arg :ref-trans %closure-fun)
+ ;; This SELF slot needs explanation.
+ ;;
+ ;; Ordinary closures did not need this slot before version 0.9.3.xx,
+ ;; as the closure object was already in some dedicated register --
+ ;; EAX/RAX on x86(-64), reg_LEXENV on register-rich platforms -- and
+ ;; consequently setting up the environment (from the INFO slot,
+ ;; below) was easy.
+ ;;
+ ;; However, it is not easy to support calling FUNCALLABLE-INSTANCEs
+ ;; in the same way; in a FUNCALLABLE-INSTANCE, there are
+ ;; conceptually two variable-length data areas: the closure
+ ;; environment, if any, and the slots of the instance.
+ ;;
+ ;; Until sbcl-0.9.3.xx, it was required that closures to be set as a
+ ;; FUNCALLABLE-INSTANCE-FUNCTION be defined using the magical
+ ;; keyword SB-KERNEL:INSTANCE-LAMBDA, rather than ordinary LAMBDA;
+ ;; this caused an extra indirection to be compiled into the closure
+ ;; code to load the closure from the FUNCALLABLE-INSTANCE-LEXENV
+ ;; slot before setting up the environment for the function body.
+ ;; Failure to obey this protocol yielded confusing error messages as
+ ;; either INSTANCE-LAMBDAs tried to dereference environments that
+ ;; weren't there, or ordinary LAMBDAs got hold of the LAYOUT and
+ ;; LEXENV slots of a FUNCALLABLE-INSTANCE.
+ ;;
+ ;; By adding this SELF slot, which is at the same offset in a
+ ;; regular CLOSURE as the LEXENV slot is in a FUNCALLABLE-INSTANCE,
+ ;; we enable the extra indirection (VOP FUNCALLABLE-INSTANCE-LEXENV,
+ ;; in src/compiler/ir2tran.lisp) to be compiled unconditionally
+ ;; (provided that we set this slot to the closure object itself).
+ ;; Relative to the code before, this adds a word to the space
+ ;; requirements of a closure, and one instruction (a memory fetch)
+ ;; to the body of a closure function.
+ ;;
+ ;; There are potentially other implementation strategies which would
+ ;; remove the need for this extra indirection in regular closures,
+ ;; such as setting up a trampoline for funcallable instances (though
+ ;; it was not clear to me that there are enough registers free in
+ ;; the x86 backend to permit this). This indirection should not be
+ ;; too disastrous, given that for regular closures the fetch is from
+ ;; memory which is known to be active.
+ ;;
+ ;; CSR, 2005-08-05
+ (self) ; KLUDGE (see above comment)
(info :rest-p t))
(define-primitive-object (funcallable-instance
)
(lexenv :ref-known (flushable) :ref-trans %funcallable-instance-lexenv
:set-known (unsafe) :set-trans (setf %funcallable-instance-lexenv))
- (layout :init :arg
- :ref-known (flushable) :ref-trans %funcallable-instance-layout
- :set-known (unsafe) :set-trans (setf %funcallable-instance-layout))
(info :rest-p t))
(define-primitive-object (value-cell :lowtag other-pointer-lowtag
;;; Hence the even-fixnum lowtag just so we don't get odd(sic) numbers
;;; added to the slot offsets
(define-primitive-object (thread :lowtag even-fixnum-lowtag)
- ;; unbound_marker is borrowed very briefly at thread startup to
- ;; pass the address of initial-function into new_thread_trampoline
- (unbound-marker :init :unbound) ; tls[0] = UNBOUND_MARKER_WIDETAG
+ ;; no_tls_value_marker is borrowed very briefly at thread startup to
+ ;; pass the address of initial-function into new_thread_trampoline.
+ ;; tls[0] = NO_TLS_VALUE_MARKER_WIDETAG because a the tls index slot
+ ;; of a symbol is initialized to zero
+ (no-tls-value-marker)
(os-thread :c-type "os_thread_t")
(binding-stack-start :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1)
(binding-stack-pointer :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1)
(alien-stack-start :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1)
(alien-stack-pointer :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1)
#!+gencgc (alloc-region :c-type "struct alloc_region" :length 5)
- (tls-cookie) ; on x86, the LDT index
(this :c-type "struct thread *" :length #!+alpha 2 #!-alpha 1)
(prev :c-type "struct thread *" :length #!+alpha 2 #!-alpha 1)
(next :c-type "struct thread *" :length #!+alpha 2 #!-alpha 1)
;; starting, running, suspended, dead
- (state)
+ (state :c-type "volatile lispobj")
+ (tls-cookie) ; on x86, the LDT index
#!+(or x86 x86-64) (pseudo-atomic-atomic)
#!+(or x86 x86-64) (pseudo-atomic-interrupted)
(interrupt-fun)
- (interrupt-fun-lock)
+ (interrupt-fun-lock :c-type "volatile lispobj")
(interrupt-data :c-type "struct interrupt_data *"
:length #!+alpha 2 #!-alpha 1)
(interrupt-contexts :c-type "os_context_t *" :rest-p t))