Comment 0 for bug 629058

Revision history for this message
Tobias C. Rittweiler (tcr) wrote :

I think SBCL has all right to coalesce memory accesses for read-only
structure slots. In my real-life case, INNER actually has lots of slot
and you often want to increment several slots at once, but the API
actually always expects an OUTER.

(defstruct inner
  (x 0 :type (unsigned-byte 32)))

(defstruct outer
  (in (make-inner) :type inner :read-only t))

(declaim (inline u32+))
(defun u32+ (x y)
  (declare (type (unsigned-byte 32) x y))
  (logand #xFFFFFFFF (+ x y)))

(defun foo (outer)
  (declare (type outer outer))
  (declare (optimize speed))
  (setf (inner-x (outer-in outer)) (u32+ 1 (inner-x (outer-in outer))))
  (setf (inner-x (outer-in outer)) (u32+ 1 (inner-x (outer-in outer))))
  (values))

; disassembly for FOO
; 0C7DC6DE: 8B4A07 MOV ECX, [EDX+7] ; no-arg-parsing entry point
; 6E1: 8B5A07 MOV EBX, [EDX+7]
; 6E4: 8B43FF MOV EAX, [EBX-1]
; 6E7: C1E808 SHR EAX, 8
; 6EA: 8B5C83FF MOV EBX, [EBX+EAX*4-1]
; 6EE: 43 INC EBX
; 6EF: 8B41FF MOV EAX, [ECX-1]
; 6F2: C1E808 SHR EAX, 8
; 6F5: 895C81FF MOV [ECX+EAX*4-1], EBX
; 6F9: 8B4A07 MOV ECX, [EDX+7]
; 6FC: 8B5207 MOV EDX, [EDX+7]
; 6FF: 8B42FF MOV EAX, [EDX-1]
; 702: C1E808 SHR EAX, 8
; 705: 8B5482FF MOV EDX, [EDX+EAX*4-1]
; 709: 42 INC EDX
; 70A: 8B41FF MOV EAX, [ECX-1]
; 70D: C1E808 SHR EAX, 8
; 710: 895481FF MOV [ECX+EAX*4-1], EDX
; 714: 8D5D08 LEA EBX, [EBP+8]
; 717: 31C9 XOR ECX, ECX
; 719: BA0B001001 MOV EDX, 17825803
; 71E: 8BFA MOV EDI, EDX
; 720: 8BF2 MOV ESI, EDX
; 722: F9 STC
; 723: 8BE5 MOV ESP, EBP
; 725: 5D POP EBP
; 726: C3 RET
; 727: CC0A BREAK 10 ; error trap
; 729: 02 BYTE #X02
; 72A: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR
; 72B: 4F BYTE #X4F ; ECX
; 72C: CC0A BREAK 10 ; error trap
; 72E: 02 BYTE #X02
; 72F: 2D BYTE #X2D ; OBJECT-NOT-INSTANCE-ERROR
; 730: 90 BYTE #X90 ; EDX