<div dir="ltr"><div>This is necessary for LLP64 and it does not break tests on build.macos64x64/squeak.cog.spur so it should be OK.<br></div>It would be interesting to measure if it has any impact on performance.<br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-11-08 22:07 GMT+01:00 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1986.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/<wbr>VMMaker/VMMaker.oscog-nice.<wbr>1986.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.1986<br>
Author: nice<br>
Time: 8 November 2016, 9:59:38.206628 pm<br>
UUID: e06214fe-0e06-4c33-9132-<wbr>03ffe9351cbb<br>
Ancestors: VMMaker.oscog-nice.1985<br>
<br>
Like already the case for the #positive32BitIntegerFor: and #signed32BitIntegerFor: , #positive32BitValueOf: and #signed32BitValueOf: can be simplified with separate 32/64 bits branches.<br>
<br>
Indeed, we know that any 32bits signed/unsigned int will fit into a SmallInteger when hasSixtyFourBitImmediates,.<br>
No need to perform any superfluous testing...<br>
<br>
The previous implementation produces a lot of dead code in 64bits VM and prevents inlining unecessarily.<br>
<br>
=============== Diff against VMMaker.oscog-nice.1985 ===============<br>
<br>
Item was added:<br>
+ ----- Method: InterpreterPrimitives>><wbr>maybeInlinePositive32BitValueO<wbr>f: (in category 'primitive support') -----<br>
+ maybeInlinePositive32BitValueO<wbr>f: oop<br>
+ "Convert the given object into an integer value.<br>
+ The object may be either a positive SmallInteger or a four-byte LargePositiveInteger."<br>
+ <notOption: #Spur64BitMemoryManager><br>
+ <returnTypeC: #'unsigned int'><br>
+ | value ok sz |<br>
+ (objectMemory isIntegerObject: oop) ifTrue:<br>
+ [value := objectMemory integerValueOf: oop.<br>
+ (value < 0) ifTrue:<br>
+ [self primitiveFail. value := 0].<br>
+ ^value].<br>
+<br>
+ (objectMemory isNonIntegerImmediate: oop)<br>
+ ifTrue:<br>
+ [self primitiveFail.<br>
+ ^0]<br>
+ ifFalse:<br>
+ [ok := objectMemory<br>
+ isClassOfNonImm: oop<br>
+ equalTo: (objectMemory splObj: ClassLargePositiveInteger)<br>
+ compactClassIndex: ClassLargePositiveIntegerCompa<wbr>ctIndex.<br>
+ ok ifFalse:<br>
+ [self primitiveFail.<br>
+ ^0].<br>
+ sz := objectMemory numBytesOfBytes: oop.<br>
+ sz > 4 ifTrue:<br>
+ [self primitiveFail.<br>
+ ^0].<br>
+ ^self cCoerceSimple: (objectMemory byteSwapped32IfBigEndian: (objectMemory fetchLong32: 0 ofObject: oop)) to: #'unsigned int']!<br>
<br>
Item was added:<br>
+ ----- Method: InterpreterPrimitives>><wbr>noInlineSigned32BitValueOf: (in category 'primitive support') -----<br>
+ noInlineSigned32BitValueOf: oop<br>
+ "Convert the given object into an integer value.<br>
+ The object may be either a SmallInteger or a four-byte LargeInteger."<br>
+ | value negative ok magnitude |<br>
+ <notOption: #Spur64BitMemoryManager><br>
+ <inline: false><br>
+ <returnTypeC: #int><br>
+ <var: #value type: #int><br>
+ <var: #magnitude type: #'unsigned int'><br>
+ self deny: objectMemory hasSixtyFourBitImmediates.<br>
+ (objectMemory isIntegerObject: oop) ifTrue:<br>
+ [^objectMemory integerValueOf: oop].<br>
+<br>
+ (objectMemory isNonIntegerImmediate: oop) ifTrue:<br>
+ [self primitiveFail.<br>
+ ^0].<br>
+<br>
+ ok := objectMemory<br>
+ isClassOfNonImm: oop<br>
+ equalTo: (objectMemory splObj: ClassLargePositiveInteger)<br>
+ compactClassIndex: ClassLargePositiveIntegerCompa<wbr>ctIndex.<br>
+ ok<br>
+ ifTrue: [negative := false]<br>
+ ifFalse:<br>
+ [negative := true.<br>
+ ok := objectMemory isClassOfNonImm: oop<br>
+ equalTo: (objectMemory splObj: ClassLargeNegativeInteger)<br>
+ compactClassIndex: ClassLargeNegativeIntegerCompa<wbr>ctIndex.<br>
+ ok ifFalse:<br>
+ [self primitiveFail.<br>
+ ^0]].<br>
+ (objectMemory numBytesOfBytes: oop) > 4 ifTrue:<br>
+ [^self primitiveFail].<br>
+<br>
+ magnitude := self cCoerceSimple: (objectMemory byteSwapped32IfBigEndian: (objectMemory fetchLong32: 0 ofObject: oop)) to: #'unsigned int'.<br>
+<br>
+ (negative<br>
+ ifTrue: [magnitude > 16r80000000]<br>
+ ifFalse: [magnitude >= 16r80000000])<br>
+ ifTrue:<br>
+ [self primitiveFail.<br>
+ ^0].<br>
+ negative<br>
+ ifTrue: [value := 0 - magnitude]<br>
+ ifFalse: [value := magnitude].<br>
+ ^value!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>><wbr>positive32BitValueOf: (in category 'primitive support') -----<br>
positive32BitValueOf: oop<br>
"Convert the given object into an integer value.<br>
The object may be either a positive SmallInteger or a four-byte LargePositiveInteger."<br>
+ <returnTypeC: #'unsigned int'><br>
+ objectMemory hasSixtyFourBitImmediates<br>
- <returnTypeC: #usqInt><br>
- | value ok sz |<br>
- (objectMemory isIntegerObject: oop) ifTrue:<br>
- [value := objectMemory integerValueOf: oop.<br>
- (value < 0<br>
- or: [objectMemory wordSize > 4<br>
- and: [self cCode: [(self cCoerceSimple: value to: #'unsigned int') ~= value]<br>
- inSmalltalk: [value >> 32 ~= 0]]]) ifTrue:<br>
- [self primitiveFail. value := 0].<br>
- ^value].<br>
-<br>
- (objectMemory hasSixtyFourBitImmediates<br>
- or: [objectMemory isNonIntegerImmediate: oop])<br>
ifTrue:<br>
+ [(objectMemory isIntegerObject: oop) ifTrue:<br>
+ [| value64 |<br>
+ value64 := objectMemory integerValueOf: oop.<br>
+ (value64 < 0<br>
+ or: [self cCode: [(self cCoerceSimple: value64 to: #'unsigned int') ~= value64]<br>
+ inSmalltalk: [value64 >> 32 ~= 0]]) ifTrue:<br>
+ [self primitiveFail. value64 := 0].<br>
+ ^value64].<br>
+ self primitiveFail.<br>
+ ^0]<br>
- [self primitiveFail.<br>
- ^0]<br>
ifFalse:<br>
+ [^self maybeInlinePositive32BitValueO<wbr>f: oop]!<br>
- [ok := objectMemory<br>
- isClassOfNonImm: oop<br>
- equalTo: (objectMemory splObj: ClassLargePositiveInteger)<br>
- compactClassIndex: ClassLargePositiveIntegerCompa<wbr>ctIndex.<br>
- ok ifFalse:<br>
- [self primitiveFail.<br>
- ^0].<br>
- sz := objectMemory numBytesOfBytes: oop.<br>
- sz > 4 ifTrue:<br>
- [self primitiveFail.<br>
- ^0].<br>
- ^self cCoerceSimple: (objectMemory byteSwapped32IfBigEndian: (objectMemory fetchLong32: 0 ofObject: oop)) to: #'unsigned int']!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>><wbr>signed32BitValueOf: (in category 'primitive support') -----<br>
signed32BitValueOf: oop<br>
"Convert the given object into an integer value.<br>
+ The object may be either a SmallInteger or a four-byte LargeInteger."<br>
- The object may be either a positive SmallInteger or a four-byte LargeInteger."<br>
- | value negative ok magnitude |<br>
- <inline: false><br>
<returnTypeC: #int><br>
+<br>
+ objectMemory hasSixtyFourBitImmediates<br>
+ ifTrue:<br>
+ [(objectMemory isIntegerObject: oop) ifTrue:<br>
- <var: #value type: #int><br>
- <var: #magnitude type: #'unsigned int'><br>
- <var: #value64 type: #long><br>
- (objectMemory isIntegerObject: oop) ifTrue:<br>
- [objectMemory wordSize = 4<br>
- ifTrue:<br>
- [^objectMemory integerValueOf: oop]<br>
- ifFalse: "Must fail for SmallIntegers with digitLength > 4"<br>
[| value64 |<br>
value64 := objectMemory integerValueOf: oop.<br>
(self cCode: [(self cCoerceSimple: value64 to: #int) ~= value64]<br>
inSmalltalk: [value64 >> 31 ~= 0 and: [value64 >> 31 ~= -1]]) ifTrue:<br>
[self primitiveFail. value64 := 0].<br>
+ ^value64].<br>
+ self primitiveFail.<br>
+ ^0]<br>
- ^value64]].<br>
-<br>
- (objectMemory isNonIntegerImmediate: oop) ifTrue:<br>
- [self primitiveFail.<br>
- ^0].<br>
-<br>
- ok := objectMemory<br>
- isClassOfNonImm: oop<br>
- equalTo: (objectMemory splObj: ClassLargePositiveInteger)<br>
- compactClassIndex: ClassLargePositiveIntegerCompa<wbr>ctIndex.<br>
- ok<br>
- ifTrue: [negative := false]<br>
ifFalse:<br>
+ [^self noInlineSigned32BitValueOf: oop]!<br>
- [negative := true.<br>
- ok := objectMemory isClassOfNonImm: oop<br>
- equalTo: (objectMemory splObj: ClassLargeNegativeInteger)<br>
- compactClassIndex: ClassLargeNegativeIntegerCompa<wbr>ctIndex.<br>
- ok ifFalse:<br>
- [self primitiveFail.<br>
- ^0]].<br>
- (objectMemory numBytesOfBytes: oop) > 4 ifTrue:<br>
- [^self primitiveFail].<br>
-<br>
- magnitude := self cCoerceSimple: (objectMemory byteSwapped32IfBigEndian: (objectMemory fetchLong32: 0 ofObject: oop)) to: #'unsigned int'.<br>
-<br>
- (negative<br>
- ifTrue: [magnitude > 16r80000000]<br>
- ifFalse: [magnitude >= 16r80000000])<br>
- ifTrue:<br>
- [self primitiveFail.<br>
- ^0].<br>
- negative<br>
- ifTrue: [value := 0 - magnitude]<br>
- ifFalse: [value := magnitude].<br>
- ^value!<br>
<br>
</blockquote></div><br></div>