On Sat, Sep 17, 2011 at 9:00 PM, Eliot Miranda <[email protected]>wrote:

>
>
> On Sat, Sep 17, 2011 at 8:39 AM, Mariano Martinez Peck <
> [email protected]> wrote:
>
>> I wanted to write a test (before Stef asked) but I don't know how to
>> clearly copy a CompiledMethod. First I tried
>>
>> CompiledMethodTest >> testEqualityClassSideMethod
>>     | method1 method2 |
>>     method1 := self class class >> #returnPlusOne:.
>>     method2 := method1 veryDeepCopy.
>>     self deny: (method1 literalAt: method1 numLiterals) ==  (method2
>> literalAt: method2 numLiterals).
>>     self assert: method1 = method2.
>>
>> And it doesn't work, the last literal of both CM point are #==.
>>
>> Then I tried:
>>
>> testEqualityClassSideMethod
>>     | method1 method2 originalAssociation |
>>     method1 := self class class >> #returnPlusOne:.
>>     method2 := method1 veryDeepCopy.
>>     originalAssociation := method2 literalAt: method2 numLiterals.
>>     method2 literalAt: method2 numLiterals put: (Association key:
>> originalAssociation key value: originalAssociation value).
>>     method1 literalAt: method1 numLiterals put: (Association key:
>> originalAssociation key value: originalAssociation value).
>>     self deny: (method1 literalAt: method1 numLiterals) ==  (method2
>> literalAt: method2 numLiterals).
>>     self assert: method1 = method2.
>>
>> Again, same problem.
>>
>> So...I don't know how can I copy a CM completly, that means, even use
>> different objects for the last literals. Any ideas?
>>
>
> Compile them from source using the same and different source. Generate
> source with subtle differences etc.  e.g. use
> Behavior>compile:classified:notifying:trailer:ifFail: which answers a
> compiled method.
>


Thanks Eliot for the point :)
Two new test: #testEqualityInstanceSideMethod and
#testEqualityClassSideMethod.
testEqualityClassSideMethod should be failing before
http://code.google.com/p/pharo/issues/detail?id=4814
and green after it.


>
>
>
>> Thanks!
>>
>>
>> On Sat, Sep 17, 2011 at 11:30 AM, Mariano Martinez Peck <
>> [email protected]> wrote:
>>
>>>
>>>  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]]
>>>>
>>>>
>>>>>
>>> Thanks. Issue and slice in
>>> http://code.google.com/p/pharo/issues/detail?id=4814
>>>
>>>
>>>
>>>
>>>>  Nicolas
>>>>>
>>>>> >> On Fri, Sep 16, 2011 at 8:12 PM, Stéphane Ducasse
>>>>> >> <[email protected]> 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
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Mariano
>>> http://marianopeck.wordpress.com
>>>
>>>
>>
>>
>> --
>> Mariano
>> http://marianopeck.wordpress.com
>>
>>
>
>
> --
> best,
> Eliot
>
>


-- 
Mariano
http://marianopeck.wordpress.com

Reply via email to