Make better use of tag bits on 64bit platforms
Currently we have only one tagging scheme for both 32bit and 64bit platforms:
| bits | cl_type | boxed | comment |
|---------+-------------+-------+---------------------------|
| 00 | [object] | + | |
| 01 | t_list | - | ECL_NIL or a box for cons |
| 10 | t_character | - | |
| 11 | t_fixnum | - | 30/62 bits for a fixnum |
It is noteworthy, that in this scheme tag bits directly correspond to the cl_type enum number, so querying type of such object is just a bit operation: (object & 0x3)
.
I've drafted two schemes, one which preserves this property (not very flexible) and one which will require more bit fiddling but arguably better and enabling faster code (more bits for fixnum and space left for encoding more immediate objects if they fit in < 60 bits.
Proposed scheme for tag bits on 64 bit architecutre. Some types are
boxed yet they have unique tag bits pattern for quick type check w/o
memory access.
| bits | cl_type | boxed | comment |
|---------+-----------------------------+-------+--------------------------------------------------|
| 0000 | [object] | + | any other object (always boxed) |
| 0001 | t_list | - | small cons uses this |
| 0010 | t_character | - | |
| 0011 | t_fixnum | - | 60 bits for fixnum |
| 0100 | t_bignum | + | |
| 0101 | t_ratio | + | |
| 0110 | t_singlefloat | - | |
| 0111 | t_doublefloat | + | |
| 1000 | t_longfloat | + | |
| 1001 | t_complex | + | |
| 1010 | t_csfloat | + | unused on platforms without native complex float |
| 1011 | t_cdfloat | + | unused on platforms without native complex float |
| 1100 | t_clfloat | + | unused on platforms without native complex float |
| 1101 | [reserved] | | ? t_rack (based on smallcons) |
| 1110 | [reserved] | | ? t_locative (first-class location) |
| 1111 | [reserved] | | ? t_smallbit (simple bit-vector 52b + 6b dim) |
Alternative scheme (not preserving relation immediate tag = cl-type,
this will require more bit fiddling):
| 64 bits | cl_type | boxed | comment |
|---------+-----------------------------+-------+--------------------------------------------|
| 00 | [object] | + | two bits are used to identify object type |
| 0000 | [other type] | + | |
| 0100 | t_bignum / t_ratio | + | this or t_fixnum -> RATIONAL |
| 1000 | t_doublefloat / t_longfloat | + | this or t_singefloat -> FLOAT |
| 1100 | t_complex / t_c?float | + | this -> COMPLEX |
|---------+-----------------------------+-------+--------------------------------------------|
| 1 | t_fixnum | - | 63 bits for fixnum |
|---------+-----------------------------+-------+--------------------------------------------|
| 10 | [immediate] | - | |
| 0010 | t_list | - | ECL_NIL or a box for cons |
| 0110 | t_character | - | we can encode more immediates in 0110 |
| 1010 | t_singlefloat | - | then we would have two [reserved] pointers |
| 1110 | [reserved] | - | ? t_locative, t_rack, t_smallbit, ... |