---------- Forwarded message ----------
From: Eliot Miranda <eliot.miranda@gmail.com>
Date: Fri, Oct 25, 2013 at 2:18 PM
Subject: use of pointsTo: for includesSelector:
To: The general-purpose Squeak developers list <squeak-dev@lists.squeakfoundation.org>, Pharo Development <pharo-project@lists.gforge.inria.fr>


Hi All,

� � 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:

anArray doWithIndex:
[:entry :index|
(self whichClassIncludesSelector: entry) ifNotNil:
[:c| | m |
m := c >> entry.
(m pragmaAt: #option:) ifNotNil:
[:pragma|
(initializationOptions at: (pragma arguments first) ifAbsent: [true]) ifFalse:
[anArray at: index put: 0]]]]

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:

MethodDictionary>>includesKey: aSymbol
"This override assumes that pointsTo is a fast primitive"

aSymbol ifNil: [^ false].
^ self pointsTo: aSymbol

ProtoObject>>pointsTo: anObject
"This method returns true if self contains a pointer to anObject,
and returns false otherwise"
<primitive: 132>
1 to: self class instSize do:
[:i | (self instVarAt: i) == anObject ifTrue: [^ true]].
1 to: self basicSize do:
[:i | (self basicAt: i) == anObject ifTrue: [^ true]].
^ false

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?
--
best,
Eliot



--
best,
Eliot