Clozure / ccl

Clozure Common Lisp
http://ccl.clozure.com
Apache License 2.0
840 stars 105 forks source link

aref from upgraded vector enters debugger when called from function but not top-level #478

Closed snunez1 closed 2 months ago

snunez1 commented 5 months ago

Code

(require 'alexandria)

(defstruct canonical-sequence
  "Canonical representation of a sequence of array indexes."
  (vector nil :type (simple-array alexandria:array-index (*))))

(defun canonical-sequence (sequence)
  "Canonical representation of array indexes from canonical-sequence SEQUENCE.
May share structure. Vectors of the upgraded type of (SIMPLE-ARRAY ARRAY-INDEX (*)) are preferred
for efficiency, otherwise they are coerced."

  (let ((vector (coerce sequence '(simple-array alexandria:array-index (*)))))
    (assert (and (plusp (length vector))
                 (every (lambda (index)
                          (typep index 'alexandria:array-index))
                        vector)))
    (make-canonical-sequence :vector vector)))

(defun foo (x)
  (aref (canonical-sequence-vector x) 0))

Demonstration

CL-USER> (defparameter *cs* (canonical-sequence #(2 3 5)))
*CS*
CL-USER> (aref (canonical-sequence-vector *cs*) 0)
2
CL-USER> (foo *cs*)
; Evaluation aborted on #<TYPE-ERROR #x210186F09D>.

CL-USER> (lisp-implementation-version)
"Version 1.12 (v1.12) WindowsX8664"

This is too low level for me to form a working theory, but it may be similar or related to #229. Odd that it works from the top level, but fails when called from within a function. Alignment issue? The code is known to work with CCL on ARM32.

informatimago commented 5 months ago

This code works for me on "Version 1.12.1 (v1.12.1-7-g4912320e) Darwinx8664". Try to load, or compile and load the source again. Perhaps you have an old version of foo?

metayan commented 5 months ago

Confirming issue on "Version 1.12.2 (v1.12.2-7-g7804e4f9) DarwinX8664"

> Error: The value #<VECTOR 3 type FIXNUM, simple>
 is not of the expected type CCL::SIMPLE-UNSIGNED-DOUBLEWORD-VECTOR.
snunez1 commented 5 months ago

This code works for me on "Version 1.12.1 (v1.12.1-7-g4912320e) Darwinx8664". Try to load, or compile and load the source again. Perhaps you have an old version of foo?

I've seen this intermittently. The https://github.com/Lisp-Stat/select/issues/3 issue mentions that sometimes, rarely, it seems to work fine. Another user there encountered it and has a full stack trace. That's what make me suspect a memory/alignment problem.

metayan commented 5 months ago

Confirming the issue on both Darwin (Catalina) and Linux (Devuan Daedalus) x8664. Using v1.12.1, v1.12.2 and current master (v1.12.2-14-gb947aece).

Also with the version @informatimago (v1.12.1-7) reported as working. However, here it's v1.12.1-7-g7aecdb0f. (Can't find a 4912320e.)

informatimago commented 5 months ago

Also, it depends on the optimization. I can reproduce it with the last setting:

(declaim (optimize (speed 0) (space 0) (safety 3) (debug 3) (compilation-speed 3))) ; no
(declaim (optimize (speed 3) (space 3) (safety 0) (debug 0) (compilation-speed 0))) ; no
(declaim (optimize (speed 1) (space 1) (safety 0) (debug 0) (compilation-speed 1))) ; yes
xrme commented 4 months ago

I think x8664-array-type-name-from-ctype may be at fault here.

? (x8664::x8664-array-type-name-from-ctype (ccl::specifier-type '(simple-array (mod 72057594037927935) (*))))
:UNSIGNED-64-BIT-VECTOR

But CCL actually chooses to use a (simple-array fixnum (*)) to represent an array with the element type of (mod 72057594037927935).

CL-USER> (coerce #(2 3 5) '(simple-array (mod 72057594037927935)))
#(2 3 5)
CL-USER> (type-of *)
(SIMPLE-ARRAY FIXNUM (3))

In that case, I'd think that :fixnum-vector would be correct thing for x8664-array-type-name-from-ctype to return.

Interestingly, ppc64-array-type-name-from-ctype would do the same thing, so this issue has been around a long time.

If a little more thinking and testing proves this to be correct, I'll check in a fix.

snunez1 commented 2 months ago

This seems fixed. Closing.