Samuele Pedroni wrote:
From: Jeremy Hylton <jeremy@zope.com>
> "SP" == Samuele Pedroni <pedronis@bluewin.ch> writes: ... SP> one can try to guess the slots of a class looking for the SP> "self.attr" pattern at compile time in a more or less clever SP> way. The set of compile-time guessed attrs will be passed to SP> MAKE_CLASS which will construct the runtime guess using the SP> union of the super-classes guesses and the compile time guess SP> for the class. This information can be used to layout a dlict.
Right! There's another step necessary to take advantage though. When you execute a method you don't know the receiver type (self.__class__). So you need to specialize the bytecode to a particular receiver the first time the method is called. Since this could be relatively expensive and you don't know how often the method will be executed, you need to decide dynamically when to do it. Just like HotSpot.
Why not assume the general case is the most common, ie, that the object is an instance of this class or one of its subclasses? That way you could do the specialization at compile time. And for the (presumably) few times that this isn't true fallback to another technique, perhaps like HotSpot. Also, doesn't calling a base class method as: Base.method(self) # in particular __init__() vs. self.method() create problems if you specialize for a specific class? Or does specialization necessarily mean for a subclass and all its base clases?
Right, because with multiple inheritance you cannot make the layout of a subclass compatible with that of *all* superclasses, so simple monomorphic inline caches will not work :(.
ISTM that it would be best to handle single inheritance first. Multiple inheritance could perhaps be handled for the class with the most commonly referenced attribute (assuming 2+ classes don't define the same attr. And use a fallback technique for all other cases.
We probably have to worry about a class or instance being modified in a way that invalidates the dlict offsets computed. (Not sure here, but I think that's the case.) If so, we probably need a different
Right, if an attr is deleted, methods added/removed dynamically, etc.
object -- call it a template -- that represents the concrete layout and is tied to unmodified concrete class. When objects or classes are modified in dangerous ways, we'd need to invalidate the template pointer for the affected instances.
By using a template, doesn't that become a dict lookup again?
These are all interesting topics, although from these more or less informal discussions to results there is a lot of details and code :(.
I agree. Since we can't know what will be optimal, it seems safer to keep the existing functionality as a fallback case and try to improve things with small steps (eg, single inheritance, first).
But already improving the global lookup thing would be a good step.
Definitely. Neal