Sealing, a Teaser #
hacking, August 15th 2007
As those who follow #lisp or sbcl-devel may know, I'm currently working of adding support for various aspects of class sealing to SBCL.
Sealing means diffent things in different contexts, but my preferred way of thinking about it is this: Sealing means (1) being able to tell a dynamic system that some aspects will not change (2) having the system enforce those restrictions once they are in place. A beneficial side-effect of sealing is that it often allows new optimizations to be applied.
One of the key insights to me was that sealing is not an all-or-nothing proposition: there are several things that can be sealed independently of each other.
What I currently have is:
- Superclass inheritance sealing. If the superclass inheritance of class C1 is sealed, it means that any true C1 is-a C2 relationship will always be true. New superclasses can still be added, so false C1 is-a C2 relations may still later become true. Sealing the superclass inheritance of a class implies sealing the superclass inheritance of all its superclasses.
- Subclass inheritance sealing. If the subclass inheritance of class C1 is sealed, it means that any true C2 is-a C1 relationship will always be true. New subclasses can still be added, so false C2 is-a C1 relations may still later become true. Sealing the subclass inheritance of a class implies sealing the subclass inheritance of all its subclasses.
- Direct slot location sealing. If the location of a direct instance allocated slot is sealed in class C, then the slot locations of all effective slot definitions with that name will be the same in C and all its subclasses. Unsurprisingly, sealing slot locations has a lot more restrictions then inheritance sealing — too many to enumerate here. Basically you cannot remove direct slots with sealed locations, and you cannot inherit from unrelated classes with sealed direct slot locations, or remove superclasses with sealed direct slot locations if they have subclasses with sealed direct slot locations.
That is naturally not the end of it, but it is a start, and will allow very efficient compilation of SLOT-VALUE with a constant second argument when the class of the first argument can be inferred to have the named slot at a constant location.
As a side note, my first cut of direct slot location sealing allowed more flexibility, but it turns out CLOS MOP as specified in Art of The Metaobject Protocol doesn't give enough leevay: the instance structure protocol it specifies doesn't seem to allow sparse instances with unused slot locations, which would have allowed removing slots whose locations have been sealed.