[Vm-dev] VM Maker: VMMaker.oscog-nice.1732.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Mar 18 22:28:31 UTC 2016


2016-03-18 21:40 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:

>
> Hi Nicolas,
>
> On Thu, Mar 17, 2016 at 3:24 PM, <commits at source.squeak.org> wrote:
>
>>
>> Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
>> http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1732.mcz
>>
>> ==================== Summary ====================
>>
>> Name: VMMaker.oscog-nice.1732
>> Author: nice
>> Time: 17 March 2016, 11:22:07.715 pm
>> UUID: ea9dd158-4847-464e-9642-9786252797dc
>> Ancestors: VMMaker.oscog-nice.1731
>>
>> Use little endian accelerators too for fetching 32 & 64 bits large
>> integers value (like the ones used for storing value).
>>
>> Dramatically simplify fetching of signedInteger values by using an
>> intermediate unsigned magnitude.
>>
>> Declare the positive32/64BitIntegerFor: and
>> maybeInlinePositive32BitIntegerFor: parameter as unsigned since it is
>> interpreted as positive.
>>
>> Use asUnsignedInteger in isIntegerValue: tests, integerObjectOf: and
>> rotatedFloatBitsOf: in order to ban potential UB.
>>
>> Simplify bit operations using
>> positiveMachineIntegerValueOf:/positiveMachineIntegerFor: rather than doing
>> 32/64 bits dissertation.
>>
>> Fetch magnitude of positive large ints into an unsigned for large int bit
>> ops.
>>
>
>
> In the following
>
>  ----- Method: StackInterpreter>>maybeInlinePositive32BitIntegerFor: (in
> category 'primitive support') -----
>   maybeInlinePositive32BitIntegerFor: integerValue
>         "N.B. will *not* cause a GC.
>          integerValue is interpreted as POSITIVE, e.g. as the result of
> Bitmap>at:."
>         <notOption: #Spur64BitMemoryManager>
> +       <var: 'integerValue' type: #'unsigned int'>
>         | newLargeInteger |
>         self deny: objectMemory hasSixtyFourBitImmediates.
> +       integerValue <= objectMemory maxSmallInteger
> +               ifTrue: [^ objectMemory integerObjectOf: integerValue].
> -       (integerValue asInteger >= 0
> -        and: [objectMemory isIntegerValue: integerValue]) ifTrue:
> -               [^objectMemory integerObjectOf: integerValue].
>
> shouldn't we compare against minSmallInteger as well, because e.g.
> -16r80000000 could overflow SmallInteger and answer 0?
>
>
>
> P.S.  Lovely seeing this code getting some good loving.
>
>
Hi Eliot,
the idea is that every sender of positive32BitIntegerFor: will pass an
unsigned int.
At least that's the intention of every sender.

Unfortunately, slang inlining does not force a parameter variable copy in
case of sign mismatch
That's the case of primitiveBitShift in which a variable is declare signed
    sqInt shifted;
Then the send:
    shifted := self positiveMachineIntegerFor: shifted.
is translated into:
    if (shifted <= (MaxSmallInteger)) {
        shifted = ((shifted << 1) | 1);
instead of:
    unsigned int integerValue = shifted;
    if (integerValue <= (MaxSmallInteger)) {
        shifted = ((integerValue << 1) | 1);
    ...

Here we have 3 options:
   1) fix slang inlining
   2) patch every sender of positiveMachineIntegerFor: to make sure that
effective parameter is unsigned
   3) revert this change

In my branch I have opted for 2), but completely failed to backport the
patch in trunk (this change is 2 years old...).
Right now I'm testing that the patch work and I will commit ASAP.

Sorry for breaking, I've not tested enough because I'm too much focused on
64bits brand.
But testing all the flavours is not a task for a human anyway, more for a
bot like a Jenkins server.



>
>
>>
>> =============== Diff against VMMaker.oscog-nice.1731 ===============
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>magnitude64BitIntegerFor:neg: (in
>> category 'primitive support') -----
>>   magnitude64BitIntegerFor: magnitude neg: isNegative
>>         "Return a Large Integer object for the given integer magnitude
>> and sign"
>>         | newLargeInteger largeClass highWord sz isSmall smallVal |
>>         <var: 'magnitude' type: #usqLong>
>>         <var: 'highWord' type: #usqInt>
>>
>>         isSmall := isNegative
>>                                 ifTrue: [magnitude <= (objectMemory
>> maxSmallInteger + 1)]
>>                                 ifFalse: [magnitude <= objectMemory
>> maxSmallInteger].
>>         isSmall ifTrue:
>>                 [smallVal := self cCoerceSimple: magnitude to: #sqInt.
>>                  isNegative ifTrue: [smallVal := 0 - smallVal].
>>                  ^objectMemory integerObjectOf: smallVal].
>>
>>         largeClass := isNegative
>>                                         ifTrue: [objectMemory
>> classLargeNegativeInteger]
>>                                         ifFalse: [objectMemory
>> classLargePositiveInteger].
>>         objectMemory wordSize = 8
>>                 ifTrue: [sz := 8]
>>                 ifFalse:
>>                         [(highWord := magnitude >> 32) = 0
>>                                 ifTrue: [sz := 4]
>>                                 ifFalse:
>>                                         [sz := 5.
>>                                          (highWord := highWord >> 8) = 0
>> ifFalse:
>>                                                 [sz := sz + 1.
>>                                                  (highWord := highWord >>
>> 8) = 0 ifFalse:
>>                                                         [sz := sz + 1.
>>                                                          (highWord :=
>> highWord >> 8) = 0 ifFalse: [sz := sz + 1]]]]].
>>         newLargeInteger := objectMemory instantiateClass: largeClass
>> indexableSize:  sz.
>>         self cppIf: VMBIGENDIAN
>>                 ifTrue:
>>                         [sz > 4 ifTrue:
>>                                 [objectMemory
>>                                         storeByte: 7 ofObject:
>> newLargeInteger withValue: (magnitude >> 56 bitAnd: 16rFF);
>>                                         storeByte: 6 ofObject:
>> newLargeInteger withValue: (magnitude >> 48 bitAnd: 16rFF);
>>                                         storeByte: 5 ofObject:
>> newLargeInteger withValue: (magnitude >> 40 bitAnd: 16rFF);
>>                                         storeByte: 4 ofObject:
>> newLargeInteger withValue: (magnitude >> 32 bitAnd: 16rFF)].
>>                         objectMemory
>>                                 storeByte: 3 ofObject: newLargeInteger
>> withValue: (magnitude >> 24 bitAnd: 16rFF);
>>                                 storeByte: 2 ofObject: newLargeInteger
>> withValue: (magnitude >> 16 bitAnd: 16rFF);
>>                                 storeByte: 1 ofObject: newLargeInteger
>> withValue: (magnitude >>   8 bitAnd: 16rFF);
>>                                 storeByte: 0 ofObject: newLargeInteger
>> withValue: (magnitude ">> 0" bitAnd: 16rFF)]
>>                 ifFalse:
>> +                       [sz > 4
>> +                               ifTrue: [objectMemory storeLong64: 0
>> ofObject: newLargeInteger withValue: magnitude]
>> +                               ifFalse: [objectMemory storeLong32: 0
>> ofObject: newLargeInteger withValue: (self cCode: [magnitude] inSmalltalk:
>> [magnitude bitAnd: 16rFFFFFFFF])]].
>> -                       [sz > 4 ifTrue:
>> -                               [objectMemory storeLong32: 1 ofObject:
>> newLargeInteger withValue: magnitude >> 32].
>> -                       objectMemory
>> -                               storeLong32: 0
>> -                               ofObject: newLargeInteger
>> -                               withValue: (self cCode: [magnitude]
>> inSmalltalk: [magnitude bitAnd: 16rFFFFFFFF])].
>>
>>         ^newLargeInteger!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>magnitude64BitValueOf: (in
>> category 'primitive support') -----
>>   magnitude64BitValueOf: oop
>>         "Convert the given object into an integer value.
>>         The object may be either a positive SmallInteger or an eight-byte
>> LargeInteger."
>>         | sz value ok smallIntValue |
>>         <returnTypeC: #usqLong>
>>         <var: #value type: #usqLong>
>>
>>         (objectMemory isIntegerObject: oop) ifTrue:
>>                 [smallIntValue := (objectMemory integerValueOf: oop).
>>                 smallIntValue < 0 ifTrue: [smallIntValue := 0 -
>> smallIntValue].
>>                 ^self cCoerce: smallIntValue to: #usqLong].
>>
>>         (objectMemory isNonIntegerImmediate: oop) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>>         ok := objectMemory isClassOfNonImm: oop
>>                                         equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>>                                         compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>>         ok
>>                 ifFalse:
>>                         [ok := objectMemory isClassOfNonImm: oop
>>                                                         equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>>                         ok ifFalse:
>>                                 [self primitiveFail.
>>                                  ^0]].
>>         sz := objectMemory numBytesOfBytes: oop.
>>         sz > (self sizeof: #sqLong) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>> +       self cppIf: VMBIGENDIAN
>> +               ifTrue:
>> +                       [value := objectMemory fetchByte: sz - 1
>> ofObject: oop.
>> +                       sz - 2 to: 0 by: -1 do:
>> +                               [:i | value := value << 8 + (objectMemory
>> fetchByte: i ofObject: oop)]]
>> +               ifFalse:
>> +                       [sz > 4
>> +                               ifTrue: [value := self cCoerceSimple:
>> (objectMemory fetchLong64: 0 ofObject: oop) to: #usqLong]
>> +                               ifFalse: [value := self cCoerceSimple:
>> (objectMemory fetchLong32: 0 ofObject: oop) to: #'unsigned int'].].
>> -       value := objectMemory fetchByte: sz - 1 ofObject: oop.
>> -       sz - 2 to: 0 by: -1 do:
>> -               [:i | value := value << 8 + (objectMemory fetchByte: i
>> ofObject: oop)].
>>         ^value!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>positive64BitValueOf: (in category
>> 'primitive support') -----
>>   positive64BitValueOf: oop
>>         "Convert the given object into an integer value.
>>         The object may be either a positive SmallInteger or an eight-byte
>> LargePositiveInteger."
>>
>>         <returnTypeC: #usqLong>
>>         | sz value ok |
>>         <var: #value type: #usqLong>
>>         (objectMemory isIntegerObject: oop) ifTrue:
>>                 [(objectMemory integerValueOf: oop) < 0 ifTrue:
>>                         [^self primitiveFail].
>>                  ^objectMemory integerValueOf: oop].
>>
>>         (objectMemory isNonIntegerImmediate: oop) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>>         ok := objectMemory
>>                         isClassOfNonImm: oop
>>                         equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>>                         compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>>         ok ifFalse:
>>                 [self primitiveFail.
>>                  ^0].
>>         sz := objectMemory numBytesOfBytes: oop.
>>         sz > (self sizeof: #sqLong) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>> +       self cppIf: VMBIGENDIAN
>> +               ifTrue:
>> +                       [value := 0.
>> +                       0 to: sz - 1 do: [:i |
>> +                               value := value + ((self cCoerce:
>> (objectMemory fetchByte: i ofObject: oop) to: #usqLong) <<  (i*8))]]
>> +               ifFalse:
>> +                       [sz > 4
>> +                               ifTrue: [value := self cCoerceSimple:
>> (objectMemory fetchLong64: 0 ofObject: oop) to: #usqLong]
>> +                               ifFalse: [value := self cCoerceSimple:
>> (objectMemory fetchLong32: 0 ofObject: oop) to: #'unsigned int'].].
>> -       value := 0.
>> -       0 to: sz - 1 do: [:i |
>> -               value := value + ((self cCoerce: (objectMemory fetchByte:
>> i ofObject: oop) to: #usqLong) <<  (i*8))].
>>         ^value!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category
>> 'arithmetic integer primitives') -----
>>   primitiveBitAnd
>>         <inline: false>
>> +       <var: 'integerArgument' type: #usqInt>
>> +       <var: 'intergerReceiver' type: #usqInt>
>>         | integerReceiver integerArgument |
>>         integerArgument := self stackTop.
>>         integerReceiver := self stackValue: 1.
>>         "Comment out the short-cut.  Either the inline interpreter
>> bytecode or the JIT primitive will handle this case.
>>          ((objectMemory isIntegerObject: integerArgument)
>>          and: [objectMemory isIntegerObject: integerReceiver])
>>                 ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd:
>> integerReceiver)]
>>                 ifFalse:
>> +                       ["
>> +                       integerArgument := self
>> positiveMachineIntegerValueOf: integerArgument.
>> +                       integerReceiver := self
>> positiveMachineIntegerValueOf: integerReceiver.
>> +                       self successful ifTrue:
>> +                                       [self pop: 2 thenPush: (self
>> positiveMachineIntegerFor: (integerArgument bitAnd: integerReceiver))]
>> -                       ["objectMemory wordSize = 8
>> -                               ifTrue:
>> -                                       [integerArgument := self
>> positive64BitValueOf: integerArgument.
>> -                                        integerReceiver := self
>> positive64BitValueOf: integerReceiver.
>> -                                        self successful ifTrue:
>> -                                               [self pop: 2 thenPush:
>> (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]
>>                                 ifFalse:
>> +                                       []"]"!
>> -                                       [integerArgument := self
>> positive32BitValueOf: integerArgument.
>> -                                        integerReceiver := self
>> positive32BitValueOf: integerReceiver.
>> -                                        self successful ifTrue:
>> -                                               [self pop: 2 thenPush:
>> (self positive32BitIntegerFor: (integerArgument bitAnd:
>> integerReceiver))]]"]"!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>primitiveBitAndLargeIntegers (in
>> category 'arithmetic largeint primitives') -----
>>   primitiveBitAndLargeIntegers
>>         "Primitive logical operations for large integers in 64 bit range"
>>         | integerRcvr integerArg oopResult |
>>         <export: true>
>> +       <var: 'integerRcvr' type: 'usqLong'>
>> +       <var: 'integerArg' type: 'usqLong'>
>> -       <var: 'integerRcvr' type: 'sqLong'>
>> -       <var: 'integerArg' type: 'sqLong'>
>>
>>         integerArg := self positive64BitValueOf: (self stackValue: 0).
>>         integerRcvr := self positive64BitValueOf: (self stackValue: 1).
>>         self successful ifFalse:[^nil].
>>
>>         oopResult := self positive64BitIntegerFor: (integerRcvr bitAnd:
>> integerArg).
>>         self successful ifTrue:[self pop: 2 thenPush: oopResult]!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>primitiveBitOr (in category
>> 'arithmetic integer primitives') -----
>>   primitiveBitOr
>>         <inline: false>
>> +       <var: 'integerArgument' type: #usqInt>
>> +       <var: 'intergerReceiver' type: #usqInt>
>>         | integerReceiver integerArgument |
>>         integerArgument := self stackTop.
>>         integerReceiver := self stackValue: 1.
>>         "Comment out the short-cut.  Either the inline interpreter
>> bytecode or the JIT primitive will handle this case.
>>          ((objectMemory isIntegerObject: integerArgument)
>>          and: [objectMemory isIntegerObject: integerReceiver])
>>                 ifTrue: [self pop: 2 thenPush: (integerArgument bitOr:
>> integerReceiver)]
>>                 ifFalse:
>> +                       ["
>> +                       integerArgument := self
>> positiveMachineIntegerValueOf: integerArgument.
>> +                       integerReceiver := self
>> positiveMachineIntegerValueOf: integerReceiver.
>> +                       self successful ifTrue:
>> +                                       [self pop: 2 thenPush: (self
>> positiveMachineIntegerFor: (integerArgument bitOr: integerReceiver))]
>> -                       ["objectMemory wordSize = 8
>> -                               ifTrue:
>> -                                       [integerArgument := self
>> positive64BitValueOf: integerArgument.
>> -                                        integerReceiver := self
>> positive64BitValueOf: integerReceiver.
>> -                                        self successful ifTrue:
>> -                                               [self pop: 2 thenPush:
>> (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]
>>                                 ifFalse:
>> +                                       []"]"!
>> -                                       [integerArgument := self
>> positive32BitValueOf: integerArgument.
>> -                                        integerReceiver := self
>> positive32BitValueOf: integerReceiver.
>> -                                        self successful ifTrue:
>> -                                               [self pop: 2 thenPush:
>> (self positive32BitIntegerFor: (integerArgument bitOr:
>> integerReceiver))]]"]"!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>primitiveBitOrLargeIntegers (in
>> category 'arithmetic largeint primitives') -----
>>   primitiveBitOrLargeIntegers
>>         "Primitive logical operations for large integers in 64 bit range"
>>         | integerRcvr integerArg oopResult |
>>         <export: true>
>> +       <var: 'integerRcvr' type: 'usqLong'>
>> +       <var: 'integerArg' type: 'usqLong'>
>> -       <var: 'integerRcvr' type: 'sqLong'>
>> -       <var: 'integerArg' type: 'sqLong'>
>>
>>         integerArg := self positive64BitValueOf: (self stackValue: 0).
>>         integerRcvr := self positive64BitValueOf: (self stackValue: 1).
>>         self successful ifFalse:[^nil].
>>
>>         oopResult := self positive64BitIntegerFor: (integerRcvr bitOr:
>> integerArg).
>>         self successful ifTrue:[self pop: 2 thenPush: oopResult]!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>primitiveBitXor (in category
>> 'arithmetic integer primitives') -----
>>   primitiveBitXor
>>         <inline: false>
>>         | integerReceiver integerArgument |
>>         integerArgument := self stackTop.
>>         integerReceiver := self stackValue: 1.
>>         ((objectMemory isIntegerObject: integerArgument)
>>          and: [objectMemory isIntegerObject: integerReceiver])
>>                 ifTrue: "xoring will leave the tag bits zero, whether the
>> tag is 1 or zero, so add it back in."
>>                         [self pop: 2 thenPush: (integerArgument bitXor:
>> integerReceiver) + objectMemory smallIntegerTag]
>>                 ifFalse:
>> +                       [integerArgument := self
>> positiveMachineIntegerValueOf: integerArgument.
>> +                        integerReceiver := self
>> positiveMachineIntegerValueOf: integerReceiver.
>> +                        self successful ifTrue:
>> +                               [self pop: 2 thenPush: (self
>> positiveMachineIntegerFor: (integerArgument bitXor: integerReceiver))]]!
>> -                       [objectMemory wordSize = 8
>> -                               ifTrue:
>> -                                       [integerArgument := self
>> positive64BitValueOf: integerArgument.
>> -                                        integerReceiver := self
>> positive64BitValueOf: integerReceiver.
>> -                                        self successful ifTrue:
>> -                                               [self pop: 2 thenPush:
>> (self positive64BitIntegerFor: (integerArgument bitXor: integerReceiver))]]
>> -                               ifFalse:
>> -                                       [integerArgument := self
>> positive32BitValueOf: integerArgument.
>> -                                        integerReceiver := self
>> positive32BitValueOf: integerReceiver.
>> -                                        self successful ifTrue:
>> -                                               [self pop: 2 thenPush:
>> (self positive32BitIntegerFor: (integerArgument bitXor:
>> integerReceiver))]]]!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>primitiveBitXorLargeIntegers (in
>> category 'arithmetic largeint primitives') -----
>>   primitiveBitXorLargeIntegers
>>         "Primitive logical operations for large integers in 64 bit range"
>>         | integerRcvr integerArg oopResult |
>>         <export: true>
>> +       <var: 'integerRcvr' type: 'usqLong'>
>> +       <var: 'integerArg' type: 'usqLong'>
>> -       <var: 'integerRcvr' type: 'sqLong'>
>> -       <var: 'integerArg' type: 'sqLong'>
>>
>>         integerArg := self positive64BitValueOf: (self stackValue: 0).
>>         integerRcvr := self positive64BitValueOf: (self stackValue: 1).
>>         self successful ifFalse:[^nil].
>>
>>         oopResult := self positive64BitIntegerFor: (integerRcvr bitXor:
>> integerArg).
>>         self successful ifTrue:[self pop: 2 thenPush: oopResult]!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>signed32BitValueOf: (in category
>> 'primitive support') -----
>>   signed32BitValueOf: oop
>>         "Convert the given object into an integer value.
>>         The object may be either a positive SmallInteger or a four-byte
>> LargeInteger."
>> +       | value negative ok magnitude |
>> -       | value negative ok |
>>         <inline: false>
>>         <returnTypeC: #int>
>>         <var: #value type: #int>
>> +       <var: #magnitude type: #'unsigned int'>
>>         <var: #value64 type: #long>
>>         (objectMemory isIntegerObject: oop) ifTrue:
>>                 [objectMemory wordSize = 4
>>                         ifTrue:
>>                                 [^objectMemory integerValueOf: oop]
>>                         ifFalse: "Must fail for SmallIntegers with
>> digitLength > 4"
>>                                 [| value64 |
>>                                  value64 := objectMemory integerValueOf:
>> oop.
>>                                  (self cCode: [(self cCoerceSimple:
>> value64 to: #int) ~= value64]
>>                                                 inSmalltalk: [value64 >>
>> 31 ~= 0 and: [value64 >> 31 ~= -1]]) ifTrue:
>>                                         [self primitiveFail. value64 :=
>> 0].
>>                                  ^value64]].
>>
>>         (objectMemory isNonIntegerImmediate: oop) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>>         ok := objectMemory
>>                         isClassOfNonImm: oop
>>                         equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>>                         compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>>         ok
>>                 ifTrue: [negative := false]
>>                 ifFalse:
>>                         [negative := true.
>>                          ok := objectMemory isClassOfNonImm: oop
>>                                                         equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>>                          ok ifFalse:
>>                                 [self primitiveFail.
>>                                  ^0]].
>>         (objectMemory numBytesOfBytes: oop) > 4 ifTrue:
>>                 [^self primitiveFail].
>>
>> +       magnitude := self cppIf: VMBIGENDIAN
>> -       value := self cppIf: VMBIGENDIAN
>>                                 ifTrue:
>>                                         [ (objectMemory fetchByte: 0
>> ofObject: oop) +
>>                                          ((objectMemory fetchByte: 1
>> ofObject: oop) <<  8) +
>>                                          ((objectMemory fetchByte: 2
>> ofObject: oop) << 16) +
>>                                          ((objectMemory fetchByte: 3
>> ofObject: oop) << 24)]
>>                                 ifFalse:
>> +                                       [(objectMemory fetchLong32: 0
>> ofObject: oop) asUnsignedInteger].
>> +
>> +       (negative
>> +               ifTrue: [magnitude > 16r80000000]
>> +               ifFalse: [magnitude >= 16r80000000])
>> +                       ifTrue:
>> +                               [self primitiveFail.
>> +                               ^0].
>> +       negative
>> +               ifTrue: [value := 0 - magnitude]
>> +               ifFalse: [value := magnitude].
>> +       ^value!
>> -                                       [objectMemory fetchLong32: 0
>> ofObject: oop].
>> -       self cCode: []
>> -               inSmalltalk:
>> -                       [(value anyMask: 16r80000000) ifTrue:
>> -                               [value := value - 16r100000000]].
>> -       "Filter out values out of range for the signed interpretation
>> such as
>> -        16rFFFFFFFF (positive w/ bit 32 set) and -16rFFFFFFFF (negative
>> w/ bit
>> -        32 set). Since the sign is implicit in the class we require that
>> the high
>> -        bit of the magnitude is not set which is a simple test here.
>> Note that
>> -        we have to handle the most negative 32-bit value -2147483648
>> specially."
>> -       value < 0 ifTrue:
>> -               [self assert: (self sizeof: value) == 4.
>> -                "Don't fail for -16r80000000/-2147483648
>> -                 Alas the simple (negative and: [value - 1 > 0]) isn't
>> adequate since in C the result of signed integer
>> -                 overflow is undefined and hence under optimization this
>> may fail.  The shift, however, is well-defined."
>> -                (negative and: [0 = (self cCode: [value << 1]
>> -
>>  inSmalltalk: [value << 1 bitAnd: (1 << 32) - 1])]) ifTrue:
>> -                       [^value].
>> -                self primitiveFail.
>> -                ^0].
>> -       ^negative
>> -               ifTrue: [0 - value]
>> -               ifFalse: [value]!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>signed64BitValueOf: (in category
>> 'primitive support') -----
>>   signed64BitValueOf: oop
>>         "Convert the given object into an integer value.
>>          The object may be either a positive SmallInteger or a eight-byte
>> LargeInteger."
>> +       | sz value negative ok magnitude |
>> -       | sz value negative ok |
>>         <inline: false>
>>         <returnTypeC: #sqLong>
>>         <var: #value type: #sqLong>
>> +       <var: #magnitude type: #usqLong>
>>         (objectMemory isIntegerObject: oop) ifTrue:
>>                 [^self cCoerce: (objectMemory integerValueOf: oop) to:
>> #sqLong].
>>
>>         (objectMemory isNonIntegerImmediate: oop) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>>         ok := objectMemory isClassOfNonImm: oop
>>                                         equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>>                                         compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>>         ok
>>                 ifTrue: [negative := false]
>>                 ifFalse:
>>                         [negative := true.
>>                          ok := objectMemory isClassOfNonImm: oop
>>                                                         equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>>                         ok ifFalse:
>>                                 [self primitiveFail.
>>                                  ^0]].
>>         sz := objectMemory numBytesOfBytes: oop.
>>         sz > (self sizeof: #sqLong) ifTrue:
>>                 [self primitiveFail.
>>                  ^0].
>>
>>         self cppIf: VMBIGENDIAN
>>                 ifTrue:
>> +                       [magnitude := objectMemory fetchByte: sz - 1
>> ofObject: oop.
>> -                       [value := objectMemory fetchByte: sz - 1
>> ofObject: oop.
>>                          sz - 2 to: 0 by: -1 do: [:i |
>> +                               magnitude := magnitude << 8 +
>> (objectMemory fetchByte: i ofObject: oop)]]
>> -                               value := value << 8 + (objectMemory
>> fetchByte: i ofObject: oop)]]
>>                 ifFalse:
>> +                       [magnitude := sz > 4
>> -                       [value := sz > 4
>>                                                 ifTrue: [objectMemory
>> fetchLong64: 0 ofObject: oop]
>>                                                 ifFalse: [(objectMemory
>> fetchLong32: 0 ofObject: oop) asUnsignedInteger]].
>> +
>> +       (negative
>> +               ifTrue: [magnitude > 16r8000000000000000]
>> +               ifFalse: [magnitude >= 16r8000000000000000])
>> +                       ifTrue: [self primitiveFail.
>> +                               ^0].
>> +       negative
>> +               ifTrue: [value := 0 - magnitude]
>> +               ifFalse: [value := magnitude].
>> +       ^value!
>> -       "Filter out values out of range for the signed interpretation
>> such as
>> -       16rFFFFFFFF... (positive w/ bit 64 set) and -16rFFFFFFFF...
>> (negative w/ bit
>> -       64 set). Since the sign is implicit in the class we require that
>> the high bit of
>> -       the magnitude is not set which is a simple test here.  Note that
>> we have to
>> -       handle the most negative 64-bit value -9223372036854775808
>> specially."
>> -       self cCode: []
>> -               inSmalltalk:
>> -                       [(value anyMask: 16r8000000000000000) ifTrue:
>> -                               [value := value - 16r10000000000000000]].
>> -       value < 0 ifTrue:
>> -               [self cCode:
>> -                       [self assert: (self sizeof: value) == 8.
>> -                        self assert: (self sizeof: value << 1) == 8].
>> -               "Don't fail for -9223372036854775808/-16r8000000000000000.
>> -                Alas the simple (negative and: [value - 1 > 0]) isn't
>> adequate since in C the result of signed integer
>> -                overflow is undefined and hence under optimization this
>> may fail.  The shift, however, is well-defined."
>> -                (negative and: [0 = (self cCode: [value << 1]
>> -
>>  inSmalltalk: [value << 1 bitAnd: (1 << 64) - 1])]) ifTrue:
>> -                       [^value].
>> -                self primitiveFail.
>> -                ^0].
>> -       ^negative
>> -               ifTrue:[0 - value]
>> -               ifFalse:[value]!
>>
>> Item was changed:
>>   ----- Method: InterpreterPrimitives>>signedMachineIntegerValueOf: (in
>> category 'primitive support') -----
>>   signedMachineIntegerValueOf: oop
>>         "Answer a signed value of an integer up to the size of a machine
>> word.
>>         The object may be either a positive SmallInteger or a
>> LargeInteger of size <= word size."
>>         <returnTypeC: #'long'>
>> +       | negative ok bs value limit magnitude |
>> -       | negative ok bs value bits |
>>         <var: #value type: #long>
>> +       <var: #magnitude type: #usqInt>
>> +       <var: #limit type: #usqInt>
>>         (objectMemory isIntegerObject: oop) ifTrue:
>>                 [^objectMemory integerValueOf: oop].
>>
>>         (objectMemory isNonIntegerImmediate: oop) ifTrue:
>>                 [^self primitiveFail].
>>
>>         ok := objectMemory isClassOfNonImm: oop
>>                                         equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>>                                         compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>>         ok
>>                 ifTrue: [negative := false]
>>                 ifFalse:
>>                         [negative := true.
>>                          ok := objectMemory isClassOfNonImm: oop
>>                                                         equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>>                         ok ifFalse: [^self primitiveFail]].
>>         bs := objectMemory numBytesOf: oop.
>>         bs > (self sizeof: #'unsigned long') ifTrue:
>>                 [^self primitiveFail].
>>
>>         ((self sizeof: #'unsigned long') = 8
>>         and: [bs > 4]) ifTrue:
>> +               [magnitude := self cppIf: VMBIGENDIAN
>> -               [value := self cppIf: VMBIGENDIAN
>>                                         ifTrue:
>>                                                 [    (objectMemory
>> fetchByte: 0 ofObject: oop)
>>                                                  + ((objectMemory
>> fetchByte: 1 ofObject: oop) <<  8)
>>                                                  + ((objectMemory
>> fetchByte: 2 ofObject: oop) << 16)
>>                                                  + ((objectMemory
>> fetchByte: 3 ofObject: oop) << 24)
>>                                                  + ((objectMemory
>> fetchByte: 4 ofObject: oop) << 32)
>>                                                  + ((objectMemory
>> fetchByte: 5 ofObject: oop) << 40)
>>                                                  + ((objectMemory
>> fetchByte: 6 ofObject: oop) << 48)
>>                                                  + ((objectMemory
>> fetchByte: 7 ofObject: oop) << 56)]
>>                                         ifFalse:
>>                                                 [objectMemory
>> fetchLong64: 0 ofObject: oop]]
>>                 ifFalse:
>> +                       [magnitude := self cppIf: VMBIGENDIAN
>> -                       [value := self cppIf: VMBIGENDIAN
>>                                                 ifTrue:
>>                                                         [
>> (objectMemory fetchByte: 0 ofObject: oop)
>>                                                          + ((objectMemory
>> fetchByte: 1 ofObject: oop) <<  8)
>>                                                          + ((objectMemory
>> fetchByte: 2 ofObject: oop) << 16)
>>                                                          + ((objectMemory
>> fetchByte: 3 ofObject: oop) << 24)]
>>                                                 ifFalse:
>>                                                         [(objectMemory
>> fetchLong32: 0 ofObject: oop) asUnsignedInteger]].
>> +
>> +       limit := 1 asUnsignedInteger << ((self sizeof: #usqInt) * 8 - 1).
>> +       (negative
>> +               ifTrue: [magnitude > limit]
>> +               ifFalse: [magnitude >= limit])
>> +                       ifTrue: [self primitiveFail.
>> +                               ^0].
>> +       negative
>> +               ifTrue: [value := 0 - magnitude]
>> +               ifFalse: [value := magnitude].
>> +       ^value!
>> -
>> -       self cCode: []
>> -               inSmalltalk:
>> -                       [bits := (self sizeof: #long) * 8.
>> -                        (value bitShift: 1 - bits) > 0 ifTrue:
>> -                               [value := value - (1 bitShift: bits)]].
>> -       value < 0 ifTrue:
>> -               ["Don't fail for -16r80000000[00000000].
>> -                 Alas the simple (negative and: [value - 1 > 0]) isn't
>> adequate since in C the result of signed integer
>> -                 overflow is undefined and hence under optimization this
>> may fail.  The shift, however, is well-defined."
>> -                (negative and: [0 = (self cCode: [value << 1]
>> -
>>  inSmalltalk: [value << 1 bitAnd: (1 << bits) - 1])]) ifTrue:
>> -                       [^value].
>> -                ^self primitiveFail].
>> -       ^negative
>> -               ifTrue: [0 - value]
>> -               ifFalse: [value]!
>>
>> Item was changed:
>>   ----- Method: InterpreterProxy>>positive32BitIntegerFor: (in category
>> 'converting') -----
>>   positive32BitIntegerFor: integerValue
>> +       <var: 'integerValue' type: #'unsigned int'>
>>         integerValue isInteger ifFalse:[self error:'Not an Integer
>> object'].
>>         ^integerValue > 0
>>                 ifTrue:[integerValue]
>>                 ifFalse:[ (1 bitShift: 32) + integerValue]!
>>
>> Item was changed:
>>   ----- Method: InterpreterProxy>>positive64BitIntegerFor: (in category
>> 'converting') -----
>>   positive64BitIntegerFor: integerValue
>>         <api>
>>         <returnTypeC: #sqInt> "...because answering the 64-bit argument
>> causes the type inferencer to say this answers 64-bits."
>> +       <var: 'integerValue' type: #usqLong>
>> -       <var: 'integerValue' type: #sqLong>
>>         integerValue isInteger ifFalse:[self error:'Not an Integer
>> object'].
>>         ^integerValue > 0
>>                 ifTrue:[integerValue]
>>                 ifFalse:[ (1 bitShift: 64) + integerValue]!
>>
>> Item was changed:
>>   ----- Method: ObjectMemory>>isIntegerValue: (in category 'interpreter
>> access') -----
>>   isIntegerValue: intValue
>>         "Answer if the given value can be represented as a Smalltalk
>> integer value.
>>          In C, use a shift and XOR to set the sign bit if and only if the
>> top two bits of the given
>>          value are the same, then test the sign bit. Note that the top
>> two bits are equal for
>>          exactly those integers in the range that can be represented in
>> 31-bits or 63-bits."
>>         <api>
>>         ^self
>> +               cCode: [(intValue asUnsignedInteger bitXor: (intValue
>> asUnsignedInteger << 1)) asInteger >= 0]
>> +               inSmalltalk: [intValue >= self minSmallInteger and:
>> [intValue <= self maxSmallInteger]]!
>> -               cCode: [(intValue bitXor: (intValue << 1)) asInteger >= 0]
>> -               inSmalltalk: [intValue >= 16r-40000000 and: [intValue <=
>> 16r3FFFFFFF]]!
>>
>> Item was changed:
>>   ----- Method: Spur32BitMemoryManager>>isIntegerValue: (in category
>> 'interpreter access') -----
>>   isIntegerValue: intValue
>>         "Answer if the given value can be represented as a Smalltalk
>> integer value.
>>          In C, use a shift and XOR to set the sign bit if and only if the
>> top two bits of the given
>>          value are the same, then test the sign bit. Note that the top
>> two bits are equal for
>>          exactly those integers in the range that can be represented in
>> 31-bits or 63-bits."
>>         <api>
>>         ^self
>> +               cCode: [(intValue asUnsignedInteger bitXor: (intValue
>> asUnsignedInteger << 1)) asInteger >= 0]
>> +               inSmalltalk: [intValue >= self minSmallInteger and:
>> [intValue <= self maxSmallInteger]]!
>> -               cCode: [(intValue bitXor: (intValue << 1)) asInteger >= 0]
>> -               inSmalltalk: [intValue >= 16r-40000000 and: [intValue <=
>> 16r3FFFFFFF]]!
>>
>> Item was changed:
>>   ----- Method: Spur64BitMemoryManager>>integerObjectOf: (in category
>> 'immediates') -----
>>   integerObjectOf: value
>>         "Convert the integer value, assumed to be in SmallInteger range,
>> into a tagged SmallInteger object.
>>          In C, use a shift and an add to set the tag bit.
>>          In Smalltalk we have to work harder because the simulator works
>> with strictly positive bit patterns."
>>         <returnTypeC: #sqInt>
>>         ^self
>> +               cCode: [value asUnsignedInteger << self numTagBits + 1]
>> -               cCode: [value << self numTagBits + 1]
>>                 inSmalltalk: [value << self numTagBits
>>                                         + (value >= 0
>>                                                 ifTrue: [1]
>>                                                 ifFalse:
>> [16r10000000000000001])]!
>>
>> Item was changed:
>>   ----- Method: Spur64BitMemoryManager>>isIntegerValue: (in category
>> 'interpreter access') -----
>>   isIntegerValue: intValue
>>         "Answer if the given value can be represented as a Smalltalk
>> integer value.
>>          In 64-bits we use a 3 bit tag which leaves 61 bits for 2's
>> complement signed
>>          integers. In C, use a shift add and mask to test if the top 4
>> bits are all the same.
>>          Since 16rFFFFFFFFFFFFFFFF >> 60 = 16rF the computation intValue
>> >> 60 + 1 bitAnd: 16rF
>>          maps in-range -ve values to 0 and in-range +ve values to 1."
>>         <api>
>>         ^self
>>                 cCode: [(intValue >> 60 + 1 bitAnd: 16rF) <= 1] "N.B.
>> (16rFFFFFFFFFFFFFFFF >> 60) + 1 = 16"
>> +               inSmalltalk: [intValue >= self minSmallInteger and:
>> [intValue <= self maxSmallInteger]]!
>> -               inSmalltalk: [intValue >= -16r1000000000000000 and:
>> [intValue <= 16rFFFFFFFFFFFFFFF]]!
>>
>> Item was changed:
>>   ----- Method: Spur64BitMemoryManager>>rotatedFloatBitsOf: (in category
>> 'interpreter access') -----
>>   rotatedFloatBitsOf: oop
>>         "Answer the signed, but unadjusted value of a SmallFloat64,
>> suitable for use as a hash.
>>          Keeping the exponent unadjusted keeps the value in the
>> SmallInteger range.
>>          See section 61-bit Immediate Floats in the SpurMemoryManager
>> class comment.
>>                                                         msb
>>                                lsb
>>          Decode:
>> [8expsubset][52mantissa][1s][3tags]
>>          shift away tags & sign:        [   0000
>>  ][8expsubset][52mantissa]
>>          add sign:                              [    ssss
>>  ][8expsubset][52mantissa]"
>>         self assert: (self isImmediateFloat: oop).
>>         ^oop asUnsignedInteger >> (self numTagBits + 1)
>>          + ((oop anyMask: self smallFloatSignBit)
>> +               ifTrue: [-1 asUnsignedInteger << (64 - self numTagBits -
>> 1)]
>> -               ifTrue: [-1 << (64 - self numTagBits - 1)]
>>                 ifFalse: [0])!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>maybeInlinePositive32BitIntegerFor: (in
>> category 'primitive support') -----
>>   maybeInlinePositive32BitIntegerFor: integerValue
>>         "N.B. will *not* cause a GC.
>>          integerValue is interpreted as POSITIVE, e.g. as the result of
>> Bitmap>at:."
>>         <notOption: #Spur64BitMemoryManager>
>> +       <var: 'integerValue' type: #'unsigned int'>
>>         | newLargeInteger |
>>         self deny: objectMemory hasSixtyFourBitImmediates.
>> +       integerValue <= objectMemory maxSmallInteger
>> +               ifTrue: [^ objectMemory integerObjectOf: integerValue].
>> -       (integerValue asInteger >= 0
>> -        and: [objectMemory isIntegerValue: integerValue]) ifTrue:
>> -               [^objectMemory integerObjectOf: integerValue].
>>         newLargeInteger := objectMemory
>>
>> eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
>>                                                         format:
>> (objectMemory byteFormatForNumBytes: 4)
>>                                                         numSlots: 1.
>>         self cppIf: VMBIGENDIAN
>>                 ifTrue:
>>                         [objectMemory
>>                                 storeByte: 3 ofObject: newLargeInteger
>> withValue: (integerValue >> 24 bitAnd: 16rFF);
>>                                 storeByte: 2 ofObject: newLargeInteger
>> withValue: (integerValue >> 16 bitAnd: 16rFF);
>>                                 storeByte: 1 ofObject: newLargeInteger
>> withValue: (integerValue >>   8 bitAnd: 16rFF);
>>                                 storeByte: 0 ofObject: newLargeInteger
>> withValue: (integerValue ">> 0" bitAnd: 16rFF)]
>>                 ifFalse:
>>                         [objectMemory storeLong32: 0 ofObject:
>> newLargeInteger withValue: integerValue].
>>         ^newLargeInteger!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>positive32BitIntegerFor: (in category
>> 'primitive support') -----
>>   positive32BitIntegerFor: integerValue
>>         "integerValue is interpreted as POSITIVE, e.g. as the result of
>> Bitmap>at:.
>>          N.B.  Returning in each arm separately enables Slang inlining.
>>          /Don't/ return the ifTrue:ifFalse: unless Slang inlining of
>> conditionals is fixed."
>>         <inline: true>
>> +       <var: 'integerValue' type: #'unsigned int'>
>>         objectMemory hasSixtyFourBitImmediates
>>                 ifTrue:
>>                         [^objectMemory integerObjectOf: (integerValue
>> bitAnd: 16rFFFFFFFF)]
>>                 ifFalse:
>>                         [^self maybeInlinePositive32BitIntegerFor:
>> integerValue]!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>positive64BitIntegerFor: (in category
>> 'primitive support') -----
>>   positive64BitIntegerFor: integerValue
>>         <api>
>> +       <var: 'integerValue' type: #usqLong>
>> +       <var: 'highWord' type: #'unsigned int'>
>> -       <var: 'integerValue' type: #sqLong>
>>         "Answer a Large Positive Integer object for the given integer
>> value.  N.B. will *not* cause a GC."
>>         | newLargeInteger highWord sz |
>>         objectMemory hasSixtyFourBitImmediates
>>                 ifTrue:
>> +                       [integerValue <= objectMemory maxSmallInteger
>> ifTrue:
>> -                       [(integerValue >= 0 and: [objectMemory
>> isIntegerValue: integerValue]) ifTrue:
>>                                 [^objectMemory integerObjectOf:
>> integerValue].
>>                          sz := 8]
>>                 ifFalse:
>> +                       [(highWord := integerValue >> 32) = 0 ifTrue:
>> -                       [(highWord := integerValue >>> 32) = 0 ifTrue:
>>                                 [^self positive32BitIntegerFor:
>> integerValue].
>>                          sz := 5.
>>                          (highWord := highWord >> 8) = 0 ifFalse:
>>                                 [sz := sz + 1.
>>                                  (highWord := highWord >> 8) = 0 ifFalse:
>>                                         [sz := sz + 1.
>>                                          (highWord := highWord >> 8) = 0
>> ifFalse:[sz := sz + 1]]]].
>>         newLargeInteger := objectMemory
>>
>> eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
>>                                                         format:
>> (objectMemory byteFormatForNumBytes: sz)
>>                                                         numSlots: 8 /
>> objectMemory bytesPerOop.
>>         self cppIf: VMBIGENDIAN
>>                 ifTrue:
>>                         [objectMemory
>>                                 storeByte: 7 ofObject: newLargeInteger
>> withValue: (integerValue >> 56 bitAnd: 16rFF);
>>                                 storeByte: 6 ofObject: newLargeInteger
>> withValue: (integerValue >> 48 bitAnd: 16rFF);
>>                                 storeByte: 5 ofObject: newLargeInteger
>> withValue: (integerValue >> 40 bitAnd: 16rFF);
>>                                 storeByte: 4 ofObject: newLargeInteger
>> withValue: (integerValue >> 32 bitAnd: 16rFF);
>>                                 storeByte: 3 ofObject: newLargeInteger
>> withValue: (integerValue >> 24 bitAnd: 16rFF);
>>                                 storeByte: 2 ofObject: newLargeInteger
>> withValue: (integerValue >> 16 bitAnd: 16rFF);
>>                                 storeByte: 1 ofObject: newLargeInteger
>> withValue: (integerValue >>   8 bitAnd: 16rFF);
>>                                 storeByte: 0 ofObject: newLargeInteger
>> withValue: (integerValue ">> 0" bitAnd: 16rFF)]
>>                 ifFalse:
>>                         [objectMemory storeLong64: 0 ofObject:
>> newLargeInteger withValue: integerValue].
>>         ^newLargeInteger
>>   !
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>signed64BitIntegerFor: (in category
>> 'primitive support') -----
>>   signed64BitIntegerFor: integerValue
>>         <var: 'integerValue' type: #sqLong>
>>         "Answer a Large Integer object for the given integer value.  N.B.
>> will *not* cause a GC."
>>         | newLargeInteger magnitude largeClass highWord sz |
>>         <inline: false>
>> +       <var: 'magnitude' type: #usqLong>
>> -       <var: 'magnitude' type: #sqLong>
>>         <var: 'highWord' type: #usqInt>
>>
>> -       objectMemory wordSize = 8 ifTrue:
>> -               [(objectMemory isIntegerValue: integerValue) ifTrue:
>> -                       [^objectMemory integerObjectOf: integerValue].
>> -                sz := 8].
>> -
>>         integerValue < 0
>> +               ifTrue:[        integerValue >= objectMemory
>> minSmallInteger ifTrue: [^objectMemory integerObjectOf: integerValue
>> asInteger].
>> +                               largeClass :=
>> ClassLargeNegativeIntegerCompactIndex.
>> +                               magnitude := 0 - (self cCoerceSimple:
>> integerValue to: #usqLong)]
>> +               ifFalse:[       integerValue <= objectMemory
>> maxSmallInteger ifTrue: [^objectMemory integerObjectOf: integerValue
>> asInteger].
>> +                               largeClass :=
>> ClassLargePositiveIntegerCompactIndex.
>> -               ifTrue:[        largeClass :=
>> ClassLargeNegativeIntegerCompactIndex.
>> -                               magnitude := 0 - integerValue]
>> -               ifFalse:[       largeClass :=
>> ClassLargePositiveIntegerCompactIndex.
>>                                 magnitude := integerValue].
>>
>> +       objectMemory wordSize = 8
>> +               ifTrue: [sz := 8]
>> +               ifFalse: [
>> -       "Make sure to handle the most -ve value correctly. 0 - most -ve =
>> most -ve and most -ve - 1
>> -        is +ve.  Alas the simple (negative or: [integerValue - 1 < 0])
>> fails with contemporary gcc and icc
>> -        versions with optimization and sometimes without.  The shift
>> works on all, touch wood."
>> -
>> -       objectMemory wordSize = 4 ifTrue:
>> -               [(magnitude <= 16r7FFFFFFF
>> -                 and: [integerValue >= 0
>> -                         or: [0 ~= (self cCode: [integerValue << 1]
>> -                                                       inSmalltalk:
>> [integerValue << 1 bitAnd: (1 << 64) - 1])]]) ifTrue:
>> -                               [^self signed32BitIntegerFor:
>> integerValue].
>> -
>>                  (highWord := magnitude >> 32) = 0
>>                         ifTrue: [sz := 4]
>>                         ifFalse:
>>                                 [sz := 5.
>>                                  (highWord := highWord >> 8) = 0 ifFalse:
>>                                         [sz := sz + 1.
>>                                          (highWord := highWord >> 8) = 0
>> ifFalse:
>>                                                 [sz := sz + 1.
>>                                                  (highWord := highWord >>
>> 8) = 0 ifFalse:
>>                                                         [sz := sz +
>> 1]]]]].
>>
>>         newLargeInteger := objectMemory
>>
>> eeInstantiateSmallClassIndex: largeClass
>>                                                         format:
>> (objectMemory byteFormatForNumBytes: sz)
>>                                                         numSlots: sz + 3
>> // objectMemory bytesPerOop.
>>         self cppIf: VMBIGENDIAN
>>                 ifTrue:
>>                         [sz > 4 ifTrue:
>>                                 [objectMemory
>>                                         storeByte: 7 ofObject:
>> newLargeInteger withValue: (magnitude >> 56 bitAnd: 16rFF);
>>                                         storeByte: 6 ofObject:
>> newLargeInteger withValue: (magnitude >> 48 bitAnd: 16rFF);
>>                                         storeByte: 5 ofObject:
>> newLargeInteger withValue: (magnitude >> 40 bitAnd: 16rFF);
>>                                         storeByte: 4 ofObject:
>> newLargeInteger withValue: (magnitude >> 32 bitAnd: 16rFF)].
>>                         objectMemory
>>                                 storeByte: 3 ofObject: newLargeInteger
>> withValue: (magnitude >> 24 bitAnd: 16rFF);
>>                                 storeByte: 2 ofObject: newLargeInteger
>> withValue: (magnitude >> 16 bitAnd: 16rFF);
>>                                 storeByte: 1 ofObject: newLargeInteger
>> withValue: (magnitude >>   8 bitAnd: 16rFF);
>>                                 storeByte: 0 ofObject: newLargeInteger
>> withValue: (magnitude ">> 0" bitAnd: 16rFF)]
>>                 ifFalse:
>> +                       [sz > 4
>> +                               ifTrue: [objectMemory storeLong64: 0
>> ofObject: newLargeInteger withValue: magnitude]
>> +                               ifFalse: [objectMemory storeLong32: 0
>> ofObject: newLargeInteger withValue: (self cCode: [magnitude] inSmalltalk:
>> [magnitude bitAnd: 16rFFFFFFFF])]].
>> -                       [sz > 4 ifTrue:
>> -                               [objectMemory storeLong32: 1 ofObject:
>> newLargeInteger withValue: magnitude >> 32.
>> -                                magnitude := magnitude bitAnd:
>> 16rFFFFFFFF].
>> -                       objectMemory storeLong32: 0 ofObject:
>> newLargeInteger withValue: magnitude].
>>         ^newLargeInteger!
>>
>>
>
>
> --
> _,,,^..^,,,_
> best, Eliot
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160318/9fdfb5f6/attachment-0001.htm


More information about the Vm-dev mailing list