Hi Marcus -
What are MethodAnnotations?
MethodAnnotations can be seen from two perspectives:
- storing state in CompiledMethod objects.
This is good and I wholeheartedly agree with it.
Syntax for Method Annotations.
We can set annoations to methods using the syntax we already know
for primitives (which are, in a sense, just an annotation):
Let me caution you about this a little. If compatibility is a concern (and I believe that contrary to Tweak, for many people compatibility is a major concern here) you may not want to introduce syntax for annotations lightly. I wonder if (except from Tweak) there is any existing use for annotation that would *require* syntactical support. And there isn't you may want to be careful about when and how to introduce that support.
Tweak uses these annotations to describe when a method should be activated.
Actually no. There is more involved than that and because of it the compiler has to support it as a syntactical entity (very much like like the primitive:module: syntax which is recognized separately, too).
How are they implemented?
Andreas' orginal implemention used a big WeakIdentityKeyDictionary in a class var of CompiledMethods to store the IdentityDictionary for each method. This turns out to have some nice properties (no space is used for non-annotated methods) and a bad one: Performance.
Unfortunately, there is more than one. For example, serializing compiled methods becomes a tricky issue (the main reason why I need to switch in Tweak to the new implementation).
So we hacked a version that used the literealFrame instead, after discussing this with Andreas, we now use the second-last literal Frame entry. The reasoning is the following: The first one is already used for some primitives, the last one encodes the class in the case that there is a supersend in the method.
So if we use the last entry to store the class for each method (supered or not), we can put the annoations in the one before and don't need to test for anything. Putting the class (or Trait) in the last litereal has the nice side-effect of making a fast #who possible.
Plus: We can also store the selector of a method which is extremely helpful in various situations and makes #who *blindingly* fast ;-)
Plus: We can trivially remove the awkward encoding of the file pointer (this immediately gives us an unlimited size for the changes and sources file).
Plus: We can encode which package a method belongs to right in the method.
...
The changesets attached are a first step: We are right now adding the class binding to all methods but quickmethods (need to fix that), the second last literal is initialized with nil and will lazy initalize the property dictionary if it's accessed.
Sounds good so far, but can we create a new class CompiledMethodProperties (instead of using a dictionary), please? The point being that with further normalization of CompiledMethod we will almost certainly want to add some iVars and having a dictionary will require us to do more work for converting from dictionary to an explicit object etc.
Cheers, - Andreas