1 ;;;; machine-independent aspects of the object representation
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
14 ;;;; KLUDGE: The primitive objects here may look like self-contained
15 ;;;; definitions, but in general they're not. In particular, if you
16 ;;;; try to add a slot to them, beware of the following:
17 ;;;; * (mysterious crashes which occur after changing the length
18 ;;;; of SIMPLE-FUN, just adding a new slot not even doing anything
19 ;;;; with it, still dunno why)
20 ;;;; * The GC scavenging code (and for all I know other GC code too)
21 ;;;; is not automatically generated from these layouts, but instead
22 ;;;; was hand-written to correspond to them. The offsets are
23 ;;;; automatically propagated into the GC scavenging code, but the
24 ;;;; existence of slots, and whether they should be scavenged, is
25 ;;;; not automatically propagated. Thus e.g. if you add a
26 ;;;; SIMPLE-FUN-DEBUG-INFO slot holding a tagged object which needs
27 ;;;; to be GCed, you need to tweak scav_code_header() and
28 ;;;; verify_space() in gencgc.c, and the corresponding code in gc.c.
29 ;;;; * The src/runtime/print.c code (used by LDB) is implemented
30 ;;;; using hand-written lists of slot names, which aren't automatically
31 ;;;; generated from the code in this file.
32 ;;;; * Various code (e.g. STATIC-FSET in genesis.lisp) is hard-wired
33 ;;;; to know the name of the last slot of the object the code works
34 ;;;; with, and implicitly to know that the last slot is special (being
35 ;;;; the beginning of an arbitrary-length sequence of bytes following
36 ;;;; the fixed-layout slots).
37 ;;;; -- WHN 2001-12-29
39 ;;;; the primitive objects themselves
41 (define-primitive-object (cons :lowtag list-pointer-lowtag
43 (car :ref-trans car
:set-trans sb
!c
::%rplaca
:init
:arg
44 :cas-trans %compare-and-swap-car
)
45 (cdr :ref-trans cdr
:set-trans sb
!c
::%rplacd
:init
:arg
46 :cas-trans %compare-and-swap-cdr
))
48 (define-primitive-object (instance :lowtag instance-pointer-lowtag
49 :widetag instance-header-widetag
50 :alloc-trans %make-instance
)
53 (define-primitive-object (bignum :lowtag other-pointer-lowtag
54 :widetag bignum-widetag
55 :alloc-trans sb
!bignum
::%allocate-bignum
)
56 (digits :rest-p t
:c-type
#!-alpha
"long" #!+alpha
"u32"))
58 (define-primitive-object (ratio :type ratio
59 :lowtag other-pointer-lowtag
60 :widetag ratio-widetag
61 :alloc-trans %make-ratio
)
62 (numerator :type integer
63 :ref-known
(flushable movable
)
66 (denominator :type integer
67 :ref-known
(flushable movable
)
68 :ref-trans %denominator
71 #!+#.
(cl:if
(cl:= sb
!vm
:n-word-bits
32) '(and) '(or))
72 (define-primitive-object (single-float :lowtag other-pointer-lowtag
73 :widetag single-float-widetag
)
74 (value :c-type
"float"))
76 (define-primitive-object (double-float :lowtag other-pointer-lowtag
77 :widetag double-float-widetag
)
79 (value :c-type
"double" :length
#!-x86-64
2 #!+x86-64
1))
81 (define-primitive-object (xmm :lowtag other-pointer-lowtag
83 (value :c-type
"char *" :length
8))
86 (define-primitive-object (long-float :lowtag other-pointer-lowtag
87 :widetag long-float-widetag
)
89 (value :c-type
"long double" :length
#!+x86
3 #!+sparc
4))
91 (define-primitive-object (complex :type complex
92 :lowtag other-pointer-lowtag
93 :widetag complex-widetag
94 :alloc-trans %make-complex
)
96 :ref-known
(flushable movable
)
100 :ref-known
(flushable movable
)
104 (define-primitive-object (array :lowtag other-pointer-lowtag
106 ;; FILL-POINTER of an ARRAY is in the same place as LENGTH of a
107 ;; VECTOR -- see SHRINK-VECTOR.
108 (fill-pointer :type index
109 :ref-trans %array-fill-pointer
110 :ref-known
(flushable foldable
)
111 :set-trans
(setf %array-fill-pointer
)
113 (fill-pointer-p :type
(member t nil
)
114 :ref-trans %array-fill-pointer-p
115 :ref-known
(flushable foldable
)
116 :set-trans
(setf %array-fill-pointer-p
)
118 (elements :type index
119 :ref-trans %array-available-elements
120 :ref-known
(flushable foldable
)
121 :set-trans
(setf %array-available-elements
)
124 :ref-trans %array-data-vector
125 :ref-known
(flushable foldable
)
126 :set-trans
(setf %array-data-vector
)
128 (displacement :type
(or index null
)
129 :ref-trans %array-displacement
130 :ref-known
(flushable foldable
)
131 :set-trans
(setf %array-displacement
)
133 (displaced-p :type
(member t nil
)
134 :ref-trans %array-displaced-p
135 :ref-known
(flushable foldable
)
136 :set-trans
(setf %array-displaced-p
)
138 (dimensions :rest-p t
))
140 (define-primitive-object (vector :type vector
141 :lowtag other-pointer-lowtag
143 ;; FILL-POINTER of an ARRAY is in the same place as LENGTH of a
144 ;; VECTOR -- see SHRINK-VECTOR.
145 (length :ref-trans sb
!c
::vector-length
147 (data :rest-p t
:c-type
#!-alpha
"unsigned long" #!+alpha
"u32"))
149 (define-primitive-object (code :type code-component
150 :lowtag other-pointer-lowtag
152 (code-size :type index
153 :ref-known
(flushable movable
)
154 :ref-trans %code-code-size
)
155 (entry-points :type
(or function null
)
156 :ref-known
(flushable)
157 :ref-trans %code-entry-points
159 :set-trans
(setf %code-entry-points
))
161 :ref-known
(flushable)
162 :ref-trans %code-debug-info
164 :set-trans
(setf %code-debug-info
))
166 (constants :rest-p t
))
168 (define-primitive-object (fdefn :type fdefn
169 :lowtag other-pointer-lowtag
170 :widetag fdefn-widetag
)
171 (name :ref-trans fdefn-name
)
172 (fun :type
(or function null
) :ref-trans fdefn-fun
)
173 (raw-addr :c-type
#!-alpha
"char *" #!+alpha
"u32"))
175 ;;; a simple function (as opposed to hairier things like closures
176 ;;; which are also subtypes of Common Lisp's FUNCTION type)
177 (define-primitive-object (simple-fun :type function
178 :lowtag fun-pointer-lowtag
179 :widetag simple-fun-header-widetag
)
180 #!-
(or x86 x86-64
) (self :ref-trans %simple-fun-self
181 :set-trans
(setf %simple-fun-self
))
182 #!+(or x86 x86-64
) (self
183 ;; KLUDGE: There's no :SET-KNOWN, :SET-TRANS, :REF-KNOWN, or
184 ;; :REF-TRANS here in this case. Instead, there's separate
185 ;; DEFKNOWN/DEFINE-VOP/DEFTRANSFORM stuff in
186 ;; compiler/x86/system.lisp to define and declare them by
187 ;; hand. I don't know why this is, but that's (basically)
188 ;; the way it was done in CMU CL, and it works. (It's not
189 ;; exactly the same way it was done in CMU CL in that CMU
190 ;; CL's allows duplicate DEFKNOWNs, blithely overwriting any
191 ;; previous data associated with the previous DEFKNOWN, and
192 ;; that property was used to mask the definitions here. In
193 ;; SBCL as of 0.6.12.64 that's not allowed -- too confusing!
194 ;; -- so we have to explicitly suppress the DEFKNOWNish
195 ;; stuff here in order to allow this old hack to work in the
196 ;; new world. -- WHN 2001-08-82
198 (next :type
(or function null
)
199 :ref-known
(flushable)
200 :ref-trans %simple-fun-next
202 :set-trans
(setf %simple-fun-next
))
203 (name :ref-known
(flushable)
204 :ref-trans %simple-fun-name
206 :set-trans
(setf %simple-fun-name
))
208 :ref-known
(flushable)
209 :ref-trans %simple-fun-arglist
211 :set-trans
(setf %simple-fun-arglist
))
212 (type :ref-known
(flushable)
213 :ref-trans %simple-fun-type
215 :set-trans
(setf %simple-fun-type
))
217 :ref-trans %simple-fun-xrefs
218 :ref-known
(flushable)
219 :set-trans
(setf %simple-fun-xrefs
)
221 ;; the SB!C::DEBUG-FUN object corresponding to this object, or NIL for none
222 #+nil
; FIXME: doesn't work (gotcha, lowly maintenoid!) See notes on bug 137.
223 (debug-fun :ref-known
(flushable)
224 :ref-trans %simple-fun-debug-fun
226 :set-trans
(setf %simple-fun-debug-fun
))
227 (code :rest-p t
:c-type
"unsigned char"))
229 (define-primitive-object (return-pc :lowtag other-pointer-lowtag
:widetag t
)
230 (return-point :c-type
"unsigned char" :rest-p t
))
232 (define-primitive-object (closure :lowtag fun-pointer-lowtag
233 :widetag closure-header-widetag
)
234 (fun :init
:arg
:ref-trans %closure-fun
)
237 (define-primitive-object (funcallable-instance
238 :lowtag fun-pointer-lowtag
239 :widetag funcallable-instance-header-widetag
240 :alloc-trans %make-funcallable-instance
)
241 (trampoline :init
:funcallable-instance-tramp
)
242 (function :ref-known
(flushable) :ref-trans %funcallable-instance-function
243 :set-known
(unsafe) :set-trans
(setf %funcallable-instance-function
))
246 (define-primitive-object (value-cell :lowtag other-pointer-lowtag
247 :widetag value-cell-header-widetag
248 ;; FIXME: We also have an explicit VOP
249 ;; for this. Is this needed as well?
250 :alloc-trans make-value-cell
)
251 (value :set-trans value-cell-set
253 :ref-trans value-cell-ref
254 :ref-known
(flushable)
258 (define-primitive-object (sap :lowtag other-pointer-lowtag
259 :widetag sap-widetag
)
261 (pointer :c-type
"char *" :length
2))
264 (define-primitive-object (sap :lowtag other-pointer-lowtag
265 :widetag sap-widetag
)
266 (pointer :c-type
"char *"))
269 (define-primitive-object (weak-pointer :type weak-pointer
270 :lowtag other-pointer-lowtag
271 :widetag weak-pointer-widetag
272 :alloc-trans make-weak-pointer
)
273 (value :ref-trans sb
!c
::%weak-pointer-value
:ref-known
(flushable)
275 (broken :type
(member t nil
)
276 :ref-trans sb
!c
::%weak-pointer-broken
:ref-known
(flushable)
278 (next :c-type
#!-alpha
"struct weak_pointer *" #!+alpha
"u32"))
280 ;;;; other non-heap data blocks
282 (define-primitive-object (binding)
286 (define-primitive-object (unwind-block)
287 (current-uwp :c-type
#!-alpha
"struct unwind_block *" #!+alpha
"u32")
288 (current-cont :c-type
#!-alpha
"lispobj *" #!+alpha
"u32")
289 #!-
(or x86 x86-64
) current-code
291 #!+win32 next-seh-frame
292 #!+win32 seh-frame-handler
)
294 (define-primitive-object (catch-block)
295 (current-uwp :c-type
#!-alpha
"struct unwind_block *" #!+alpha
"u32")
296 (current-cont :c-type
#!-alpha
"lispobj *" #!+alpha
"u32")
297 #!-
(or x86 x86-64
) current-code
299 #!+win32 next-seh-frame
300 #!+win32 seh-frame-handler
302 (previous-catch :c-type
#!-alpha
"struct catch_block *" #!+alpha
"u32")
305 ;;; (For an explanation of this, see the comments at the definition of
306 ;;; KLUDGE-NONDETERMINISTIC-CATCH-BLOCK-SIZE.)
307 (aver (= kludge-nondeterministic-catch-block-size catch-block-size
))
311 (define-primitive-object (symbol :lowtag other-pointer-lowtag
312 :widetag symbol-header-widetag
313 :alloc-trans %make-symbol
)
315 ;; Beware when changing this definition. NIL-the-symbol is defined
316 ;; using this layout, and NIL-the-end-of-list-marker is the cons
317 ;; ( NIL . NIL ), living in the first two slots of NIL-the-symbol
318 ;; (conses have no header). Careful selection of lowtags ensures
319 ;; that the same pointer can be used for both purposes:
320 ;; OTHER-POINTER-LOWTAG is 7, LIST-POINTER-LOWTAG is 3, so if you
321 ;; subtract 3 from (SB-KERNEL:GET-LISP-OBJ-ADDRESS 'NIL) you get the
322 ;; first data slot, and if you subtract 7 you get a symbol header.
324 ;; also the CAR of NIL-as-end-of-list
325 (value :init
:unbound
:ref-known
(flushable) :ref-trans symbol-global-value
)
326 ;; also the CDR of NIL-as-end-of-list. Its reffer needs special
327 ;; care for this reason, as hash values must be fixnums.
328 (hash :set-trans %set-symbol-hash
)
330 (plist :ref-trans symbol-plist
331 :set-trans %set-symbol-plist
332 :cas-trans %compare-and-swap-symbol-plist
335 (name :ref-trans symbol-name
:init
:arg
)
336 (package :ref-trans symbol-package
337 :set-trans %set-symbol-package
339 #!+sb-thread
(tls-index :ref-known
(flushable) :ref-trans symbol-tls-index
))
341 (define-primitive-object (complex-single-float
342 :lowtag other-pointer-lowtag
343 :widetag complex-single-float-widetag
)
344 (real :c-type
"float")
345 (imag :c-type
"float"))
347 (define-primitive-object (complex-double-float
348 :lowtag other-pointer-lowtag
349 :widetag complex-double-float-widetag
)
351 (real :c-type
"double" :length
#!-x86-64
2 #!+x86-64
1)
352 (imag :c-type
"double" :length
#!-x86-64
2 #!+x86-64
1))
354 #!+(and sb-lutex sb-thread
)
355 (define-primitive-object (lutex
356 :lowtag other-pointer-lowtag
357 :widetag lutex-widetag
358 :alloc-trans %make-lutex
)
359 (gen :c-type
"long" :length
1)
360 (live :c-type
"long" :length
1)
361 (next :c-type
"struct lutex *" :length
1)
362 (prev :c-type
"struct lutex *" :length
1)
363 (mutex :c-type
"pthread_mutex_t *"
365 (mutexattr :c-type
"pthread_mutexattr_t *"
367 (condition-variable :c-type
"pthread_cond_t *"
370 ;;; this isn't actually a lisp object at all, it's a c structure that lives
371 ;;; in c-land. However, we need sight of so many parts of it from Lisp that
372 ;;; it makes sense to define it here anyway, so that the GENESIS machinery
373 ;;; can take care of maintaining Lisp and C versions.
374 ;;; Hence the even-fixnum lowtag just so we don't get odd(sic) numbers
375 ;;; added to the slot offsets
376 (define-primitive-object (thread :lowtag even-fixnum-lowtag
)
377 ;; no_tls_value_marker is borrowed very briefly at thread startup to
378 ;; pass the address of initial-function into new_thread_trampoline.
379 ;; tls[0] = NO_TLS_VALUE_MARKER_WIDETAG because a the tls index slot
380 ;; of a symbol is initialized to zero
381 (no-tls-value-marker)
382 (os-thread :c-type
"volatile os_thread_t")
383 ;; This is the original address at which the memory was allocated,
384 ;; which may have different alignment then what we prefer to use.
385 ;; Kept here so that when the thread dies we can releast the whole
386 ;; memory we reserved.
387 (os-address :c-type
"void *" :length
#!+alpha
2 #!-alpha
1)
388 (binding-stack-start :c-type
"lispobj *" :length
#!+alpha
2 #!-alpha
1)
389 (binding-stack-pointer :c-type
"lispobj *" :length
#!+alpha
2 #!-alpha
1)
390 (control-stack-start :c-type
"lispobj *" :length
#!+alpha
2 #!-alpha
1)
391 (control-stack-end :c-type
"lispobj *" :length
#!+alpha
2 #!-alpha
1)
392 (alien-stack-start :c-type
"lispobj *" :length
#!+alpha
2 #!-alpha
1)
393 (alien-stack-pointer :c-type
"lispobj *" :length
#!+alpha
2 #!-alpha
1)
394 #!+gencgc
(alloc-region :c-type
"struct alloc_region" :length
5)
395 (this :c-type
"struct thread *" :length
#!+alpha
2 #!-alpha
1)
396 (prev :c-type
"struct thread *" :length
#!+alpha
2 #!-alpha
1)
397 (next :c-type
"struct thread *" :length
#!+alpha
2 #!-alpha
1)
398 ;; starting, running, suspended, dead
399 (state :c-type
"volatile lispobj")
400 (tls-cookie) ; on x86, the LDT index
401 #!+(or x86 x86-64
) (pseudo-atomic-bits)
402 (interrupt-data :c-type
"struct interrupt_data *"
403 :length
#!+alpha
2 #!-alpha
1)
405 (interrupt-contexts :c-type
"os_context_t *" :rest-p t
))