problem with CompiledMethod equality

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

problem with CompiledMethod equality

Mariano Martinez Peck
Hi folks. I was debugging a problem with Moose and I realized that 2 different methods can have the same CompiledMethod. This was weird for me. I don't know if this is correct or not.

For example, evaluate:

(InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)    ->  true

If you look at

CompiledMethod = aCompiledMethod 
    "Answer whether the receiver implements the same code as aCompiledMethod."

    | numLits |
    self == aCompiledMethod
        ifTrue: [ ^ true ].
    self class = aCompiledMethod class
        ifFalse: [ ^ false ].
    self size = aCompiledMethod size
        ifFalse: [ ^ false ].
    self header = aCompiledMethod header
        ifFalse: [ ^ false ].
    self initialPC to: self endPC do: [ :i |
        (self at: i) = (aCompiledMethod at: i)
            ifFalse: [ ^ false ] ].
    (self sameLiteralsAs: aCompiledMethod)
        ifFalse: [ ^ false ].
    self halt.
    ^ true


It is returning in the last ^ true.

What was weird for me is that (self sameLiteralsAs: aCompiledMethod)  returns true also. But if I print both literals:

self literals ->  {#methodReturnTop. (#InstructionClient->InstructionClient)}

aCompiledMethod literals ->  {#doDup. (#InstructionClient->InstructionClient)}

So...for me they are differnt, but sameLiteralsAs:  is returning true. Debugging that, it seems that in that method it is returning in the last ^ true.

So...any hints? is this the expected behavior ?  or it is a bug ?

Thanks

Mariano



_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Mariano Martinez Peck
Sorry...I forgot a detail: the problem is that they were storing CompiledMethods in a Dictionary, keys. I guess in Pharo 1.0 it works perfect, but in 1.1 since keys return a Set (that was the changed?), you miss some methods ;)

Just do

InstructionClient methods size -> 27
InstructionClient methods asSet size -> 21

so...it is not fun :(

solution ? ideas? help ?

Thanks :)


On Tue, May 18, 2010 at 3:35 PM, Mariano Martinez Peck <[hidden email]> wrote:
Hi folks. I was debugging a problem with Moose and I realized that 2 different methods can have the same CompiledMethod. This was weird for me. I don't know if this is correct or not.

For example, evaluate:

(InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)    ->  true

If you look at

CompiledMethod = aCompiledMethod 
    "Answer whether the receiver implements the same code as aCompiledMethod."

    | numLits |
    self == aCompiledMethod
        ifTrue: [ ^ true ].
    self class = aCompiledMethod class
        ifFalse: [ ^ false ].
    self size = aCompiledMethod size
        ifFalse: [ ^ false ].
    self header = aCompiledMethod header
        ifFalse: [ ^ false ].
    self initialPC to: self endPC do: [ :i |
        (self at: i) = (aCompiledMethod at: i)
            ifFalse: [ ^ false ] ].
    (self sameLiteralsAs: aCompiledMethod)
        ifFalse: [ ^ false ].
    self halt.
    ^ true


It is returning in the last ^ true.

What was weird for me is that (self sameLiteralsAs: aCompiledMethod)  returns true also. But if I print both literals:

self literals ->  {#methodReturnTop. (#InstructionClient->InstructionClient)}

aCompiledMethod literals ->  {#doDup. (#InstructionClient->InstructionClient)}

So...for me they are differnt, but sameLiteralsAs:  is returning true. Debugging that, it seems that in that method it is returning in the last ^ true.

So...any hints? is this the expected behavior ?  or it is a bug ?

Thanks

Mariano




_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Stéphane Ducasse
In reply to this post by Mariano Martinez Peck

On May 18, 2010, at 3:35 PM, Mariano Martinez Peck wrote:

> Hi folks. I was debugging a problem with Moose and I realized that 2 different methods can have the same CompiledMethod. This was weird for me. I don't know if this is correct or not.
>
> For example, evaluate:
>
> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)    ->  true
>
> If you look at
>
> CompiledMethod = aCompiledMethod  
>     "Answer whether the receiver implements the same code as aCompiledMethod."
>
>     | numLits |
>     self == aCompiledMethod
>         ifTrue: [ ^ true ].
>     self class = aCompiledMethod class
>         ifFalse: [ ^ false ].
>     self size = aCompiledMethod size
>         ifFalse: [ ^ false ].
>     self header = aCompiledMethod header
>         ifFalse: [ ^ false ].
>     self initialPC to: self endPC do: [ :i |
>         (self at: i) = (aCompiledMethod at: i)
>             ifFalse: [ ^ false ] ].
>     (self sameLiteralsAs: aCompiledMethod)
>         ifFalse: [ ^ false ].
>     self halt.
>     ^ true
>
>
> It is returning in the last ^ true.
>
> What was weird for me is that (self sameLiteralsAs: aCompiledMethod)  returns true also. But if I print both literals:
>
> self literals ->  {#methodReturnTop. (#InstructionClient->InstructionClient)}
>
> aCompiledMethod literals ->  {#doDup. (#InstructionClient->InstructionClient)}
>
> So...for me they are differnt, but sameLiteralsAs:  is returning true. Debugging that, it seems that in that method it is returning in the last ^ true.
>
> So...any hints? is this the expected behavior ?  or it is a bug ?

certainly a bug


>
> Thanks
>
> Mariano
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Lukas Renggli
>> So...any hints? is this the expected behavior ?  or it is a bug ?
>
> certainly a bug

I would not say that this is a bug, it depends of course what you
consider equal.

The current definition of #= in compiled method is has same bytecode,
same literals (except the class and selector) and same annotations.

In your case you probably should use an IdentitySet or IdentityDictionary.

Lukas

--
Lukas Renggli
www.lukas-renggli.ch

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Stéphane Ducasse
I was planning to have a look just after a couple of integrations... but you save my time :)
On May 18, 2010, at 4:00 PM, Lukas Renggli wrote:

>>> So...any hints? is this the expected behavior ?  or it is a bug ?
>>
>> certainly a bug
>
> I would not say that this is a bug, it depends of course what you
> consider equal.
>
> The current definition of #= in compiled method is has same bytecode,
> same literals (except the class and selector) and same annotations.
>
> In your case you probably should use an IdentitySet or IdentityDictionary.
>
> Lukas
>
> --
> Lukas Renggli
> www.lukas-renggli.ch
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Henrik Sperre Johansen
In reply to this post by Mariano Martinez Peck
On May 18, 2010, at 3:39 33PM, Mariano Martinez Peck wrote:

> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)

methodReturnTop startPC -> 13
methodReturnTop endPC -> 12.

I have a slight feeling that is one of the reasons :)
Seems to be related to method trailers size assumptions not holding.


Also, sameLiteralsAs: is a mess.
There are no comments really revealing the intention of the 8 ifTrue/False branches, no refactoring to use revealing method names...
Can anyone explain to me why numLits  -1 = index is checked?

At least for methodReturnTop, which has 2 literals, it certainly does not seem like numLits -1  contains properties....

Cheers,
Henry
_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Lukas Renggli
>> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)
>
> methodReturnTop startPC -> 13
> methodReturnTop endPC -> 12.
>
> I have a slight feeling that is one of the reasons :)
> Seems to be related to method trailers size assumptions not holding.

That's fine, the method has no bytecode. It is a quick-return self.

> Also, sameLiteralsAs: is a mess.
> There are no comments really revealing the intention of the 8 ifTrue/False branches, no refactoring to use revealing method names...
> Can anyone explain to me why numLits  -1 = index is checked?

Check the VM source/compiler on the different special literal slots
and how different kind of primitives are encoded.

> At least for methodReturnTop, which has 2 literals, it certainly does not seem like numLits -1  contains properties....

The two literals are the selector and the class-binding, as the method
comment says these literals are not considered for equality.

Lukas

--
Lukas Renggli
www.lukas-renggli.ch

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Henrik Sperre Johansen
In reply to this post by Henrik Sperre Johansen

On May 18, 2010, at 4:15 33PM, Henrik Johansen wrote:

> On May 18, 2010, at 3:39 33PM, Mariano Martinez Peck wrote:
>
>> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)
>
> methodReturnTop startPC -> 13
> methodReturnTop endPC -> 12.
>
> I have a slight feeling that is one of the reasons :)
> Seems to be related to method trailers size assumptions not holding.
>
>
> Also, sameLiteralsAs: is a mess.
> There are no comments really revealing the intention of the 8 ifTrue/False branches, no refactoring to use revealing method names...
> Can anyone explain to me why numLits  -1 = index is checked?
>
> At least for methodReturnTop, which has 2 literals, it certainly does not seem like numLits -1  contains properties....

Oh, ok, numLit -1 contains the selector.

So that would be the  "except selector" Lukas mentioned.
Same method in different classes do not  equal eachother though, if I've not made a mistake in:

|mrtCp|
mrtCp := (InstructionClient>>#methodReturnTop) copy.
mrtCp literalAt: 2 put: #ContextPart->ContextPart.
(InstructionClient>>#methodReturnTop) = mrtCp

At the very least, the branches of
index = 1 and: [ #(117 120) includes: self primitive ])
                                        ifTrue: [

REALLY deserve some comments...

Cheers,
Henry
 


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Henrik Sperre Johansen
In reply to this post by Lukas Renggli

On May 18, 2010, at 4:41 41PM, Lukas Renggli wrote:

>>> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)
>>
>> methodReturnTop startPC -> 13
>> methodReturnTop endPC -> 12.
>>
>> I have a slight feeling that is one of the reasons :)
>> Seems to be related to method trailers size assumptions not holding.
>
> That's fine, the method has no bytecode. It is a quick-return self.

Ah yes, inspecting it I saw bytes 13 -16 which were diferent, didn't realize those were the trailer itself :) Doh!

Cheers,
Henry
_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Stéphane Ducasse
In reply to this post by Henrik Sperre Johansen
Please send me that and I will integrate it.

Stef

On May 18, 2010, at 4:46 PM, Henrik Johansen wrote:

>
> On May 18, 2010, at 4:15 33PM, Henrik Johansen wrote:
>
>> On May 18, 2010, at 3:39 33PM, Mariano Martinez Peck wrote:
>>
>>> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)
>>
>> methodReturnTop startPC -> 13
>> methodReturnTop endPC -> 12.
>>
>> I have a slight feeling that is one of the reasons :)
>> Seems to be related to method trailers size assumptions not holding.
>>
>>
>> Also, sameLiteralsAs: is a mess.
>> There are no comments really revealing the intention of the 8 ifTrue/False branches, no refactoring to use revealing method names...
>> Can anyone explain to me why numLits  -1 = index is checked?
>>
>> At least for methodReturnTop, which has 2 literals, it certainly does not seem like numLits -1  contains properties....
>
> Oh, ok, numLit -1 contains the selector.
>
> So that would be the  "except selector" Lukas mentioned.
> Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>
> |mrtCp|
> mrtCp := (InstructionClient>>#methodReturnTop) copy.
> mrtCp literalAt: 2 put: #ContextPart->ContextPart.
> (InstructionClient>>#methodReturnTop) = mrtCp
>
> At the very least, the branches of
> index = 1 and: [ #(117 120) includes: self primitive ])
> ifTrue: [
>
> REALLY deserve some comments...
>
> Cheers,
> Henry
>
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Henrik Sperre Johansen

On May 18, 2010, at 4:58 18PM, Stéphane Ducasse wrote:

> Please send me that and I will integrate it.
>
> Stef

If I had any idea what a helpful comments would be, I would :)
Clearly, I just don't understand it at all atm though, and I really don't have time to read the Compiler and/or VM sources to figure it out.

Cheers,
Henry

>
> On May 18, 2010, at 4:46 PM, Henrik Johansen wrote:
>
>>
>> On May 18, 2010, at 4:15 33PM, Henrik Johansen wrote:
>>
>>> On May 18, 2010, at 3:39 33PM, Mariano Martinez Peck wrote:
>>>
>>>> (InstructionClient>>#methodReturnTop) = (InstructionClient>>#doDup)
>>>
>>> methodReturnTop startPC -> 13
>>> methodReturnTop endPC -> 12.
>>>
>>> I have a slight feeling that is one of the reasons :)
>>> Seems to be related to method trailers size assumptions not holding.
>>>
>>>
>>> Also, sameLiteralsAs: is a mess.
>>> There are no comments really revealing the intention of the 8 ifTrue/False branches, no refactoring to use revealing method names...
>>> Can anyone explain to me why numLits  -1 = index is checked?
>>>
>>> At least for methodReturnTop, which has 2 literals, it certainly does not seem like numLits -1  contains properties....
>>
>> Oh, ok, numLit -1 contains the selector.
>>
>> So that would be the  "except selector" Lukas mentioned.
>> Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>>
>> |mrtCp|
>> mrtCp := (InstructionClient>>#methodReturnTop) copy.
>> mrtCp literalAt: 2 put: #ContextPart->ContextPart.
>> (InstructionClient>>#methodReturnTop) = mrtCp
>>
>> At the very least, the branches of
>> index = 1 and: [ #(117 120) includes: self primitive ])
>> ifTrue: [
>>
>> REALLY deserve some comments...
>>
>> Cheers,
>> Henry
>>
>>
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Henrik Sperre Johansen
In reply to this post by Lukas Renggli

On May 18, 2010, at 4:41 41PM, Lukas Renggli wrote:

>
>> Also, sameLiteralsAs: is a mess.
>> There are no comments really revealing the intention of the 8 ifTrue/False branches, no refactoring to use revealing method names...
>> Can anyone explain to me why numLits  -1 = index is checked?
>
> Check the VM source/compiler on the different special literal slots
> and how different kind of primitives are encoded.


Wouldn't it be nice to document this in the method as well, so

>
>> At least for methodReturnTop, which has 2 literals, it certainly does not seem like numLits -1  contains properties....
>
> The two literals are the selector and the class-binding, as the method
> comment says these literals are not considered for equality.
Hmmm, which method comment?
In my image, at the top of sameLiteralsAs: it says:
"Compare my literals to those of method. This is needed to compare compiled methods."

And in =
"Answer whether the receiver implements the same code as aCompiledMethod."

Nothing about which literals are or aren't considered for equality :(
_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Lukas Renggli
In reply to this post by Henrik Sperre Johansen
> Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>
> |mrtCp|
> mrtCp := (InstructionClient>>#methodReturnTop) copy.
> mrtCp literalAt: 2 put: #ContextPart->ContextPart.
> (InstructionClient>>#methodReturnTop) = mrtCp

For methods that send super the behavior changes if you change the
class binding. That's probably why it is not ignored for #=.

In fact I would suggest to #= from compiled method altogether, in most
cases it doesn't do what one would expect in a given context anyway.
There are too many and possibility completely different
interpretations of #= for CompiledMethod. #== is the only decent
implementation for this class.

Lukas

>
> At the very least, the branches of
> index = 1 and: [ #(117 120) includes: self primitive ])
>                                        ifTrue: [
>
> REALLY deserve some comments...
>
> Cheers,
> Henry
>
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>



--
Lukas Renggli
www.lukas-renggli.ch

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Eliot Miranda-2
Hi Lukas,

On Tue, May 18, 2010 at 8:17 AM, Lukas Renggli <[hidden email]> wrote:
> Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>
> |mrtCp|
> mrtCp := (InstructionClient>>#methodReturnTop) copy.
> mrtCp literalAt: 2 put: #ContextPart->ContextPart.
> (InstructionClient>>#methodReturnTop) = mrtCp

For methods that send super the behavior changes if you change the
class binding. That's probably why it is not ignored for #=.

In fact I would suggest to #= from compiled method altogether, in most
cases it doesn't do what one would expect in a given context anyway.
There are too many and possibility completely different
interpretations of #= for CompiledMethod. #== is the only decent
implementation for this class.

I sympathise but I think there is a reasonable default interpretation of #= for CompiledMethod that is what most people want.  The intent is to answer whether two methods have the same execution semantics and same method tags & properties, e.g. if one were to compile the same source code in two different classes that had the same inst var offsets for the inst vars in the methods, then one would want those methods to be #=.  This allows tests such as
- checking whether a subclass has a method that is #= to a superclass, and is hence redundant.
- checking whether a set of sourceless methods are equivalent so that they may be shared under different selectors (e.g. think auto-generated accessor methods which can be cached and shared)
So for this informal definition the selector and the class are irrelevant, but bytecodes and literals (apart from the selector and method class literals) are relevant.  Its almost a short-cut comparison of error-free decompilation, although there are differences in the bytecode that wouldn't show in decompilation (e.g. using long branches for short branches).

The current definition serves for compiler hackers as it tells you accurately whether a compiler change has an effect on the bytecode, can be used to test whether compilation followed by decompilation followed by recompilation has an effect, etc.  While it may not be a universal code comparison method it has met my needs throughout the closure compiler so at least I'm pretty happy with it.

(pleading for CompiledMethod>>#= to stay the same as the current Squeak 4.1 definition, which ever since Nichoas Celier's float compilation changes, is pretty darned good).

best
Eliot





Lukas

>
> At the very least, the branches of
> index = 1 and: [ #(117 120) includes: self primitive ])
>                                        ifTrue: [
>
> REALLY deserve some comments...
>
> Cheers,
> Henry
>
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>



--
Lukas Renggli
www.lukas-renggli.ch

_______________________________________________


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Igor Stasenko
2010/5/19 Eliot Miranda <[hidden email]>:

> Hi Lukas,
>
> On Tue, May 18, 2010 at 8:17 AM, Lukas Renggli <[hidden email]> wrote:
>>
>> > Same method in different classes do not  equal eachother though, if I've
>> > not made a mistake in:
>> >
>> > |mrtCp|
>> > mrtCp := (InstructionClient>>#methodReturnTop) copy.
>> > mrtCp literalAt: 2 put: #ContextPart->ContextPart.
>> > (InstructionClient>>#methodReturnTop) = mrtCp
>>
>> For methods that send super the behavior changes if you change the
>> class binding. That's probably why it is not ignored for #=.
>>
>> In fact I would suggest to #= from compiled method altogether, in most
>> cases it doesn't do what one would expect in a given context anyway.
>> There are too many and possibility completely different
>> interpretations of #= for CompiledMethod. #== is the only decent
>> implementation for this class.
>
> I sympathise but I think there is a reasonable default interpretation of #=
> for CompiledMethod that is what most people want.  The intent is to answer
> whether two methods have the same execution semantics and same method tags &
> properties, e.g. if one were to compile the same source code in two
> different classes that had the same inst var offsets for the inst vars in
> the methods, then one would want those methods to be #=.  This allows tests
> such as
> - checking whether a subclass has a method that is #= to a superclass, and
> is hence redundant.
> - checking whether a set of sourceless methods are equivalent so that they
> may be shared under different selectors (e.g. think auto-generated accessor
> methods which can be cached and shared)
> So for this informal definition the selector and the class are irrelevant,
> but bytecodes and literals (apart from the selector and method class
> literals) are relevant.  Its almost a short-cut comparison of error-free
> decompilation, although there are differences in the bytecode that wouldn't
> show in decompilation (e.g. using long branches for short branches).
> The current definition serves for compiler hackers as it tells you
> accurately whether a compiler change has an effect on the bytecode, can be
> used to test whether compilation followed by decompilation followed by
> recompilation has an effect, etc.  While it may not be a universal code
> comparison method it has met my needs throughout the closure compiler so at
> least I'm pretty happy with it.
> (pleading for CompiledMethod>>#= to stay the same as the current Squeak 4.1
> definition, which ever since Nichoas Celier's float compilation changes, is
> pretty darned good).
> best
> Eliot
>

Well, we could have a cake and eat it too.
- rename #= to #isEqualToMethod:

Then, the parts which intentionally require a comparisons, like you
described above, will use this message.
While for the rest of smalltalk code , sending #= will end up being #==.

>
>
>>
>> Lukas
>>
>> >
>> > At the very least, the branches of
>> > index = 1 and: [ #(117 120) includes: self primitive ])
>> >                                        ifTrue: [
>> >
>> > REALLY deserve some comments...
>> >
>> > Cheers,
>> > Henry
>> >
>> >
>> >
>> > _______________________________________________
>> > Pharo-project mailing list
>> > [hidden email]
>> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>> >
>>
>>
>>
>> --
>> Lukas Renggli
>> www.lukas-renggli.ch
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>



--
Best regards,
Igor Stasenko AKA sig.

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Stéphane Ducasse
In reply to this post by Eliot Miranda-2
Elliot I think that we already took into changes made by nicolas.

Stef

On May 19, 2010, at 2:35 AM, Eliot Miranda wrote:

> Hi Lukas,
>
> On Tue, May 18, 2010 at 8:17 AM, Lukas Renggli <[hidden email]> wrote:
> > Same method in different classes do not  equal eachother though, if I've not made a mistake in:
> >
> > |mrtCp|
> > mrtCp := (InstructionClient>>#methodReturnTop) copy.
> > mrtCp literalAt: 2 put: #ContextPart->ContextPart.
> > (InstructionClient>>#methodReturnTop) = mrtCp
>
> For methods that send super the behavior changes if you change the
> class binding. That's probably why it is not ignored for #=.
>
> In fact I would suggest to #= from compiled method altogether, in most
> cases it doesn't do what one would expect in a given context anyway.
> There are too many and possibility completely different
> interpretations of #= for CompiledMethod. #== is the only decent
> implementation for this class.
>
> I sympathise but I think there is a reasonable default interpretation of #= for CompiledMethod that is what most people want.  The intent is to answer whether two methods have the same execution semantics and same method tags & properties, e.g. if one were to compile the same source code in two different classes that had the same inst var offsets for the inst vars in the methods, then one would want those methods to be #=.  This allows tests such as
> - checking whether a subclass has a method that is #= to a superclass, and is hence redundant.
> - checking whether a set of sourceless methods are equivalent so that they may be shared under different selectors (e.g. think auto-generated accessor methods which can be cached and shared)
> So for this informal definition the selector and the class are irrelevant, but bytecodes and literals (apart from the selector and method class literals) are relevant.  Its almost a short-cut comparison of error-free decompilation, although there are differences in the bytecode that wouldn't show in decompilation (e.g. using long branches for short branches).
>
> The current definition serves for compiler hackers as it tells you accurately whether a compiler change has an effect on the bytecode, can be used to test whether compilation followed by decompilation followed by recompilation has an effect, etc.  While it may not be a universal code comparison method it has met my needs throughout the closure compiler so at least I'm pretty happy with it.
>
> (pleading for CompiledMethod>>#= to stay the same as the current Squeak 4.1 definition, which ever since Nichoas Celier's float compilation changes, is pretty darned good).
>
> best
> Eliot
>
>
>
>
>
> Lukas
>
> >
> > At the very least, the branches of
> > index = 1 and: [ #(117 120) includes: self primitive ])
> >                                        ifTrue: [
> >
> > REALLY deserve some comments...
> >
> > Cheers,
> > Henry
> >
> >
> >
> > _______________________________________________
> > Pharo-project mailing list
> > [hidden email]
> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
> >
>
>
>
> --
> Lukas Renggli
> www.lukas-renggli.ch
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Nicolas Cellier
Hi Eliot,
What about super sends ?

Object>>beNasty
    ^self

Collection>>beNasty
     self addLast; 1.
     super beNasty.

OrderedCollection>>beNasty
     self addLast; 1.
     super beNasty.

Do you think you can remove OrderedCollection>>beNasty ?

Nicolas

2010/5/19 Stéphane Ducasse <[hidden email]>:

> Elliot I think that we already took into changes made by nicolas.
>
> Stef
>
> On May 19, 2010, at 2:35 AM, Eliot Miranda wrote:
>
>> Hi Lukas,
>>
>> On Tue, May 18, 2010 at 8:17 AM, Lukas Renggli <[hidden email]> wrote:
>> > Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>> >
>> > |mrtCp|
>> > mrtCp := (InstructionClient>>#methodReturnTop) copy.
>> > mrtCp literalAt: 2 put: #ContextPart->ContextPart.
>> > (InstructionClient>>#methodReturnTop) = mrtCp
>>
>> For methods that send super the behavior changes if you change the
>> class binding. That's probably why it is not ignored for #=.
>>
>> In fact I would suggest to #= from compiled method altogether, in most
>> cases it doesn't do what one would expect in a given context anyway.
>> There are too many and possibility completely different
>> interpretations of #= for CompiledMethod. #== is the only decent
>> implementation for this class.
>>
>> I sympathise but I think there is a reasonable default interpretation of #= for CompiledMethod that is what most people want.  The intent is to answer whether two methods have the same execution semantics and same method tags & properties, e.g. if one were to compile the same source code in two different classes that had the same inst var offsets for the inst vars in the methods, then one would want those methods to be #=.  This allows tests such as
>> - checking whether a subclass has a method that is #= to a superclass, and is hence redundant.
>> - checking whether a set of sourceless methods are equivalent so that they may be shared under different selectors (e.g. think auto-generated accessor methods which can be cached and shared)
>> So for this informal definition the selector and the class are irrelevant, but bytecodes and literals (apart from the selector and method class literals) are relevant.  Its almost a short-cut comparison of error-free decompilation, although there are differences in the bytecode that wouldn't show in decompilation (e.g. using long branches for short branches).
>>
>> The current definition serves for compiler hackers as it tells you accurately whether a compiler change has an effect on the bytecode, can be used to test whether compilation followed by decompilation followed by recompilation has an effect, etc.  While it may not be a universal code comparison method it has met my needs throughout the closure compiler so at least I'm pretty happy with it.
>>
>> (pleading for CompiledMethod>>#= to stay the same as the current Squeak 4.1 definition, which ever since Nichoas Celier's float compilation changes, is pretty darned good).
>>
>> best
>> Eliot
>>
>>
>>
>>
>>
>> Lukas
>>
>> >
>> > At the very least, the branches of
>> > index = 1 and: [ #(117 120) includes: self primitive ])
>> >                                        ifTrue: [
>> >
>> > REALLY deserve some comments...
>> >
>> > Cheers,
>> > Henry
>> >
>> >
>> >
>> > _______________________________________________
>> > Pharo-project mailing list
>> > [hidden email]
>> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>> >
>>
>>
>>
>> --
>> Lukas Renggli
>> www.lukas-renggli.ch
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Eliot Miranda-2


On Wed, May 19, 2010 at 4:58 AM, Nicolas Cellier <[hidden email]> wrote:
Hi Eliot,
What about super sends ?

Object>>beNasty
   ^self

Collection>>beNasty
    self addLast; 1.
    super beNasty.

OrderedCollection>>beNasty
    self addLast; 1.
    super beNasty.

Good point.  I still find the existing #= definition very useful for compiler verification. 
 

Do you think you can remove OrderedCollection>>beNasty ?

Nicolas

2010/5/19 Stéphane Ducasse <[hidden email]>:
> Elliot I think that we already took into changes made by nicolas.
>
> Stef
>
> On May 19, 2010, at 2:35 AM, Eliot Miranda wrote:
>
>> Hi Lukas,
>>
>> On Tue, May 18, 2010 at 8:17 AM, Lukas Renggli <[hidden email]> wrote:
>> > Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>> >
>> > |mrtCp|
>> > mrtCp := (InstructionClient>>#methodReturnTop) copy.
>> > mrtCp literalAt: 2 put: #ContextPart->ContextPart.
>> > (InstructionClient>>#methodReturnTop) = mrtCp
>>
>> For methods that send super the behavior changes if you change the
>> class binding. That's probably why it is not ignored for #=.
>>
>> In fact I would suggest to #= from compiled method altogether, in most
>> cases it doesn't do what one would expect in a given context anyway.
>> There are too many and possibility completely different
>> interpretations of #= for CompiledMethod. #== is the only decent
>> implementation for this class.
>>
>> I sympathise but I think there is a reasonable default interpretation of #= for CompiledMethod that is what most people want.  The intent is to answer whether two methods have the same execution semantics and same method tags & properties, e.g. if one were to compile the same source code in two different classes that had the same inst var offsets for the inst vars in the methods, then one would want those methods to be #=.  This allows tests such as
>> - checking whether a subclass has a method that is #= to a superclass, and is hence redundant.
>> - checking whether a set of sourceless methods are equivalent so that they may be shared under different selectors (e.g. think auto-generated accessor methods which can be cached and shared)
>> So for this informal definition the selector and the class are irrelevant, but bytecodes and literals (apart from the selector and method class literals) are relevant.  Its almost a short-cut comparison of error-free decompilation, although there are differences in the bytecode that wouldn't show in decompilation (e.g. using long branches for short branches).
>>
>> The current definition serves for compiler hackers as it tells you accurately whether a compiler change has an effect on the bytecode, can be used to test whether compilation followed by decompilation followed by recompilation has an effect, etc.  While it may not be a universal code comparison method it has met my needs throughout the closure compiler so at least I'm pretty happy with it.
>>
>> (pleading for CompiledMethod>>#= to stay the same as the current Squeak 4.1 definition, which ever since Nichoas Celier's float compilation changes, is pretty darned good).
>>
>> best
>> Eliot
>>
>>
>>
>>
>>
>> Lukas
>>
>> >
>> > At the very least, the branches of
>> > index = 1 and: [ #(117 120) includes: self primitive ])
>> >                                        ifTrue: [
>> >
>> > REALLY deserve some comments...
>> >
>> > Cheers,
>> > Henry
>> >
>> >
>> >
>> > _______________________________________________
>> > Pharo-project mailing list
>> > [hidden email]
>> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>> >
>>
>>
>>
>> --
>> Lukas Renggli
>> www.lukas-renggli.ch
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: problem with CompiledMethod equality

Mariano Martinez Peck
Wow.....the conversation went far away from my understanding and knowledge. I will try to read it slowly and carefully, several times and try to understand what you said.

For the moment (just my needs) the solution from Lukas worked: use IdentitityDictionary instead of Dictionary.

Now I let you to you to decide if it is a bug or not, if it deserves comment, etc.

Thank you very much.

Mariano

2010/5/19 Eliot Miranda <[hidden email]>


On Wed, May 19, 2010 at 4:58 AM, Nicolas Cellier <[hidden email]> wrote:
Hi Eliot,
What about super sends ?

Object>>beNasty
   ^self

Collection>>beNasty
    self addLast; 1.
    super beNasty.

OrderedCollection>>beNasty
    self addLast; 1.
    super beNasty.

Good point.  I still find the existing #= definition very useful for compiler verification. 
 

Do you think you can remove OrderedCollection>>beNasty ?

Nicolas

2010/5/19 Stéphane Ducasse <[hidden email]>:
> Elliot I think that we already took into changes made by nicolas.
>
> Stef
>
> On May 19, 2010, at 2:35 AM, Eliot Miranda wrote:
>
>> Hi Lukas,
>>
>> On Tue, May 18, 2010 at 8:17 AM, Lukas Renggli <[hidden email]> wrote:
>> > Same method in different classes do not  equal eachother though, if I've not made a mistake in:
>> >
>> > |mrtCp|
>> > mrtCp := (InstructionClient>>#methodReturnTop) copy.
>> > mrtCp literalAt: 2 put: #ContextPart->ContextPart.
>> > (InstructionClient>>#methodReturnTop) = mrtCp
>>
>> For methods that send super the behavior changes if you change the
>> class binding. That's probably why it is not ignored for #=.
>>
>> In fact I would suggest to #= from compiled method altogether, in most
>> cases it doesn't do what one would expect in a given context anyway.
>> There are too many and possibility completely different
>> interpretations of #= for CompiledMethod. #== is the only decent
>> implementation for this class.
>>
>> I sympathise but I think there is a reasonable default interpretation of #= for CompiledMethod that is what most people want.  The intent is to answer whether two methods have the same execution semantics and same method tags & properties, e.g. if one were to compile the same source code in two different classes that had the same inst var offsets for the inst vars in the methods, then one would want those methods to be #=.  This allows tests such as
>> - checking whether a subclass has a method that is #= to a superclass, and is hence redundant.
>> - checking whether a set of sourceless methods are equivalent so that they may be shared under different selectors (e.g. think auto-generated accessor methods which can be cached and shared)
>> So for this informal definition the selector and the class are irrelevant, but bytecodes and literals (apart from the selector and method class literals) are relevant.  Its almost a short-cut comparison of error-free decompilation, although there are differences in the bytecode that wouldn't show in decompilation (e.g. using long branches for short branches).
>>
>> The current definition serves for compiler hackers as it tells you accurately whether a compiler change has an effect on the bytecode, can be used to test whether compilation followed by decompilation followed by recompilation has an effect, etc.  While it may not be a universal code comparison method it has met my needs throughout the closure compiler so at least I'm pretty happy with it.
>>
>> (pleading for CompiledMethod>>#= to stay the same as the current Squeak 4.1 definition, which ever since Nichoas Celier's float compilation changes, is pretty darned good).
>>
>> best
>> Eliot
>>
>>
>>
>>
>>
>> Lukas
>>
>> >
>> > At the very least, the branches of
>> > index = 1 and: [ #(117 120) includes: self primitive ])
>> >                                        ifTrue: [
>> >
>> > REALLY deserve some comments...
>> >
>> > Cheers,
>> > Henry
>> >
>> >
>> >
>> > _______________________________________________
>> > Pharo-project mailing list
>> > [hidden email]
>> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>> >
>>
>>
>>
>> --
>> Lukas Renggli
>> www.lukas-renggli.ch
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project