When I first introduced Self, I mentioned that Self is a programming language which employs prototype-based inheritance; it does not depend on a class-instance distinction to facilitate object-oriented programming, but rather, it uses a prototype object from which copies are created. The methods associated with a prototype is stored in a traits object which is just another object storing methods that can be used on a prototype and all its copies through a parent slot.
The trouble begins when we actually try to implement this prototype-based
inheritance system as an actual virtual machine, particularly with regards to
memory consumption. Say that I have a prototype object
point with a constant
parent slot pointing to
traits point and two assignable slots,
y.1 When we copy this object, we would expect to copy all three fields. But
if we scale that up, that’s so much unnecessary data being copied! For one, for
every copy of the
point prototype we make, we’re copying that
parent slot reference. Not to mention, because our language is dynamic, we can’t
y as offsets into memory, because they might be constant
or assignable (Self can’t intrinsically know). So our naive implementation would
be pretty inefficient.
Can we make this more memory-efficient? In fact, we can; we can exploit the fact that most Self objects that are copied only ever have their assignable slots modified. Let’s take a look at how the original developers of Self have optimized the memory usage of the Self virtual machine.