2 (defun list-all-layouts ()
5 ;; I should probably incorporate permgen into the set of spaces
6 ;; that can be listed, but until then ...
7 (sb-vm::map-objects-in-range
8 (lambda (obj widetag size
)
9 (declare (ignore widetag size
))
10 (when (sb-kernel::layout-p obj
)
12 (sb-kernel:%make-lisp-obj sb-vm
:permgen-space-start
)
13 (sb-kernel:%make-lisp-obj
(sb-sys:sap-int sb-vm
:*permgen-space-free-pointer
*)))
16 (sb-vm:list-allocated-objects
:all
:type sb-vm
:instance-widetag
17 :test
#'sb-kernel
::layout-p
))
19 (with-test (:name
:funinstance-layout-bitmaps-all-same
)
20 (let* ((list (list-all-layouts))
22 (remove-if-not (lambda (x) (find (sb-kernel:find-layout
'function
)
23 (sb-kernel:layout-inherits x
)))
25 (bitmaps (mapcar 'sb-kernel
::%layout-bitmap fun-layouts
)))
26 (assert (= (length (remove-duplicates bitmaps
)) 1))))
28 (with-test (:name
:stream-layout-bits
)
29 (loop for wrapper being each hash-value
30 of
(sb-kernel:classoid-subclasses
(sb-kernel:find-classoid
't
))
31 do
(flet ((check-bit (bit ancestor-type
)
32 (let ((ancestor (sb-kernel:find-layout ancestor-type
)))
33 (when (or (eq wrapper ancestor
)
34 (find ancestor
(sb-kernel:layout-inherits wrapper
)))
35 (assert (logtest bit
(sb-kernel:layout-flags wrapper
)))))))
36 (check-bit sb-kernel
:+stream-layout-flag
+ 'stream
)
37 (check-bit sb-kernel
:+string-stream-layout-flag
+ 'string-stream
)
38 (check-bit sb-kernel
:+file-stream-layout-flag
+ 'file-stream
))))
40 (with-test (:name
:boxed-layout-bits
)
42 (dolist (name '(hash-table sb-thread
:thread sb-thread
::avlnode
))
43 (let ((layout (sb-kernel:find-layout name
)))
44 (assert (not (logtest (sb-kernel:layout-flags layout
)
45 sb-kernel
:+strictly-boxed-flag
+)))))
46 ;; Positive test, just a small sampling
47 (dolist (name '(condition warning error
48 pathname logical-pathname
49 sb-impl
::string-output-stream
50 structure-object sb-c
::node
52 (let ((layout (sb-kernel:find-layout name
)))
53 (assert (logtest (sb-kernel:layout-flags layout
)
54 sb-kernel
:+strictly-boxed-flag
+)))))
56 ;;; Test some aspects of bitmaps, and the iterator.
58 ;;; A layout-bitmap has the same representation as a BIGNUM-
59 ;;; least-significant word first, native endian within the word.
60 ;;; Like a bignum, all but the last word are unsigned, and the last is signed.
61 ;;; This representation allows trailing slots to be either all tagged
65 (defstruct (d3 (:include d2
)))
66 (defstruct (d4 (:include d3
)))
67 (defstruct (d5 (:include d4
)))
68 (defstruct (d6 (:include d5
)))
69 (defstruct (d7 (:include d6
)))
70 (defstruct (d8 (:include d7
)))
71 (defstruct (d9 (:include d8
)))
72 (defstruct (d10 (:include d9
)))
73 (defstruct (d11 (:include d10
)))
74 (defstruct (d12 (:include d11
)))
75 (defstruct (d13 (:include d12
)))
76 (defstruct (d14 (:include d13
)))
77 (defstruct (d15 (:include d14
)))
79 (defparameter *test-layouts
*
80 (coerce (list* (sb-kernel:find-layout
't
)
81 (sb-kernel:find-layout
'structure-object
)
82 (loop for i from
2 to
15
83 collect
(sb-kernel:find-layout
(intern (format nil
"D~D" i
)))))
86 ;;; Assert that BITMAP-NWORDS is insensitive to depthoid
87 (with-test (:name
:bitmap-nwords-1
)
88 (loop for depthoid from
3 to
16
90 (let ((layout (sb-kernel:make-layout
92 (sb-kernel:make-undefined-classoid
'blah
)
94 :bitmap
#+64-bit
#x6fffffffeeeeff02
; 1-word bignum
96 :inherits
(subseq *test-layouts
* 0 depthoid
)
97 :flags sb-kernel
:+structure-layout-flag
+)))
98 (assert (= (sb-kernel:bitmap-nwords layout
) 1)))))
99 (with-test (:name
:bitmap-nwords-2
)
100 (loop for depthoid from
3 to
16
102 (let ((layout (sb-kernel:make-layout
104 (sb-kernel:make-undefined-classoid
'blah
)
106 :bitmap
#+64-bit
#xffffffffeeeeff02
; 2-word bignum
108 :inherits
(subseq *test-layouts
* 0 depthoid
)
109 :flags sb-kernel
:+structure-layout-flag
+)))
110 (assert (= (sb-kernel:bitmap-nwords layout
) 2)))))
112 (defun layout-id-vector-sap (layout)
113 (sb-sys:sap
+ (sb-sys:int-sap
(sb-kernel:get-lisp-obj-address layout
))
114 (- (ash (+ sb-vm
:instance-slots-offset
115 (sb-kernel:get-dsd-index sb-kernel
:layout sb-kernel
::id-word0
))
117 sb-vm
:instance-pointer-lowtag
)))
119 ;;;; Ensure ID uniqueness and that layout ID words match the ID's in the INHERITS vector.
120 (defparameter *all-wrappers
*
122 ;; temporary layouts (created for parsing DEFSTRUCT)
123 ;; must be be culled out.
125 (and (typep (sb-kernel:layout-classoid x
)
126 'sb-kernel
:structure-classoid
)
127 (eq (sb-kernel:layout-equalp-impl x
)
128 #'sb-kernel
::equalp-err
)))
129 (sb-vm::list-allocated-objects
:all
130 :type sb-vm
:instance-widetag
131 :test
#'sb-kernel
::layout-p
)))
133 ;;; Assert no overlaps on ID
134 (with-test (:name
:id-uniqueness
)
135 (let ((hash (make-hash-table)))
136 (dolist (wrapper *all-wrappers
*)
137 (let ((id (sb-kernel:layout-id wrapper
)))
138 (sb-int:awhen
(gethash id hash
)
139 (error "ID ~D is ~A and ~A" id sb-int
:it wrapper
))
140 (setf (gethash id hash
) wrapper
)))))
142 ;;; Assert that IDs are right
143 (with-test (:name
:id-versus-inherits
)
144 (let ((structure-object (sb-kernel:find-layout
'structure-object
)))
145 (dolist (wrapper *all-wrappers
*)
146 (when (find structure-object
(sb-kernel:layout-inherits wrapper
))
147 (let* ((layout wrapper
)
149 (sb-sys:with-pinned-objects
(layout)
150 (let ((sap (layout-id-vector-sap layout
)))
151 (loop for depthoid from
2 to
(sb-kernel:layout-depthoid wrapper
)
152 collect
(sb-sys:signed-sap-ref-32 sap
(ash (- depthoid
2) 2))))))
154 (map 'list
'sb-kernel
:layout-id
(sb-kernel:layout-inherits wrapper
))))
155 (unless (equal (list* (sb-kernel:layout-id
(sb-kernel:find-layout
't
))
156 (sb-kernel:layout-id
(sb-kernel:find-layout
'structure-object
))
158 (append expected
(list (sb-kernel:layout-id wrapper
))))
159 (error "Wrong IDs for ~A: expect ~D actual ~D~%"
160 wrapper expected ids
)))))))
162 (makunbound '*all-wrappers
*)
164 (defun random-bitmap (nwords random-state sign-bit
)
167 ;; Deposit N-WORD-BITS bits into INTEGER NWORDS times,
168 ;; then make sure the sign bit is as requested.
170 (setf (ldb (byte sb-vm
:n-word-bits position
) integer
)
171 ;; If the PRNG generates a 0 word, change it to 1.
172 (max 1 (random (ash 1 sb-vm
:n-word-bits
) random-state
)))
173 (incf position sb-vm
:n-word-bits
))
174 ;; If INSTANCE-DATA-START is 1, then the 0th bitmap bit must be 0
175 ;; because we don't want LAYOUT to be lumped in with tagged slots
176 ;; (even though it's of course tagged)
177 (when (and (= sb-vm
:instance-data-start
1) (oddp integer
))
178 (setq integer
(logxor integer
1)))
181 (ldb (byte (1- (* nwords sb-vm
:n-word-bits
)) 0) integer
))
183 (dpb integer
(byte (1- (* nwords sb-vm
:n-word-bits
)) 0) -
1)))))
184 (compile'random-bitmap
)
186 ;;; Check the random bitmap generator a little.
187 (with-test (:name
:check-random-bitmaps
)
188 (loop for nwords from
2 to
8
189 do
(dolist (sign '(:positive
:negative
))
191 (let ((b (random-bitmap nwords
*random-state
* sign
)))
192 (assert (= (sb-bignum:%bignum-length b
) nwords
)))))))
194 (defun make-layout-for-test (depthoid bitmap
)
195 (sb-kernel:make-layout
1 ; random hash
196 (sb-kernel:make-undefined-classoid
'blah
)
199 :inherits
(subseq *test-layouts
* 0 depthoid
)
200 :flags sb-kernel
:+structure-layout-flag
+))
201 (compile 'make-layout-for-test
)
203 (defun test-bitmap-iterator (layout instance-length reference-bitmap
)
205 (declare (fixnum count
))
206 (sb-kernel:do-layout-bitmap
(slot-index taggedp layout instance-length
)
208 (sb-int:aver
(eq (logbitp slot-index reference-bitmap
) taggedp
)))
209 (sb-int:aver
(= count
(- instance-length sb-vm
:instance-data-start
)))))
210 (compile 'test-bitmap-iterator
)
212 ;;; Now randomly test bitmaps of varying length in words
213 ;;; and for both values of the sign bit in the last word.
214 ;;; Test with instances that are longer than the bitmap's significant bit count
215 ;;; so that we can verify infinite sign-extension.
216 ;;; And test with shorter to make sure the loop is properly bounded
217 ;;; by the instance length.
218 (with-test (:name
:random-bitmaps
)
219 (let ((rs (make-random-state t
)))
220 ;; Modulate the depthoid so that BITMAP-START is at different indices.
221 (loop for depthoid from
6 to
10
222 do
(loop for n-bitmap-words from
1 to
6
224 (dolist (sign '(:positive
:negative
))
225 (let* ((bitmap (random-bitmap n-bitmap-words rs sign
))
226 (layout (make-layout-for-test depthoid bitmap
)))
227 (loop for instance-length from
5 to
(* (+ n-bitmap-words
2)
229 do
(test-bitmap-iterator layout instance-length bitmap
))))))))