[Pharo-project] [squeak-dev] Re: Issue 4538 and CompiledMethod equality

Eliot Miranda eliot.miranda at gmail.com
Fri Sep 16 19:16:37 UTC 2011


On Fri, Sep 16, 2011 at 12:08 PM, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> wrote:

> 2011/9/16 Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com>:
> > 2011/9/16 Mariano Martinez Peck <marianopeck at gmail.com>:
> >> I don't really know. I have implemented what Eliot say in the first
> option
> >> and it is working for me.
> >> Do you (Henry/Lukas/Nicolas/Eliot) agree to have this first solution and
> >> then improve it if necessary ?
> >>
> >> thanks
> >>
> >
> > I agree on Mariano/Eliot solution. It is a good pragmatic short term
> workaround.
> > In the long term, I wish I can say goodbye to my new super power, it's
> > a too dangerous power.
> > So I wish the VM would change (along with ClassBuilder and Tools).
>

Yes, I agree.  It just takes time to get there.


> >
> > Nicolas
> >
>
> Or maybe after reading:
>
>    literal1 := self literalAt: numLits.
>    literal2 := method literalAt: numLits.
>     ^ (literal1 == literal2) or: [literal1 key isNil == literal2 key
> isNil and: [literal1 value == literal2 value]].
>
> I we are sure that the last literal is always an Association
>

If it's not then one is playing fast and loose with the system.  But if the
method doesn't contain a super send then as far as the VM is concerned it
doesn't need an association, and that might be the case with, for example,
shared inst var accessors in Newspeak.  So instead of assuming its an
association write it something like

    ^literal1 class == literal2 class
     and: [literal1 isVariableBinding
                ifTrue: [literal1 key = literal2 key and: [literal1 value =
literal2 value]]
                ifFalse: [literal1 = literal2]]


> Nicolas
>
> >> On Fri, Sep 16, 2011 at 8:12 PM, Stéphane Ducasse
> >> <stephane.ducasse at inria.fr> wrote:
> >>>
> >>> Mariano
> >>>
> >>> So should we intgerate a fix?
> >>>
> >>> Stef
> >>>
> >>> On Sep 15, 2011, at 11:27 PM, Mariano Martinez Peck wrote:
> >>>
> >>> >
> >>> >
> >>> >
> >>> > BUT, it doesn't mean that Association is always used for globals.
> >>> > CompiledMethod equality is failing because of the last literal, the
> one that
> >>> > maps class name (symbol) and point to the real class. So...when I
> >>> > materialize, both CMs have non-identical associations for the last
> literal,
> >>> > but equal.
> >>> >
> >>> > As Henrik says the last literals are ideally #== to each other.
> >>> >  However, no Squeak dialect makes any attempt to keep the class0side
> >>> > associations equal. Look at a class-side method and you'll see it's
> last
> >>> > literal is nil->SomeClass class.  Now since this association doesn't
> exist
> >>> > in Smalltalk (unlike last literals on the instance side) the compiler
> merely
> >>> > creates distinct ones for each class-side method.
> >>> >
> >>> >
> >>> > Thanks Eliot for that point. In fact, I have just checked and you are
> >>> > right. The tests that are failing for me is those where class side
> methods
> >>> > are involded. In this case, the last literal of the original CM and
> the
> >>> > materialized, gives false in #literalEqual:   hence,  originalCM =
> >>> > materializedCM is false :(
> >>> >
> >>> >
> >>> >
> >>> > Personally I don't think one can defend the position where method
> >>> > equality is different for instance-side or class-side methods so
> there must
> >>> > be some solutions:
> >>> >
> >>> > 1. special case comparison of the last literal (the methodClass
> >>> > literal), comparing keys and insisting that the keys be #== and the
> values
> >>> > be #== (can't just define it as keys #== since all similar class-side
> >>> > methods will be equal irrespective of their actual class).
> >>> >
> >>> >
> >>> > This one seems the easier and fixes my problem :)
> >>> >
> >>> > sameLiteralsAs: method
> >>> >     "Compare my literals to those of method. This is needed to
> compare
> >>> > compiled methods."
> >>> >
> >>> >     | numLits literal1 literal2 |
> >>> >     (numLits := self numLiterals) ~= method numLiterals
> >>> >         ifTrue: [ ^ false ].
> >>> >     "The last literal requires special checking instead of using
> >>> > #literalEqual:"
> >>> >     1 to: numLits - 1 do: [ :index |
> >>> >         literal1 := self literalAt: index.
> >>> >         literal2 := method literalAt: index.
> >>> >         (literal1 == literal2 or: [ literal1 literalEqual: literal2
> ])
> >>> >             ifFalse: [
> >>> >                 (index = 1 and: [ #(117 120) includes: self primitive
> ])
> >>> >                     ifTrue: [
> >>> >                         literal1 isArray
> >>> >                             ifTrue: [
> >>> >                                 (literal2 isArray and: [ literal1
> >>> > allButLast = literal2 allButLast ])
> >>> >                                     ifFalse: [ self halt. ^ false ] ]
> >>> >                             ifFalse: [
> >>> >                                 "ExternalLibraryFunction"
> >>> >                                 (literal1 analogousCodeTo: literal2)
> >>> >                                     ifFalse: [ self halt. ^ false ] ]
> ]
> >>> >                     ifFalse: [
> >>> >                         index = (numLits - 1)
> >>> >                             ifTrue: [
> >>> >                                 "properties"
> >>> >                                 (self properties analogousCodeTo:
> method
> >>> > properties)
> >>> >                                     ifFalse: [ self halt. ^ false ] ]
> >>> >                             ifFalse: [ self halt. ^ false ] ] ] ].
> >>> >     literal1 := self literalAt: numLits.
> >>> >     literal2 := method literalAt: numLits.
> >>> >     ^ ((literal1 key == literal2 key) and: [literal1 value ==
> literal2
> >>> > value]).
> >>> >
> >>> >
> >>> >
> >>> > 2. special case comparison of the last literal (the methodClass
> >>> > literal), insisting only that the class of the literal be the same if
> it
> >>> > isVariableBinding.
> >>> >
> >>> > 3. make the compile unique class-side methodClass literals.  i.e. if
> a
> >>> > class already has a class-side method then the compiler or method
> dictionary
> >>> > insertion code must find that existing association and reuse it
> >>> >
> >>> > Other ideas?
> >>> >
> >>> > >From my point of view, that literal, the last one does not need to
> be
> >>> > identical to assume 2 CMs are equal. They just need to be equal.
> >>> >
> >>> >
> >>> > --
> >>> > Mariano
> >>> > http://marianopeck.wordpress.com
> >>> >
> >>> >
> >>> >
> >>> >
> >>> > --
> >>> > best,
> >>> > Eliot
> >>> >
> >>> >
> >>> >
> >>> >
> >>> >
> >>> >
> >>> >
> >>> > --
> >>> > Mariano
> >>> > http://marianopeck.wordpress.com
> >>> >
> >>>
> >>>
> >>
> >>
> >>
> >> --
> >> Mariano
> >> http://marianopeck.wordpress.com
> >>
> >>
> >
>
>


-- 
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20110916/72c57410/attachment.htm


More information about the Squeak-dev mailing list