<br><br><div class="gmail_quote">On Thu, Sep 15, 2011 at 1:00 PM, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@gmail.com</a>&gt;</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 &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;:<br>
<div><div></div><div class="h5">&gt;<br>
&gt;<br>
&gt; On Thu, Sep 15, 2011 at 9:45 AM, Mariano Martinez Peck<br>
&gt; &lt;<a href="mailto:marianopeck@gmail.com">marianopeck@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Ok, I understand. But<br>
&gt;&gt;<br>
&gt;&gt; On Thu, Sep 15, 2011 at 6:05 PM, Henrik Sperre Johansen<br>
&gt;&gt; &lt;<a href="mailto:henrik.s.johansen@veloxit.no">henrik.s.johansen@veloxit.no</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On 15.09.2011 17:27, Mariano Martinez Peck wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hi guys. I am having a problem with the integration of issue 4538:<br>
&gt;&gt;&gt; <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>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; I am serializing CompiledMethods with Fuel and then I materialize them.<br>
&gt;&gt;&gt; To test they are correct, I use #=<br>
&gt;&gt;&gt; So far it was working correctly, but now for the materialized method it<br>
&gt;&gt;&gt; says they are not equal. The problem is that #= is failing in<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; (self sameLiteralsAs: aCompiledMethod)<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; And inside that method, it is failing because     (literal1 == literal2<br>
&gt;&gt;&gt; or: [ literal1 literalEqual: literal2 ])<br>
&gt;&gt;&gt; answers false.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; So... why literal1 literalEqual: literal2 answers false?  from what I can<br>
&gt;&gt;&gt; say, having that selector: &quot;literalEqual&quot;, then both MUST be equal, because<br>
&gt;&gt;&gt; they are.<br>
&gt;&gt;&gt; The problem is that it was added:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Association &gt;&gt; literalEqual: otherLiteral<br>
&gt;&gt;&gt;     &quot;Answer true if the receiver and otherLiteral represent the same<br>
&gt;&gt;&gt; literal.<br>
&gt;&gt;&gt;     Variable bindings are literally equals only if identical.<br>
&gt;&gt;&gt;     This is how variable sharing works, by preserving identity and<br>
&gt;&gt;&gt; changing only the value.&quot;<br>
&gt;&gt;&gt;     ^self == otherLiteral<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; So....I am not sure I agree with this change.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Any idea how can we deal with this problem?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Cheers<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; --<br>
&gt;&gt;&gt; Mariano<br>
&gt;&gt;&gt; <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; The change is correct, here&#39;s an example:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Create a global:<br>
&gt;&gt;&gt; Global := 1<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Create a method:<br>
&gt;&gt;&gt;    foo<br>
&gt;&gt;&gt;     ^Global<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Serialize method, deserialize<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Change value of global:<br>
&gt;&gt;&gt; Global := 5.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; foo should return 5, not 1.<br>
&gt;&gt;&gt; Unless it&#39;s actually the same association as in the SystemDictionary,<br>
&gt;&gt;&gt; this will not be true.<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; I understand that. In fact, in Fuel we use exactly the same association of<br>
&gt;&gt; SystemDictionary for globals. Look this test example:<br>
&gt;&gt;<br>
&gt;&gt; testGlobalVariableMethod<br>
&gt;&gt;<br>
&gt;&gt;     | materializedCompiledMethod |<br>
&gt;&gt;     Smalltalk globals at: #TestGlobalVariableMethod2 put: false.<br>
&gt;&gt;     (self class compileSilently: &#39;globalVariableForTestingMethod<br>
&gt;&gt;     Transcript name.<br>
&gt;&gt;     ^ GlobalVariableForTesting.&#39;).<br>
&gt;&gt;<br>
&gt;&gt;     materializedCompiledMethod := self materializedCompiledMethod: (self<br>
&gt;&gt; class &gt;&gt; #globalVariableForTestingMethod).<br>
&gt;&gt;     Smalltalk globals at: #GlobalVariableForTesting put: true.<br>
&gt;&gt;     self assert:  (materializedCompiledMethod valueWithReceiver: self<br>
&gt;&gt; arguments: #()).<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; BUT, it doesn&#39;t mean that Association is always used for globals.<br>
&gt;&gt; CompiledMethod equality is failing because of the last literal, the one that<br>
&gt;&gt; maps class name (symbol) and point to the real class. So...when I<br>
&gt;&gt; materialize, both CMs have non-identical associations for the last literal,<br>
&gt;&gt; but equal.<br>
&gt;<br>
&gt; As Henrik says the last literals are ideally #== to each other.  However, no<br>
&gt; Squeak dialect makes any attempt to keep the class0side associations equal.<br>
&gt; Look at a class-side method and you&#39;ll see it&#39;s last literal is<br>
&gt; nil-&gt;SomeClass class.  Now since this association doesn&#39;t exist in Smalltalk<br>
&gt; (unlike last literals on the instance side) the compiler merely creates<br>
&gt; distinct ones for each class-side method.<br>
&gt; Personally I don&#39;t think one can defend the position where method equality<br>
&gt; is different for instance-side or class-side methods so there must be some<br>
&gt; 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&gt;&gt;printOn: and for the debugger).  One doesn&#39;t need to use an association, but one can&#39;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&#39;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&#39;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: &#39;bar ^1&#39;.<br>
Foo compile: &#39;bar<br>
   ^super bar *2&#39;.<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&gt;&gt;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 &quot;don&#39;t do that&quot;, and in Smalltalk we should say &quot;what did you expect&quot;? :)  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>
&gt; 1. special case comparison of the last literal (the methodClass literal),<br>
&gt; comparing keys and insisting that the keys be #== and the values be #==<br>
&gt; (can&#39;t just define it as keys #== since all similar class-side methods will<br>
&gt; be equal irrespective of their actual class).<br>
&gt; 2. special case comparison of the last literal (the methodClass literal),<br>
&gt; insisting only that the class of the literal be the same if it<br>
&gt; isVariableBinding.<br>
&gt; 3. make the compile unique class-side methodClass literals.  i.e. if a class<br>
&gt; already has a class-side method then the compiler or method dictionary<br>
&gt; insertion code must find that existing association and reuse it<br>
&gt; Other ideas?<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt;From my point of view, that literal, the last one does not need to be<br>
&gt;&gt; identical to assume 2 CMs are equal. They just need to be equal.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; Mariano<br>
&gt;&gt; <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; best,<br>
&gt; Eliot<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div><br>