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

Reply via email to