[Vm-dev] Does primitiveEqual perform too much job ?
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Fri Aug 31 21:38:55 UTC 2012
Let's browse this code:
primitiveEqual
| integerReceiver integerArgument result |
integerArgument := self popStack.
integerReceiver := self popStack.
result := self compare31or32Bits: integerReceiver equal: integerArgument.
self checkBooleanResult: result
compare31or32Bits: obj1 equal: obj2
"May set success to false"
"First compare two ST integers..."
((self isIntegerObject: obj1)
and: [self isIntegerObject: obj2])
ifTrue: [^ obj1 = obj2].
"Now compare, assuming positive integers, but setting fail if not"
^ (self positive32BitValueOf: obj1) = (self positive32BitValueOf: obj2)
positive32BitValueOf: oop
"Convert the given object into an integer value.
The object may be either a positive ST integer or a four-byte
LargePositiveInteger."
| sz value |
(self isIntegerObject: oop) ifTrue: [
value := self integerValueOf: oop.
value < 0 ifTrue: [^ self primitiveFail].
^ value].
self assertClassOf: oop is: (self splObj: ClassLargePositiveInteger).
successFlag ifTrue: [
sz := self lengthOf: oop.
sz = 4 ifFalse: [^ self primitiveFail]].
successFlag ifTrue: [
^ (self fetchByte: 0 ofObject: oop) +
((self fetchByte: 1 ofObject: oop) << 8) +
((self fetchByte: 2 ofObject: oop) << 16) +
((self fetchByte: 3 ofObject: oop) << 24) ].
Why do we need to check equality vs 32bit ClassLargePositiveInteger?
Is there any producer of such un-normalized LargePositiveInteger?
If not, a much simpler thing that would work is to just compare the oop:
primitiveEqual
| integerReceiver integerArgument result |
integerArgument := self popStack.
integerReceiver := self popStack.
(self isIntegerObject: integerArgument) ifFalse: [self primitiveFail. ^nil].
self checkBooleanResult: integerReceiver = integerArgument
OK, it will fail for LargeInt instead of answering false, if we really
need to accelerate this edge case, just do:
primitiveEqual
| integerReceiver integerArgument result |
integerArgument := self popStack.
integerReceiver := self popStack.
(self isIntegerObject: integerArgument)
ifFalse:
[self assertClassOf: oop is: (self splObj: ClassLargePositiveInteger)].
self checkBooleanResult: integerReceiver = integerArgument
It's not very pure, we may compare an encoded signed interger value
xxxx...xxxxxxx1 with a pointer yyyy...yyyyy00, but they will never
equal.
Or maybe we never really call the primitive because we use kinda
special bytecode ?
I'm just curious...
Nicolas
More information about the Vm-dev
mailing list