1) isDoubleOop would be fast isnan is fast (push oop on fpreg, push oop on fpreg, test fpequal) would require a second test (int64) oop = NanOop to represent nan in Smalltalk... 2) conversion oop->native double is 0-OP
3) conversion native double->oop costs a isnan: oop=(isnan(d))?NanOop:(oop)d; 4) 32 bits native integer stored in low 32 bits would be very fast isSmallIntOop just cost a comparison of high 32 bits with SmallIntegerNanTag
conversions is just accessing low 32 bits, or filling high 32 bits with this tag 5) Addressing a 32bit space would be just as fast as with above trick 6) Addressing a 48bit space would cost a bitAnd:/bitOr: to tag/untag high 16 bits with Pointer48BitNanTag.
Given there are 4 bits for tags, this let us implement an immediate 32 bit character! 7) GarbageCollector trick could use highest of these 4 bits, isOop tests would cost more