1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
10 (in-package "SB!KERNEL")
12 ;;; ANSI doesn't guarantee the existence of specialized vectors
13 ;;; other than T, BIT, CHARACTER.
15 ;;; (MAKE-ARRAY 10 :ELEMENT-TYPE '(UNSIGNED-BYTE 4))
16 ;;; in the cross-compilation host, we could easily end up with a
17 ;;; vector of (UNSIGNED-BYTE 8) or of T, and the dumped result would
20 ;;; To reduce the prominence of this issue in cross-compilation, we
21 ;;; record arrays that should be specialized in a hashtable.
22 ;;; Fasl dumping will complain about a specialized array that does not
23 ;;; have an entry in the table.
25 ;;; Previously some specialized arrays were "weakened" to (ARRAY T) in the
26 ;;; cross-compiler which served to show that the code was indifferent to
27 ;;; specialization, but made no guarantees about what array type was dumped.
28 ;;; Explicit code was needed to make correct constant arrays at load-time.
29 ;;; The current approach permits use of array constants in an easy way that
30 ;;; avoids host-Lisp-based reflection, and avoids having a DEFTYPE that
31 ;;; changes its meaning between the host and target compilations.
33 ;;; The motivation for this host-agnostic approach is that it supports dumping
34 ;;; (UNSIGNED-BYTE 64) array literals in a 32-bit cross-compilation host,
35 ;;; where that array type is almost surely upgraded to (ARRAY T).
36 ;;; Therefore a host-reflection-based mechanism would be almost certain to fail.
38 ;;; In case anyone wants to rewrite this yet again, here's an alternate way
39 ;;; that was deemed unworkable: in cross-compilation, all specialized arrays
40 ;;; were wrapped in an XC-ARRAY-WRAPPER struct consisting of one slot for
41 ;;; the desired element-type and one slot with the real array. All affected
42 ;;; uses of AREF and (SETF AREF) had to be macroized so that the cross-compiler
43 ;;; could use (AREF (XC-ARRAY-WRAPPER-DATA obj) index) where the real compiler,
44 ;;; and all code compiled by it, would just use AREF using a single abstraction.
45 ;;; CTYPE-OF was hacked to return ARRAY for an xc-array-wrapper which
46 ;;; meant that the cross-compiler thought that transforms on arrays should run
47 ;;; on wrappers, e.g. the foldable function LENGTH should look into wrappers,
48 ;;; as could bounds-checks (ARRAY-DIMENSION). This technique led to confusing
49 ;;; code within the compiler and was abandoned in favor of the hashtable.
52 ;; The target code is trivial
53 (defmacro !make-specialized-array
(length element-type
&optional contents
)
54 `(make-array ,length
:element-type
,element-type
55 ,@(if contents
`(:initial-contents
,contents
))))
59 ;; Use this only for array specializations that are not required by ANSI.
60 (defmacro !make-specialized-array
(length element-type
&optional contents
)
61 (once-only ((et element-type
))
62 `(register-specialized-array
63 (make-array ,length
:element-type
,et
65 `(:initial-contents
,contents
)
66 ;; Initialize in case it upgrades to (ARRAY T)
67 ;; and gets filled with NIL where SBCL would 0-fill.
68 `(:initial-element
0)))
70 (defun !coerce-to-specialized
(data element-type
)
71 (register-specialized-array (coerce data
`(simple-array ,element-type
1))
73 ;; The specialized array registry has file-wide scope. Hacking that aspect
74 ;; into the xc build scaffold seemed preferable to hacking the compiler.
75 (defun register-specialized-array (array element-type
)
76 (setf (gethash array sb-cold
::*array-to-specialization
*) element-type
)
78 (defun !specialized-array-element-type
(array)
79 (cond ((gethash array sb-cold
::*array-to-specialization
*))
80 ((bit-vector-p array
) 'bit
)
81 ((stringp array
) 'base-char
)