<br><br><div class="gmail_quote">On Thu, Sep 15, 2011 at 1:00 PM, Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
2011/9/15 Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>>:<br>
<div><div></div><div class="h5">><br>
><br>
> On Thu, Sep 15, 2011 at 9:45 AM, Mariano Martinez Peck<br>
> <<a href="mailto:marianopeck@gmail.com">marianopeck@gmail.com</a>> wrote:<br>
>><br>
>> Ok, I understand. But<br>
>><br>
>> On Thu, Sep 15, 2011 at 6:05 PM, Henrik Sperre Johansen<br>
>> <<a href="mailto:henrik.s.johansen@veloxit.no">henrik.s.johansen@veloxit.no</a>> wrote:<br>
>>><br>
>>> On 15.09.2011 17:27, Mariano Martinez Peck wrote:<br>
>>><br>
>>> Hi guys. I am having a problem with the integration of issue 4538:<br>
>>> <a href="http://code.google.com/p/pharo/issues/detail?id=4538" target="_blank">http://code.google.com/p/pharo/issues/detail?id=4538</a><br>
>>><br>
>>> I am serializing CompiledMethods with Fuel and then I materialize them.<br>
>>> To test they are correct, I use #=<br>
>>> So far it was working correctly, but now for the materialized method it<br>
>>> says they are not equal. The problem is that #= is failing in<br>
>>><br>
>>> (self sameLiteralsAs: aCompiledMethod)<br>
>>><br>
>>> And inside that method, it is failing because (literal1 == literal2<br>
>>> or: [ literal1 literalEqual: literal2 ])<br>
>>> answers false.<br>
>>><br>
>>> So... why literal1 literalEqual: literal2 answers false? from what I can<br>
>>> say, having that selector: "literalEqual", then both MUST be equal, because<br>
>>> they are.<br>
>>> The problem is that it was added:<br>
>>><br>
>>> Association >> literalEqual: otherLiteral<br>
>>> "Answer true if the receiver and otherLiteral represent the same<br>
>>> literal.<br>
>>> Variable bindings are literally equals only if identical.<br>
>>> This is how variable sharing works, by preserving identity and<br>
>>> changing only the value."<br>
>>> ^self == otherLiteral<br>
>>><br>
>>><br>
>>> So....I am not sure I agree with this change.<br>
>>><br>
>>> Any idea how can we deal with this problem?<br>
>>><br>
>>> Cheers<br>
>>><br>
>>> --<br>
>>> Mariano<br>
>>> <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
>>><br>
>>> The change is correct, here's an example:<br>
>>><br>
>>> Create a global:<br>
>>> Global := 1<br>
>>><br>
>>> Create a method:<br>
>>> foo<br>
>>> ^Global<br>
>>><br>
>>> Serialize method, deserialize<br>
>>><br>
>>> Change value of global:<br>
>>> Global := 5.<br>
>>><br>
>>> foo should return 5, not 1.<br>
>>> Unless it's actually the same association as in the SystemDictionary,<br>
>>> this will not be true.<br>
>>><br>
>><br>
>> I understand that. In fact, in Fuel we use exactly the same association of<br>
>> SystemDictionary for globals. Look this test example:<br>
>><br>
>> testGlobalVariableMethod<br>
>><br>
>> | materializedCompiledMethod |<br>
>> Smalltalk globals at: #TestGlobalVariableMethod2 put: false.<br>
>> (self class compileSilently: 'globalVariableForTestingMethod<br>
>> Transcript name.<br>
>> ^ GlobalVariableForTesting.').<br>
>><br>
>> materializedCompiledMethod := self materializedCompiledMethod: (self<br>
>> class >> #globalVariableForTestingMethod).<br>
>> Smalltalk globals at: #GlobalVariableForTesting put: true.<br>
>> self assert: (materializedCompiledMethod valueWithReceiver: self<br>
>> arguments: #()).<br>
>><br>
>><br>
>><br>
>> BUT, it doesn't mean that Association is always used for globals.<br>
>> CompiledMethod equality is failing because of the last literal, the one that<br>
>> maps class name (symbol) and point to the real class. So...when I<br>
>> materialize, both CMs have non-identical associations for the last literal,<br>
>> but equal.<br>
><br>
> As Henrik says the last literals are ideally #== to each other. However, no<br>
> Squeak dialect makes any attempt to keep the class0side associations equal.<br>
> Look at a class-side method and you'll see it's last literal is<br>
> nil->SomeClass class. Now since this association doesn't exist in Smalltalk<br>
> (unlike last literals on the instance side) the compiler merely creates<br>
> distinct ones for each class-side method.<br>
> Personally I don't think one can defend the position where method equality<br>
> is different for instance-side or class-side methods so there must be some<br>
> solutions:<br>
<br>
</div></div>Hmm, good catch.<br>
A metaclass is never accessed by dictionary lookup, but only by<br>
sending #class to a class, so there is no point in maintaining a<br>
unique Association.<br>
(otherwise, we could maintain such Association in inst. var. thisClass).<br>
Having a nil key is a clear indication that lookup is pointless.<br>
<br>
The question is why having an association at all in the CompiledMethod ?<br>
For handling super sends ?<br></blockquote><div><br></div><div>Yes, but two reasons. One is super sends and the other is being able to answer the methodClass (e.g. for CompiledMethod>>printOn: and for the debugger). One doesn't need to use an association, but one can't change that without changing al the VMs /and/ changing the ClassBuilder so that when it becomes a class on class redefinition the methodsa are updated. Indeed VisualWorks does exactly this.</div>
<div><br></div><div>In any case, the super send implementation in the VM means we can't change this overnight :)</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I think a simple reference to the class would be enough.<br>
IMHO, the purpose was to simplify implementation.<br>
<br>
And I don't think the example of Henrik is worth :<br>
Lets just change it a bit:<br>
<br>
Object subclass: #SuperFoo.!<br>
Object subclass: #Bar.!<br>
SuperFoo subclass: #Foo.!<br>
<br>
SuperFoo compile: 'bar ^1'.<br>
Foo compile: 'bar<br>
^super bar *2'.<br>
foo := Foo new.<br>
Smalltalk at: #Foo put: Bar.<br>
^foo bar<br>
<br>
Could you predict the result (will it try to invoke super Bar bar) ?<br>
Yes, since the last association is shared, we just broke (foo<br>
class>>bar) for no reason...<br></blockquote><div><br></div><div>Right. But Rube Goldberg machines work like Rube Goldberg machines. Tis the nature of the beast. Doctors say "don't do that", and in Smalltalk we should say "what did you expect"? :) Being able to change the system is worth the cost of it behaving contrary to common-sense. Just like the physical world :)</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
Nicolas<br>
</font><div><div></div><div class="h5"><br>
> 1. special case comparison of the last literal (the methodClass literal),<br>
> comparing keys and insisting that the keys be #== and the values be #==<br>
> (can't just define it as keys #== since all similar class-side methods will<br>
> be equal irrespective of their actual class).<br>
> 2. special case comparison of the last literal (the methodClass literal),<br>
> insisting only that the class of the literal be the same if it<br>
> isVariableBinding.<br>
> 3. make the compile unique class-side methodClass literals. i.e. if a class<br>
> already has a class-side method then the compiler or method dictionary<br>
> insertion code must find that existing association and reuse it<br>
> Other ideas?<br>
><br>
>><br>
>> >From my point of view, that literal, the last one does not need to be<br>
>> identical to assume 2 CMs are equal. They just need to be equal.<br>
>><br>
>><br>
>> --<br>
>> Mariano<br>
>> <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
>><br>
><br>
><br>
><br>
> --<br>
> best,<br>
> Eliot<br>
><br>
><br>
><br>
><br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div><br>