[Vm-dev] Integer comparition primitive failures on Cog
Igor Stasenko
siguctua at gmail.com
Mon May 2 11:22:07 UTC 2011
On 2 May 2011 13:06, Henrik Sperre Johansen
<henrik.s.johansen at veloxit.no> wrote:
>
> On 02.05.2011 12:48, Igor Stasenko wrote:
>>
>> Hmm.. that's really strange, because as far as i can see,
>> the code there are the same:
>>
>> (primitive: 3)
>>
>> Interpreter>>primitiveLessThan
>> | integerReceiver integerArgument |
>> integerArgument := self popInteger.
>> integerReceiver := self popInteger.
>> self checkBooleanResult: integerReceiver< integerArgument
>>
>> InterpreterPrimitives>>primitiveLessThan
>> | integerReceiver integerArgument |
>> integerArgument := self popInteger.
>> integerReceiver := self popInteger.
>> self checkBooleanResult: integerReceiver< integerArgument
>>
>> and #popInteger also same (it fails if value on stack are not
>> smallinteger).
>> So, in Squeak VM comparison primitive also fails,
>> which should lead to evaluating failure code.
>
> Cog has translation methods for those primitives in cogit.c, see
> genSmallIntegerComparison.
>
>
>> Also, a primitives for floats accepting a smallintegers as arguments,
>> so by rewriting:
>>
>>
>> SmallInteger>> < aNumber
>> "Primitive. Compare the receiver with the argument and answer with
>> true if the receiver is less than the argument. Otherwise answer
>> false.
>> Fail if the argument is not a SmallInteger. Essential. No Lookup.
>> See
>> Object documentation whatIsAPrimitive."
>>
>> <primitive: 3>
>> ^ aNumber>= self
>>
>>
>> [1 to: 2000000 do: [:i |
>> i< 2354.234. ] timeToRun
>>
>> before:
>>
>> 8223
>>
>> after:
>> 20
>>
>> so... 421 times faster :)
>
> Yes, that's basically what I proposed to do in image, albeit in a different
> place.
>
But i really wonder why it falls to normal send..
Consider this:
StackInterpreter>>bytecodePrimLessThan
| rcvr arg aBool |
rcvr := self internalStackValue: 1.
arg := self internalStackValue: 0.
(self areIntegers: rcvr and: arg) ifTrue:
["The C code can avoid detagging since tagged integers are still signed.
But this means the simulator must override to do detagging."
^self cCode: [self booleanCheat: rcvr < arg]
inSmalltalk: [self booleanCheat: (objectMemory integerValueOf:
rcvr) < (objectMemory integerValueOf: arg)]].
self initPrimCall.
aBool := self primitiveFloatLess: rcvr thanArg: arg.
self successful ifTrue: [^ self booleanCheat: aBool].
messageSelector := self specialSelector: 2.
argumentCount := 1.
self normalSend
so, for #< send it tries to avoid doing normal send
and instead tries to do quick int<int comparison first,
and then
float/int < float/int
second (using #primitiveFloatLess:thanArg:)
so it should not fall to normal send.
So , i think the problem is, that #genSmallIntegerComparison: (and friends)
generating code for comparing integers only and falls back to normal
send when it fails,
without attempting to use #primitiveFloatLess:thanArg: .
> Cheers,
> Henry
>
--
Best regards,
Igor Stasenko AKA sig.
More information about the Vm-dev
mailing list