Adam Warner <usenet@consulting.net.nz> wrote:
+---------------
| I see that EDX is being set to a machine value of 0 using the XOR idiom.
| A little more experimentation with (print 1) and (print 2) shows that a
| machine integer is four times the size of a CMUCL fixnum.
+---------------
To be precise, it is four times the *range*, not size. The size of a
machine word is the *same* as the size of a fixnum, as is any other
CMUCL Lisp object (a.k.a. descriptor). The two low-order bits of CMUCL
fixnums are always zero. which which why they range over only 1/4
of the value space. (See "internal-design.txt"[1] for more detail.)
+---------------
| Thus the only time the Lisp representation matches the machine
| representation is when the Lisp fixnum is zero.
+---------------
Uh... Don't forget about the contents of elements of specialized arrays!
These can be identical to the machine representation.
+---------------
| I built a countdown variable hoping that a more efficient test could be
| built by the compiler than a comparison to NIL. If we replace the above
| disassembly with (print nil) we see that NIL is represented as a memory
| location. Whether an object is NIL involves comparing an object to this
| address, e.g. CMP EDX, #x2800000B, where #x2800000B is the address of NIL.
+---------------
This is a design choice CMUCL made, just one of several ways to
do it. In Common Lisp, NIL is a bit of a difficult case for type
representation, since it is *both* a symbol and the list terminator --
(AND (SYMBOLP NIL) (ENDP NIL)) ==> T -- *and* you want CAR/CDR to
be fast on it. CMUCL chose[1] to pun a CONS cell into the middle of
the NIL symbol object, said cell containing (CONS NIL NIL). Then they
put that symbol object in a fixed virtual address (#x2800000B). So
both CAR/CDR & symbol ops are fast,
One could choose some other representation for NIL to speed the ENDP
test, but then all of the *other* operations on NIL would be slowed down.
+---------------
| A comparison to zero doesn't require this address overhead.
+---------------
But if you steal the zero machine word for NIL, then you can't
do fast fixnum arithmetic without constantly adjusting offsets.
There's no free lunch.
Personally, I think the choices CMUCL made are generally pretty
reasonable, but YMMV.
-Rob
[1] As ${CMUCL-18E}/lib/cmucl/doc/impl/internal-design.txt notes,
the *3* lower bits of a machine word are used for tags, but
both the 000 and 100 (binary) codepoints are assigned to fixnums.
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607