<div dir="ltr"><div>Ouch! bad bug!<br>I don't know if we need the speed, but we need the correctness.<br><br></div>To add to weirdness, I tested that (Object canUnderstand: Object methodDictionary size) is true, but I have (Object canUnderstand: Object selectors size) answering false, because it has two non nil slot less than the tally...<br>
<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/10/25 Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hi All,<div><br></div><div> I just got a little burned. I was searching through an Array of symbols and integers (it is the PrimitiveTable from the VM), wanting to filter-out methods with a with a certain pragma. The code looks like:</div>
<div><br></div><div><div><span style="white-space:pre-wrap">        </span>anArray doWithIndex:</div><div><span style="white-space:pre-wrap">                </span>[:entry :index|</div><div><span style="white-space:pre-wrap">                </span>(self whichClassIncludesSelector: entry) ifNotNil:</div>
<div><span style="white-space:pre-wrap">                        </span>[:c| | m |</div><div><span style="white-space:pre-wrap">                        </span>m := c >> entry.</div><div><span style="white-space:pre-wrap">                        </span>(m pragmaAt: #option:) ifNotNil:</div>
<div><span style="white-space:pre-wrap">                                </span>[:pragma|</div><div><span style="white-space:pre-wrap">                                </span>(initializationOptions at: (pragma arguments first) ifAbsent: [true]) ifFalse:</div>
<div><span style="white-space:pre-wrap">                                        </span>[anArray at: index put: 0]]]]</div><div><br></div><div>the error was a keyNotFound error for c >> entry. Turns out entry was the integer 306, a code for a quick primitive that returns some inst var. The question is why did (self whichClassIncludesSelector: entry) evaluate to other than nil given that 306 is /not/ a selector in any of the classes from self on up. Well, it's MethodDictionary's use of pointsTo: that is at fault:</div>
<div><br></div><div><div>MethodDictionary>>includesKey: aSymbol</div><div><span style="white-space:pre-wrap">        </span>"This override assumes that pointsTo is a fast primitive"</div><div><br>
</div><div><span style="white-space:pre-wrap">        </span>aSymbol ifNil: [^ false].</div><div><span style="white-space:pre-wrap">        </span>^ self pointsTo: aSymbol</div></div><div><br></div><div>
<div>ProtoObject>>pointsTo: anObject</div><div><span style="white-space:pre-wrap">        </span>"This method returns true if self contains a pointer to anObject,</div><div><span style="white-space:pre-wrap">                </span>and returns false otherwise"</div>
<div><span style="white-space:pre-wrap">        </span><primitive: 132></div><div><span style="white-space:pre-wrap">        </span>1 to: self class instSize do:</div><div><span style="white-space:pre-wrap">                </span>[:i | (self instVarAt: i) == anObject ifTrue: [^ true]].</div>
<div><span style="white-space:pre-wrap">        </span>1 to: self basicSize do:</div><div><span style="white-space:pre-wrap">                </span>[:i | (self basicAt: i) == anObject ifTrue: [^ true]].</div>
<div><span style="white-space:pre-wrap">        </span>^ false</div></div><div><div><br></div><div>Turns out that 306 was the tally of one of the method dictionaries along self's superclass chain. This seems to be to be completely bogus. Do we really need crude performance hacks like this any more?</div>
<span class="HOEnZb"><font color="#888888">
-- <br>best,<div>Eliot</div>
</font></span></div></div></div>
<br><br>
<br></blockquote></div><br></div>