<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small">Hi Christoph,<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Mar 14, 2021 at 8:48 AM Thiede, Christoph <<a href="mailto:Christoph.Thiede@student.hpi.uni-potsdam.de">Christoph.Thiede@student.hpi.uni-potsdam.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">




<div dir="ltr">
<div id="gmail-m_-1665041689816893699divtagdefaultwrapper" style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif" dir="ltr">
<p>Hi all,</p>
<p><br>
</p>
<p>it's Sunday afternoon (at least in my timezone :D) and here's an interesting weekend issue for you, maybe even a bug in the VM:</p>
<p><br>
</p>
<p></p>
<div>p := [ObjectTest new testBecomeForward] newProcess.</div>
<div>p runUntil: [:c | c isDead].</div>
<br>
<p></p>
<p>In my fresh trunk image, this expression always fails, i.e. a TestFailure is raised from the second assertion in the test, <span>pt3 == pt2.</span></p>
<p><span><span style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols;font-size:16px"></span></span></p>
<p style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols;font-size:16px">
However, w<span style="font-size:12pt">hen running the test normally, i.e. executing the first block without simulation, the test passes as expected.</span></p>
<div>Also, when I try to debug the simulation, the test passes again.<br>
</div>

<p></p>
<p><span><span style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols;font-size:16px">But I even inserted a halt around the (pt3 == pt2) and could
 see that it actually </span><span style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols;font-size:16px">evaluated to false.</span><br>
</span></p>
<p><br>
</p>
<p><span style="font-size:12pt">And when I change the expression like this, it suddenly passes:</span></p>
<p><span style="font-size:12pt"><br>
</span></p>
<p><span style="font-size:12pt"></span></p>
<div style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols;font-size:16px">
p := [ObjectTest new testBecomeForward] newProcess.</div>
<div style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols;font-size:16px">
p runUntil: [:c | Smalltalk garbageCollect. c isDead].</div>
<br>

<p></p>
<p><span style="font-size:12pt">What is this? Does the VM require some kind of memory sweep before the object identity consistency is restored again? To me, this looks pretty suspicious at least.</span></p></div></div></blockquote><div><font size="4"><br></font></div><div class="gmail_default"><font size="4">Thank you.  You've found a bug in the interpreted version of primitive 110.  It read</font></div><div class="gmail_default"><font size="4"><br></font></div><div class="gmail_default"><div class="gmail_default"><font face="times new roman, serif" size="4">primitiveIdentical</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>"is the receiver/first argument the same object as the (last) argument?.</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">      </span> pop argumentCount because this can be used as a mirror primitive."</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>| thisObject otherObject |</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span><span style="color:rgb(0,0,0)">otherObject</span> := self stackValue: 1.</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">    </span><span style="color:rgb(0,0,0)">thisObject</span> := self stackTop.</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>((objectMemory isOopForwarded: otherObject)</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span> or: [argumentCount > 1</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span> and: [objectMemory isOopForwarded: thisObject]])</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>ifTrue:</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>[self primitiveFailFor: PrimErrBadArgument]</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">                </span>ifFalse:</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>[self pop: argumentCount + 1 thenPushBool: thisObject = otherObject]</font></div><div class="gmail_default"><font size="4"><br></font></div><div class="gmail_default"><font size="4">but this is the wrong way around.  It should read</font></div><div class="gmail_default"><font size="4"><br></font></div><div class="gmail_default"><div class="gmail_default"><font face="times new roman, serif" size="4">primitiveIdentical</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>"is the receiver/first argument the same object as the (last) argument?.</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">      </span> pop argumentCount because this can be used as a mirror primitive."</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>| thisObject otherObject |</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>thisObject := self stackValue: 1.</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>otherObject := self stackTop.</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>((objectMemory isOopForwarded: otherObject)</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span> or: [argumentCount > 1</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span> and: [objectMemory isOopForwarded: thisObject]])</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>ifTrue:</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>[self primitiveFailFor: PrimErrBadArgument]</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">                </span>ifFalse:</font></div><div class="gmail_default"><font face="times new roman, serif" size="4"><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>[self pop: argumentCount + 1 thenPushBool: thisObject = otherObject]</font></div><div class="gmail_default"><font size="4"><br></font></div><div class="gmail_default"><font size="4">The invariant on invoking a primitive is that the receiver is unforwarded.  This is because it being the receiver of the message, the message send machinery ensures it is not forwarded (if it was, the cached message send logic would fail, and the slow lookup path checks for a forwarded receiver, unforwarding and repeating the send if so).  But primitive arguments could be forwarded.  So primitiveIdentical must check for a potentially forwarded argument.  Stupidly I had written this carelessly and had not got the variable names the right way round and hence was checking if the receiver was forwarded, not the argument.</font></div></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div id="gmail-m_-1665041689816893699divtagdefaultwrapper" style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif" dir="ltr">
<p><span style="font-size:12pt">In SqueakJS, I cannot reproduce the issue, i.e., since </span><a href="https://github.com/codefrau/SqueakJS/pull/117" id="gmail-m_-1665041689816893699LPlnk113464" target="_blank" style="font-size:12pt">https://github.com/codefrau/SqueakJS/pull/117</a><span style="font-size:12pt">, #testBecomeForward
 never fails.</span></p></div></div></blockquote><div class="gmail_default"><font size="4">SqueakJS doesn't use transparent forwarding.  You'll also find that it won't fail in a pre-Spur image.</font></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div id="gmail-m_-1665041689816893699divtagdefaultwrapper" style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif" dir="ltr"><p><span style="font-size:12pt">Best,</span><br></p>
<p><span style="font-size:12pt">Christoph</span></p></div></div></blockquote></div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="border-collapse:separate"><font size="4"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></font></span></div></div></div></div></div></div></div></div></div></div>