Hi Marcel,
Hi Eliot.
In current Trunk, which has SistaV1 enabled, "Smalltalk specialObjectsArray at: 38" is still "nil" but should be "FullBlockClosure". Is this good? How can the bytecode "pushFullClosure" work?
Ha, good catch! The answer is key to one of Spur’s performance gains over the old object representation. If you collect the identityHashes of all Behaviors in the specialObjectsArray you’ll notice they all have small values. In Spur an object header *does not* contain a full reference to the class of the object. Instead it contains a 22 bit field that contains the identityHash of its class. The heap contains a sparse array mapping class identityHash to class object. That’s why Behavior>>identityHash is a different primitive to Object>>identityHash, to ensure that Behaviors have unique identityHashes.
Consequently when the vm instantiates FullBlockClosure, Array, Message, LargePositiveInteger et al, commonly used classes known to the VM, it is storing a constant into the object header, not fetching the class from the specialObjectsArray. In fact it writes the entire object header as a precomputed constant through the allocation pointer and hence instantiation in Spur is much faster than in V3.
But yes, we should arrange that (specialObjectsArray at:38) == FullBlockClosure.