Request for Comment: MethodAnnotations for 3.9alpha

Alejandro F. Reimondo aleReimondo at smalltalking.net
Sun Aug 28 09:35:38 UTC 2005


Hello Marcus, and all;

The properties can be implemented for all objects
 (e.g. Digitalk's Smalltalk saga has had implemented
  for +10years, and it is proved to be helpfull).
If done this way, CompiledMethods will not be
 "special objects"... with properties :-)

> e.g. store:
>     (Object>>#halt) setProperty: #hello toValue: 5.
> and read:
>    (Object>>#halt) valueOfProperty: #value;

Please use messages like:
anObject properties   "returns the properties dictionary"
anObject propertyAt: aSymbol "returns th eproperty aSymbol or nil"
anObject propertyAt: aSymbol ifAbsent: aBlock
anObject propertyAt: aSymbol ifAbsentPut: aBlock

The only situation I think the messages like #setxxx:toValue:
 is if you have a class named #Value...
It is like calling "instance variables" for object collaborator's
 names when we have no class named #Variable
 it is used only for historial reasons but we must try to not
 continue doing the same error to not confuse novices
 (people that already think in languages and an object
 "Oriented" way... they see objects as dynamic/extensible
 variables to hold values of any "type"...)

Remember to consider properties when saving/loading
 objects from streams (if not implemented in the object,
 the registry must be considered while storing).
Any subclass can implement the #properties message
 to change the mechanism or store the dictionary in
 the object itself.

> 2) 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):
>
> Object>>mumble
>     <hello: 4>
>
> Tweak uses these annotations to describe when a method should be
> activated.

mmm... why to use a "primitive" mechanism?

mumble
    ^thisContext method propertyAt: #hello
(or something like this using only objects and no syntax/architecture sugar)

> 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 is the way it was implemented in VisualSmalltalk,
 but for Object class.
Doing that way you can have properties for all objects.

> This turns
> out to have some nice properties (no space is used for non-annotated
> methods) and
> a bad one: Performance. For ByteSurgeon, after annotation all methods
> (40.000), it was unusably slow.

Under optimized VMs (jitter?) the perfomance penalty is really low.

> 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.

The literal index can be codified in the compiledMethod's
 header if bits are free... (or can be extended)
It can also be detected by detecting more literals than the header informs
 and/or having a "special class" to detect your addition (for example,
 a TweakLiteral) to detect what literal's you added (the original/old
literal
 and another interesting information; e.g.: if you want to
 put a silent cookie to parasityze in a method as a proxy for
 protection or use count/metrics)

> 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.

I prefer a specialized literal detectable by it's species
 (don't care about the literal position).

> Any comments? Does anyone see a problem with the annotations itself
> or the implementation?

I see no problems, it is a well known and comfortable mechanism
 to annotate objects and has been used from long time ago.

best,
Ale.


----- Original Message ----- 
From: "Marcus Denker" <denker at iam.unibe.ch>
To: "The general-purpose Squeak developers list"
<squeak-dev at lists.squeakfoundation.org>
Sent: Sunday, August 28, 2005 2:41 PM
Subject: Request for Comment: MethodAnnotations for 3.9alpha


> Hello squeakers,
>
> Of the long and exiting list of things that are in consideration for
> 3.9a, one is MethodAnnotations.
> This is a changeset that was done by Andreas long time ago (2002, I
> think) and it's used extensively
> in Tweak. At SCG, we have used it for ByteSurgeon and are using it
> for another ongoing project.
>
> What are MethodAnnotations?
> ---------------------------------------
>
> MethodAnnotations can be seen from two perspectives:
>
> 1) storing state in CompiledMethod objects.
>
> In Squeak, CompiledMethod is a strange class. One thing you can't
> do is adding an instance variable. This makes experimentation awfully
> complicated, e.g. people made hacks to store state in the literalFrame
> or in class vars... see MethodWrappers for an example.
>
> MethodAnnotations just provides a general, nice and easy way to store
> stuff in compiledMethods, no need for hacks anymore.
>
> e.g. store:
>
>     (Object>>#halt) setProperty: #hello toValue: 5.
>
> and read:
>
>    (Object>>#halt) valueOfProperty: #value;
>
>
> 2) 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):
>
> Object>>mumble
>     <hello: 4>
>
> Tweak uses these annotations to describe when a method should be
> activated.
>
> 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. For ByteSurgeon, after annotation all methods
> (40.000), it
> was unusably slow.
>
> 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.
>
> 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.
>
> Please note that the attached changesets need to be files in in-order
> and the first
> one will recompile the whole image.
>
> Filling the last literal with the class (or trait) for all methods
> will be done in an addional step
> after the annotation cs is in 3.9. Then we will change the
> implementation of compiledMethod>>who
> to use this information.
>
> Any comments? Does anyone see a problem with the annotations itself
> or the implementation?
>
>      Marcus
>
>


----------------------------------------------------------------------------
----


>
>


----------------------------------------------------------------------------
----


>
>




More information about the Squeak-dev mailing list