VM Maker: VMMaker.oscog-nice.1813.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-nice.1813.mcz

commits-2
 
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1813.mcz

==================== Summary ====================

Name: VMMaker.oscog-nice.1813
Author: nice
Time: 20 April 2016, 1:02:48.617 am
UUID: 9ce7e2b2-2956-4228-9744-345c61a693ed
Ancestors: VMMaker.oscog-nice.1812

Revert elimination of type specifications for LargeIntegersPlugin.

Instead, provide a bunch of Integer type checking.
- isIntegerObject: <=> isMemberOf: SmallInteger (already existing)
- isKindOfInteger: <=> isKindOf: Integer
- isLargeIntegerObject= <=> isKindOf: LargePositiveInteger (Squeak) or LargeInteger (Pharo)
- isLargePositiveIntegerObject: <=> isMemberOf: LargePositiveInteger
- isLargeNegativeIntegerObject: <=> isMemberOf: LargeNegativeInteger

Note that this will require a change of svn source for platforms/Cross/vm/sqVirtalMachine.[ch]

=============== Diff against VMMaker.oscog-nice.1812 ===============

Item was changed:
  ----- Method: FFIPlugin>>ffiPushUnsignedLongLongOop: (in category 'callout support') -----
  ffiPushUnsignedLongLongOop: oop
  "Push a longlong type (e.g., a 64bit integer).
  Note: Coercions from float are *not* supported."
  | lowWord highWord length ptr |
  <var: #ptr type:'unsigned char *'>
  oop == interpreterProxy nilObject
  ifTrue:[^self ffiPushUnsignedLong: 0 Long: 0.]. "@@: check this"
  oop == interpreterProxy falseObject
  ifTrue:[^self ffiPushUnsignedLong: 0 Long: 0].
  oop == interpreterProxy trueObject
  ifTrue:[^self ffiPushUnsignedLong: 0 Long: 1].
  (interpreterProxy isIntegerObject: oop) ifTrue:[
  lowWord := interpreterProxy integerValueOf: oop.
  lowWord < 0 ifTrue:[^self ffiFail: FFIErrorCoercionFailed].
  highWord := 0.
  ] ifFalse:[
+ (interpreterProxy isLargePositiveIntegerObject: oop)
- (interpreterProxy fetchClassOf: oop) = interpreterProxy classLargePositiveInteger
  ifFalse:[^interpreterProxy primitiveFail].
  (interpreterProxy isBytes: oop) ifFalse:[^self ffiFail: FFIErrorCoercionFailed].
  length := interpreterProxy byteSizeOf: oop.
  length > 8 ifTrue:[^self ffiFail: FFIErrorCoercionFailed].
  lowWord := highWord := 0.
  ptr := interpreterProxy firstIndexableField: oop.
  0 to: (length min: 4)-1 do:[:i|
  lowWord := lowWord + ((ptr at: i) << (i*8))].
  0 to: (length-5) do:[:i|
  highWord := highWord + ((ptr at: i+4) << (i*8))].
  ].
  ^self ffiPushUnsignedLong: lowWord Long: highWord.!

Item was changed:
  ----- Method: IA32ABIPlugin>>primAlienReplace (in category 'primitives-accessing') -----
  primAlienReplace
  "Copy some number of bytes from some source object starting at the index
  into the receiver destination object  from startIndex to stopIndex .  The  source
  and destination may be Aliens or byte-indexable objects.  The primitive wll have either
  of the following signatures:
  <Alien | indexableByteSubclass | indexableWordSubclass>
  primReplaceFrom: start <Integer>
  to: stop <Integer>
  with: replacement <Alien | indexableByteSubclass | indexableWordSubclass | Integer>
  startingAt: repStart <Integer> ^<self>
  <primitive: 'primitiveAlienReplace' error: errorCode module: 'IA32ABI'>
  <Anywhere>
  primReplaceIn: dest <Alien | indexableByteSubclass | indexableWordSubclass>
  from: start <Integer>
  to: stop <Integer>
  with: replacement <Alien | indexableByteSubclass | indexableWordSubclass | Integer>
  startingAt: repStart <Integer> ^<self>
  <primitive: 'primitiveAlienReplace' error: errorCode module: 'IA32ABI'>
  "
  | array start stop repl replStart dest src totalLength count |
  <export: true>
  array := interpreterProxy stackValue: 4.
  start := interpreterProxy stackIntegerValue: 3.
  stop := interpreterProxy stackIntegerValue: 2.
  repl := interpreterProxy stackValue: 1.
  replStart := interpreterProxy stackIntegerValue: 0.
 
  (interpreterProxy failed
  or: [(interpreterProxy isWordsOrBytes: array) not]) ifTrue:
  [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
 
  (self isAlien: array)
  ifTrue:
  [totalLength := self sizeField: array.
  dest := (self startOfData: array withSize: totalLength) + start - 1.
  totalLength = 0 "no bounds checks for zero-sized (pointer) Aliens"
  ifTrue: [totalLength := stop]
  ifFalse: [totalLength := totalLength abs]]
  ifFalse:
  [totalLength := interpreterProxy byteSizeOf: array.
  dest := (self startOfByteData: array) + start - 1].
  (start >= 1 and: [start - 1 <= stop and: [stop <= totalLength]])
  ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex].
 
  (interpreterProxy isIntegerObject: repl)
  ifTrue:
  [(interpreterProxy integerValueOf: repl) <= 0 ifTrue:
  [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  src := (interpreterProxy integerValueOf: repl) + replStart - 1]
  ifFalse:
+ [(interpreterProxy isLargePositiveIntegerObject: repl)
- [(interpreterProxy fetchClassOf: repl) ==  interpreterProxy classLargePositiveInteger
  ifTrue:
  [src := (interpreterProxy positive32BitValueOf: repl) + replStart - 1.
  interpreterProxy failed ifTrue:
  [^interpreterProxy primitiveFailFor: PrimErrBadArgument]]
  ifFalse:
  [(self isAlien: repl)
  ifTrue:
  [totalLength := self sizeField: repl.
  src := (self startOfData: repl withSize: totalLength) + replStart - 1.
  totalLength = 0 "no bounds checks for zero-sized (pointer) Aliens"
  ifTrue: [totalLength := stop - start + replStart]
  ifFalse: [totalLength := totalLength abs]]
  ifFalse:
  [(interpreterProxy isWordsOrBytes: repl) ifFalse:
  [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  totalLength := interpreterProxy byteSizeOf: repl.
  src := (self startOfByteData: repl) + replStart - 1].
  (replStart >= 1 and: [stop - start + replStart <= totalLength]) ifFalse:
  [^interpreterProxy primitiveFailFor: PrimErrBadIndex]]].
 
  (interpreterProxy isOopImmutable: array) ifTrue:
  [^interpreterProxy primitiveFailFor: PrimErrNoModification].
 
  count := stop - start + 1.
  self cCode: 'memmove((void *)dest,(void *)src,count)'
  inSmalltalk:
  [count := count + src + dest. "squash unused var compiler warnings"
  self error: 'not implemented'].
 
  interpreterProxy pop: interpreterProxy methodArgumentCount!

Item was added:
+ ----- Method: Integer class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+
+ ^cg ccgLoad: aBlock expr: aString asKindOfIntegerFrom: anInteger!

Item was added:
+ ----- Method: Interpreter>>isKindOfInteger: (in category 'plugin primitive support') -----
+ isKindOfInteger: oop
+ "Answer true if the oop is kind of Integer (Small or Large)."
+ <api>
+ <inline: true>
+ ^(self isIntegerObject: oop)
+ or: [self isLargeIntegerInstance: oop]!

Item was added:
+ ----- Method: Interpreter>>isLargeIntegerObject: (in category 'plugin primitive support') -----
+ isLargeIntegerObject: oop
+ ^(self isLargeIntegerInstance: oop)!

Item was added:
+ ----- Method: Interpreter>>isLargeNegativeIntegerObject: (in category 'plugin primitive support') -----
+ isLargeNegativeIntegerObject: oop
+ ^(self isInstanceOfClassLargeNegativeInteger: oop)!

Item was added:
+ ----- Method: Interpreter>>isLargePositiveIntegerObject: (in category 'plugin primitive support') -----
+ isLargePositiveIntegerObject: oop
+ ^(self isInstanceOfClassLargePositiveInteger: oop)!

Item was removed:
- ----- Method: InterpreterPrimitives>>isInstanceOfClassLargeNegativeInteger: (in category 'primitive support') -----
- isInstanceOfClassLargeNegativeInteger: oop
- <inline: true>
- "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
- (because is:instanceOf:compactClassIndex: has an inline: pragma) the
- phrase (objectMemory splObj: ClassLargeNegativeInteger) is expanded
- in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
- ^objectMemory
- is: oop
- instanceOf: (objectMemory splObj: ClassLargeNegativeInteger)
- compactClassIndex: ClassLargeNegativeIntegerCompactIndex!

Item was removed:
- ----- Method: InterpreterPrimitives>>isInstanceOfClassLargePositiveInteger: (in category 'primitive support') -----
- isInstanceOfClassLargePositiveInteger: oop
- <inline: true>
- "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
- (because is:instanceOf:compactClassIndex: has an inline: pragma) the
- phrase (objectMemory splObj: ClassLargePositiveInteger) is expanded
- in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
- ^objectMemory
- is: oop
- instanceOf: (objectMemory splObj: ClassLargePositiveInteger)
- compactClassIndex: ClassLargePositiveIntegerCompactIndex!

Item was added:
+ ----- Method: InterpreterProxy>>isKindOfInteger: (in category 'testing') -----
+ isKindOfInteger: objectOrientedPointer
+ ^objectOrientedPointer isInteger!

Item was added:
+ ----- Method: InterpreterProxy>>isLargeIntegerObject: (in category 'testing') -----
+ isLargeIntegerObject: objectOrientedPointer
+ ^objectOrientedPointer isKindOf: LargePositiveInteger!

Item was added:
+ ----- Method: InterpreterProxy>>isLargeNegativeIntegerObject: (in category 'testing') -----
+ isLargeNegativeIntegerObject: objectOrientedPointer
+ ^objectOrientedPointer isMemberOf: LargeNegativeInteger!

Item was added:
+ ----- Method: InterpreterProxy>>isLargePositiveIntegerObject: (in category 'testing') -----
+ isLargePositiveIntegerObject: objectOrientedPointer
+ ^objectOrientedPointer isMemberOf: LargePositiveInteger!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitAddLarge:with: (in category 'oop functions') -----
  digitAddLarge: firstInteger with: secondInteger
  "Does not need to normalize!!"
  | over firstDigitLen secondDigitLen shortInt shortDigitLen longInt longDigitLen sum newSum neg |
  <var: #over type: #'unsigned int'>
  firstDigitLen := self digitSizeOfLargeInt: firstInteger.
  secondDigitLen := self digitSizeOfLargeInt: secondInteger.
+ neg := interpreterProxy isLargeNegativeIntegerObject: firstInteger.
- neg := (interpreterProxy fetchClassOf: firstInteger)
- = interpreterProxy classLargeNegativeInteger.
  firstDigitLen <= secondDigitLen
  ifTrue:
  [shortInt := firstInteger.
  shortDigitLen := firstDigitLen.
  longInt := secondInteger.
  longDigitLen := secondDigitLen]
  ifFalse:
  [shortInt := secondInteger.
  shortDigitLen := secondDigitLen.
  longInt := firstInteger.
  longDigitLen := firstDigitLen].
  " sum := Integer new: len neg: firstInteger negative."
  self remapOop: #(shortInt longInt ) in: [sum := self createLargeIntegerNeg: neg digitLength: longDigitLen].
  over := self
  cDigitAdd: (self pointerToFirstDigitOfLargeInt: shortInt)
  len: shortDigitLen
  with: (self pointerToFirstDigitOfLargeInt: longInt)
  len: longDigitLen
  into: (self pointerToFirstDigitOfLargeInt: sum).
  over > 0
  ifTrue:
  ["sum := sum growby: 1."
  self remapOop: sum in: [newSum := self createLargeIntegerNeg: neg byteLength: longDigitLen * 4 + 1].
  self
  cDigitCopyFrom: (self pointerToFirstDigitOfLargeInt: sum)
  to: (self pointerToFirstDigitOfLargeInt: newSum)
  len: longDigitLen.
  sum := newSum.
  "C index!!"
  self cDigitOf: (self pointerToFirstDigitOfLargeInt: sum)
  at: longDigitLen put: over]
  ifFalse:
  [sum := neg
  ifTrue: [self normalizeNegative: sum]
  ifFalse: [self normalizePositive: sum]].
  ^ sum!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitBitLogic:with:opIndex: (in category 'oop functions') -----
  digitBitLogic: firstInteger with: secondInteger opIndex: opIx
  "Bit logic here is only implemented for positive integers or Zero;
  if rec or arg is negative, it fails."
  | firstLarge secondLarge firstLen secondLen shortLen shortLarge longLen longLarge result |
  (interpreterProxy isIntegerObject: firstInteger)
  ifTrue:
  [(interpreterProxy integerValueOf: firstInteger)
  < 0 ifTrue: [^ interpreterProxy primitiveFail].
  "convert it to a not normalized LargeInteger"
  self remapOop: secondInteger in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
  ifFalse:
+ [(interpreterProxy isLargePositiveIntegerObject: firstInteger) ifFalse: [^ interpreterProxy primitiveFail].
- [(interpreterProxy fetchClassOf: firstInteger)
- = interpreterProxy classLargePositiveInteger ifFalse: [^ interpreterProxy primitiveFail].
  firstLarge := firstInteger].
  (interpreterProxy isIntegerObject: secondInteger)
  ifTrue:
  [(interpreterProxy integerValueOf: secondInteger)
  < 0 ifTrue: [^ interpreterProxy primitiveFail].
  "convert it to a not normalized LargeInteger"
  self remapOop: firstLarge in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
  ifFalse:
+ [(interpreterProxy isLargePositiveIntegerObject: secondInteger) ifFalse: [^ interpreterProxy primitiveFail].
- [(interpreterProxy fetchClassOf: secondInteger)
- = interpreterProxy classLargePositiveInteger ifFalse: [^ interpreterProxy primitiveFail].
  secondLarge := secondInteger].
  firstLen := self byteSizeOfLargeInt: firstLarge.
  secondLen := self byteSizeOfLargeInt: secondLarge.
  firstLen < secondLen
  ifTrue:
  [shortLen := firstLen.
  shortLarge := firstLarge.
  longLen := secondLen.
  longLarge := secondLarge]
  ifFalse:
  [shortLen := secondLen.
  shortLarge := secondLarge.
  longLen := firstLen.
  longLarge := firstLarge].
  self remapOop: #(shortLarge longLarge ) in: [result := interpreterProxy instantiateClass: interpreterProxy classLargePositiveInteger indexableSize: longLen].
  self
  cDigitOp: opIx
  short: (self pointerToFirstDigitOfLargeInt: shortLarge)
  len: shortLen + 3 // 4
  long: (self pointerToFirstDigitOfLargeInt: longLarge)
  len: longLen + 3 // 4
  into: (self pointerToFirstDigitOfLargeInt: result).
  interpreterProxy failed ifTrue: [^ 0].
  ^ self normalizePositive: result!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitSubLarge:with: (in category 'oop functions') -----
  digitSubLarge: firstInteger with: secondInteger
  "Normalizes."
  | firstDigitLen secondDigitLen larger largeDigitLen smaller smallerDigitLen neg resDigitLen res firstNeg |
+ firstNeg := interpreterProxy isLargeNegativeIntegerObject: firstInteger.
- firstNeg := (interpreterProxy fetchClassOf: firstInteger)
- = interpreterProxy classLargeNegativeInteger.
  firstDigitLen := self digitSizeOfLargeInt: firstInteger.
  secondDigitLen := self digitSizeOfLargeInt: secondInteger.
  firstDigitLen = secondDigitLen ifTrue:
  [[firstDigitLen > 1
   and: [(self unsafeDigitOfLargeInt: firstInteger at: firstDigitLen) = (self unsafeDigitOfLargeInt: secondInteger at: firstDigitLen)]]
  whileTrue: [firstDigitLen := firstDigitLen - 1].
  secondDigitLen := firstDigitLen].
  (firstDigitLen < secondDigitLen
  or: [firstDigitLen = secondDigitLen
  and: [(self unsafeDigitOfLargeInt: firstInteger at: firstDigitLen) < (self unsafeDigitOfLargeInt: secondInteger at: firstDigitLen)]])
  ifTrue:
  [larger := secondInteger.
  largeDigitLen := secondDigitLen.
  smaller := firstInteger.
  smallerDigitLen := firstDigitLen.
  neg := firstNeg == false]
  ifFalse:
  [larger := firstInteger.
  largeDigitLen := firstDigitLen.
  smaller := secondInteger.
  smallerDigitLen := secondDigitLen.
  neg := firstNeg].
  resDigitLen := largeDigitLen.
  self remapOop: #(smaller larger)
  in: [res := self createLargeIntegerNeg: neg digitLength: resDigitLen].
  self
  cDigitSub: (self pointerToFirstDigitOfLargeInt: smaller)
  len: smallerDigitLen
  with: (self pointerToFirstDigitOfLargeInt: larger)
  len: largeDigitLen
  into: (self pointerToFirstDigitOfLargeInt: res).
  ^neg
  ifTrue: [self normalizeNegative: res]
  ifFalse: [self normalizePositive: res]!

Item was removed:
- ----- Method: LargeIntegersPlugin>>isLargeIntegerOop: (in category 'util') -----
- isLargeIntegerOop: oop
- | oopClass |
- oopClass := interpreterProxy fetchClassOf: oop.
- ^oopClass == interpreterProxy classLargeNegativeInteger or: [oopClass == interpreterProxy classLargePositiveInteger]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>normalize: (in category 'oop functions') -----
  normalize: aLargeInteger
  "Check for leading zeroes and return shortened copy if so."
  self debugCode: [self msg: 'normalize: aLargeInteger'].
+ (interpreterProxy isLargePositiveIntegerObject: aLargeInteger)
- (interpreterProxy fetchClassOf: aLargeInteger)
- = interpreterProxy classLargePositiveInteger
  ifTrue: [^ self normalizePositive: aLargeInteger]
  ifFalse: [^ self normalizeNegative: aLargeInteger]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primAnyBitFrom:to: (in category 'Integer primitives') -----
  primAnyBitFrom: from to: to
  | integer large |
  self debugCode: [self msg: 'primAnyBitFrom: from to: to'].
  integer := self
  primitive: 'primAnyBitFromTo'
+ parameters: #(#SmallInteger #SmallInteger )
+ receiver: #Integer.
- parameters: #(#SmallInteger #SmallInteger ).
  (interpreterProxy isIntegerObject: integer)
  ifTrue: ["convert it to a not normalized LargeInteger"
  large := self createLargeFromSmallInteger: integer]
+ ifFalse: [large := integer].
- ifFalse:
- [(self isLargeIntegerOop: integer) ifFalse: [^interpreterProxy primitiveFail].
- large := integer].
  ^ (self
  anyBitOfLargeInt: large
  from: from
  to: to)
  asOop: Boolean!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitAdd: (in category 'Integer primitives') -----
  primDigitAdd: secondInteger
  | firstLarge secondLarge firstInteger |
  self debugCode: [self msg: 'primDigitAdd: secondInteger'].
+ firstInteger := self
+ primitive: 'primDigitAdd'
+ parameters: #(Integer )
+ receiver: #Integer.
- firstInteger := self primitive: 'primDigitAdd'.
  (interpreterProxy isIntegerObject: firstInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self remapOop: secondInteger in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+ ifFalse: [firstLarge := firstInteger].
- ifFalse:
- [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
- firstLarge := firstInteger].
  (interpreterProxy isIntegerObject: secondInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self remapOop: firstLarge in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
+ ifFalse: [secondLarge := secondInteger].
- ifFalse:
- [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail].
- secondLarge := secondInteger].
  ^ self digitAddLarge: firstLarge with: secondLarge!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitAnd: (in category 'Integer primitives') -----
  primDigitBitAnd: secondInteger
  "Bit logic here is only implemented for positive integers or Zero; if rec
  or arg is negative, it fails."
  | firstInteger |
  self debugCode: [self msg: 'primDigitBitAnd: secondInteger'].
+ firstInteger := self
+ primitive: 'primDigitBitAnd'
+ parameters: #(Integer )
+ receiver: #Integer.
- firstInteger := self primitive: 'primDigitBitAnd'.
  ^ self
  digitBitLogic: firstInteger
  with: secondInteger
  opIndex: andOpIndex!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitOr: (in category 'Integer primitives') -----
  primDigitBitOr: secondInteger
  "Bit logic here is only implemented for positive integers or Zero; if rec
  or arg is negative, it fails."
  | firstInteger |
  self debugCode: [self msg: 'primDigitBitOr: secondInteger'].
+ firstInteger := self
+ primitive: 'primDigitBitOr'
+ parameters: #(Integer )
+ receiver: #Integer.
- firstInteger := self primitive: 'primDigitBitOr'.
  ^ self
  digitBitLogic: firstInteger
  with: secondInteger
  opIndex: orOpIndex!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitShiftMagnitude: (in category 'Integer primitives') -----
  primDigitBitShiftMagnitude: shiftCount
  | rShift aLarge anInteger |
  self debugCode: [self msg: 'primDigitBitShiftMagnitude: shiftCount'].
  anInteger := self
  primitive: 'primDigitBitShiftMagnitude'
+ parameters: #(#SmallInteger )
+ receiver: #Integer.
- parameters: #(#SmallInteger ).
  (interpreterProxy isIntegerObject: anInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  aLarge := self createLargeFromSmallInteger: anInteger]
+ ifFalse: [aLarge := anInteger].
- ifFalse:
- [(self isLargeIntegerOop: anInteger) ifFalse: [^interpreterProxy primitiveFail].
- aLarge := anInteger].
  shiftCount >= 0
  ifTrue: [^ self digit: aLarge Lshift: shiftCount]
  ifFalse:
  [rShift := 0 - shiftCount.
  ^ self normalize: (self
  digit: aLarge
  Rshift: rShift
  lookfirst: (self digitSizeOfLargeInt: aLarge))]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitXor: (in category 'Integer primitives') -----
  primDigitBitXor: secondInteger
  "Bit logic here is only implemented for positive integers or Zero; if rec
  or arg is negative, it fails."
  | firstInteger |
  self debugCode: [self msg: 'primDigitBitXor: secondInteger'].
+ firstInteger := self
+ primitive: 'primDigitBitXor'
+ parameters: #(Integer )
+ receiver: #Integer.
- firstInteger := self primitive: 'primDigitBitXor'.
  ^ self
  digitBitLogic: firstInteger
  with: secondInteger
  opIndex: xorOpIndex!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitCompare: (in category 'Integer primitives') -----
  primDigitCompare: secondInteger
+ | firstVal secondVal firstInteger |
- | firstVal secondVal firstInteger firstIsSmall secondIsSmall |
  self debugCode: [self msg: 'primDigitCompare: secondInteger'].
+ firstInteger := self
+ primitive: 'primDigitCompare'
+ parameters: #(#Integer )
+ receiver: #Integer.
- firstInteger := self primitive: 'primDigitCompare'.
  "shortcut: aSmallInteger has to be smaller in Magnitude as aLargeInteger"
+ (interpreterProxy isIntegerObject: firstInteger)
+ ifTrue: ["first"
+ (interpreterProxy isIntegerObject: secondInteger)
+ ifTrue: ["second"
+ (firstVal := interpreterProxy integerValueOf: firstInteger) > (secondVal := interpreterProxy integerValueOf: secondInteger)
- firstIsSmall := interpreterProxy isIntegerObject: firstInteger.
- secondIsSmall := interpreterProxy isIntegerObject: secondInteger.
- firstIsSmall ifFalse: [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail]].
- secondIsSmall ifFalse: [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail]].
- firstIsSmall
- ifTrue:
- [secondIsSmall
- ifTrue:
- [(firstVal := interpreterProxy integerValueOf: firstInteger) > (secondVal := interpreterProxy integerValueOf: secondInteger)
  ifTrue: [^ 1 asOop: SmallInteger"first > second"]
  ifFalse: [firstVal < secondVal
  ifTrue: [^ -1 asOop: SmallInteger"first < second"]
  ifFalse: [^ 0 asOop: SmallInteger"first = second"]]]
+ ifFalse: ["SECOND"
+ ^ -1 asOop: SmallInteger"first < SECOND"]]
+ ifFalse: ["FIRST"
+ (interpreterProxy isIntegerObject: secondInteger)
+ ifTrue: ["second"
+ ^ 1 asOop: SmallInteger"FIRST > second"]
+ ifFalse: ["SECOND"
+ ^ self digitCompareLarge: firstInteger with: secondInteger]]!
- ifFalse:
- [^ -1 asOop: SmallInteger"first < SECOND"]]
- ifFalse:
- [secondIsSmall
- ifTrue:
- [^ 1 asOop: SmallInteger"FIRST > second"]
- ifFalse:
- [^ self digitCompareLarge: firstInteger with: secondInteger]]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitDiv:negative: (in category 'Integer primitives') -----
  primDigitDiv: secondInteger negative: neg
  "Answer the result of dividing firstInteger by secondInteger.
  Fail if parameters are not integers, not normalized or secondInteger is
  zero. "
  | firstAsLargeInteger secondAsLargeInteger firstInteger |
  self debugCode: [self msg: 'primDigitDiv: secondInteger negative: neg'].
  firstInteger := self
  primitive: 'primDigitDivNegative'
+ parameters: #(#Integer #Boolean )
+ receiver: #Integer.
- parameters: #(#Oop #Boolean ).
  "Coerce SmallIntegers to corresponding (not normalized) large integers  
  and check for zerodivide."
  (interpreterProxy isIntegerObject: firstInteger)
+ ifTrue: ["convert to LargeInteger"
- ifTrue:
- ["convert to LargeInteger"
  self
  remapOop: secondInteger
  in: [firstAsLargeInteger := self createLargeFromSmallInteger: firstInteger]]
  ifFalse:
+ ["Avoid crashes in case of getting unnormalized args."
+ (self isNormalized: firstInteger)
+ ifFalse:
+ [self debugCode:
+ [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
+ self msg: '------> receiver *not* normalized!!'].
+ ^ interpreterProxy primitiveFail].
+ firstAsLargeInteger := firstInteger].
- [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
- "Avoid crashes in case of getting unnormalized args."
- (self isNormalized: firstInteger) ifFalse: [self
- debugCode: [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
- self msg: '------> receiver *not* normalized!!'].
- ^ interpreterProxy primitiveFail].firstAsLargeInteger := firstInteger].
  (interpreterProxy isIntegerObject: secondInteger)
+ ifTrue: ["check for zerodivide and convert to LargeInteger"
+ (interpreterProxy integerValueOf: secondInteger)
+ = 0
- ifTrue:
- ["check for zerodivide and convert to LargeInteger"
- (interpreterProxy integerValueOf: secondInteger) = 0
  ifTrue: [^ interpreterProxy primitiveFail].
  self
  remapOop: firstAsLargeInteger
  in: [secondAsLargeInteger := self createLargeFromSmallInteger: secondInteger]]
  ifFalse:
+ ["Avoid crashes in case of getting unnormalized args."
+ (self isNormalized: secondInteger)
+ ifFalse:
+ [self debugCode:
+ [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
+ self msg: '------> argument *not* normalized!!'].
+ ^ interpreterProxy primitiveFail].
- [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail].
- (self isNormalized: secondInteger) ifFalse: [self
- debugCode: [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
- self msg: '------> argument *not* normalized!!'].
- ^ interpreterProxy primitiveFail].
  secondAsLargeInteger := secondInteger].
  ^ self
  digitDivLarge: firstAsLargeInteger
  with: secondAsLargeInteger
  negative: neg!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitMultiply:negative: (in category 'Integer primitives') -----
  primDigitMultiply: secondInteger negative: neg
  | firstLarge secondLarge firstInteger |
  self debugCode: [self msg: 'primDigitMultiply: secondInteger negative: neg'].
  firstInteger := self
  primitive: 'primDigitMultiplyNegative'
+ parameters: #(#Integer #Boolean )
+ receiver: #Integer.
- parameters: #(#Oop #Boolean ).
  (interpreterProxy isIntegerObject: firstInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self
  remapOop: secondInteger
  in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+ ifFalse: [firstLarge := firstInteger].
- ifFalse:
- [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
- firstLarge := firstInteger].
  (interpreterProxy isIntegerObject: secondInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self
  remapOop: firstLarge
  in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
+ ifFalse: [secondLarge := secondInteger].
- ifFalse:
- [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail].
- secondLarge := secondInteger].
  ^ self
  digitMultiplyLarge: firstLarge
  with: secondLarge
  negative: neg!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitSubtract: (in category 'Integer primitives') -----
  primDigitSubtract: secondInteger
  | firstLarge secondLarge firstInteger |
  self debugCode: [self msg: 'primDigitSubtract: secondInteger'].
+ firstInteger := self
+ primitive: 'primDigitSubtract'
+ parameters: #(#Integer )
+ receiver: #Integer.
- firstInteger := self primitive: 'primDigitSubtract'.
  (interpreterProxy isIntegerObject: firstInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self
  remapOop: secondInteger
  in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+ ifFalse: [firstLarge := firstInteger].
- ifFalse:
- [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
- firstLarge := firstInteger].
  (interpreterProxy isIntegerObject: secondInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self
  remapOop: firstLarge
  in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
+ ifFalse: [secondLarge := secondInteger].
- ifFalse:
- [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
- secondLarge := secondInteger].
  ^ self digitSubLarge: firstLarge with: secondLarge!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primMontgomeryDigitLength (in category 'Integer primitives') -----
  primMontgomeryDigitLength
  self debugCode: [self msg: 'primMontgomeryDigitLength'].
+ self
+ primitive: 'primMontgomeryDigitLength'
+ parameters: #()
+ receiver: #Integer.
- self primitive: 'primMontgomeryDigitLength'.
  ^interpreterProxy integerObjectOf: 32!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primMontgomeryTimes:modulo:mInvModB: (in category 'Integer primitives') -----
  primMontgomeryTimes: secondOperandInteger modulo: thirdModuloInteger mInvModB: mInverseInteger
  | firstLarge secondLarge firstInteger thirdLarge mInv |
  <var: #mInv type: #'unsigned int'>
  self debugCode: [self msg: 'montgomeryTimes: secondOperandInteger modulo: thirdModuloInteger mInvModB: smallInverseInteger'].
+ firstInteger := self
+ primitive: 'primMontgomeryTimesModulo'
+ parameters: #(Integer Integer Integer )
+ receiver: #Integer.
+ mInv := interpreterProxy positive32BitValueOf: mInverseInteger.
- firstInteger := self primitive: 'primMontgomeryTimesModulo'.
- mInv := interpreterProxy positive32BitValueOf: mInverseInteger.
  (interpreterProxy isIntegerObject: firstInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self remapOop: #(secondOperandInteger thirdModuloInteger) in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+ ifFalse: [firstLarge := firstInteger].
- ifFalse:
- [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
- firstLarge := firstInteger].
  (interpreterProxy isIntegerObject: secondOperandInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self remapOop: #(firstLarge thirdModuloInteger) in: [secondLarge := self createLargeFromSmallInteger: secondOperandInteger]]
+ ifFalse: [secondLarge := secondOperandInteger].
- ifFalse:
- [(self isLargeIntegerOop: secondOperandInteger) ifFalse: [^interpreterProxy primitiveFail].
- secondLarge := secondOperandInteger].
  (interpreterProxy isIntegerObject: thirdModuloInteger)
+ ifTrue: ["convert it to a not normalized LargeInteger"
- ifTrue:
- ["convert it to a not normalized LargeInteger"
  self remapOop: #(firstLarge secondLarge) in: [thirdLarge := self createLargeFromSmallInteger: thirdModuloInteger]]
+ ifFalse: [thirdLarge := thirdModuloInteger].
- ifFalse:
- [(self isLargeIntegerOop: thirdModuloInteger) ifFalse: [^interpreterProxy primitiveFail].
- thirdLarge := thirdModuloInteger].
  ^ self digitMontgomery: firstLarge times: secondLarge modulo: thirdLarge mInvModB: mInv!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primNormalizeNegative (in category 'Integer primitives') -----
  primNormalizeNegative
  | rcvr |
  self debugCode: [self msg: 'primNormalizeNegative'].
+ rcvr := self
+ primitive: 'primNormalizeNegative'
+ parameters: #()
+ receiver: #LargeNegativeInteger.
- rcvr := self primitive: 'primNormalizeNegative'.
- (interpreterProxy fetchClassOf: rcvr) == interpreterProxy classLargeNegativeInteger ifFalse: [^interpreterProxy primitiveFail].
  ^ self normalizeNegative: rcvr!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primNormalizePositive (in category 'Integer primitives') -----
  primNormalizePositive
  | rcvr |
  self debugCode: [self msg: 'primNormalizePositive'].
+ rcvr := self
+ primitive: 'primNormalizePositive'
+ parameters: #()
+ receiver: #LargePositiveInteger.
- rcvr := self primitive: 'primNormalizePositive'.
- (interpreterProxy fetchClassOf: rcvr) == interpreterProxy classLargePositiveInteger ifFalse: [^interpreterProxy primitiveFail].
  ^ self normalizePositive: rcvr!

Item was added:
+ ----- Method: LargeNegativeInteger class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+
+ ^cg ccgLoad: aBlock expr: aString asMemberOfLargeNegativeIntegerFrom: anInteger!

Item was added:
+ ----- Method: LargePositiveInteger class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+
+ ^cg ccgLoad: aBlock expr: aString asMemberOfLargePositiveIntegerFrom: anInteger!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isKindOfInteger: (in category 'simulation only') -----
+ isKindOfInteger: offset
+ ^coInterpreter isKindOfInteger: offset!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isLargeIntegerObject: (in category 'simulation only') -----
+ isLargeIntegerObject: offset
+ ^coInterpreter isLargeIntegerObject: offset!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isLargeNegativeIntegerObject: (in category 'simulation only') -----
+ isLargeNegativeIntegerObject: offset
+ ^coInterpreter isLargeNegativeIntegerObject: offset!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isLargePositiveIntegerObject: (in category 'simulation only') -----
+ isLargePositiveIntegerObject: offset
+ ^coInterpreter isLargePositiveIntegerObject: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isKindOfInteger: (in category 'simulation only') -----
+ isKindOfInteger: offset
+ ^coInterpreter isKindOfInteger: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isLargeIntegerObject: (in category 'simulation only') -----
+ isLargeIntegerObject: offset
+ ^coInterpreter isLargeIntegerObject: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isLargeNegativeIntegerObject: (in category 'simulation only') -----
+ isLargeNegativeIntegerObject: offset
+ ^coInterpreter isLargeNegativeIntegerObject: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isLargePositiveIntegerObject: (in category 'simulation only') -----
+ isLargePositiveIntegerObject: offset
+ ^coInterpreter isLargePositiveIntegerObject: offset!

Item was changed:
  ----- Method: ObjectMemory>>cCoerceSimple:to: (in category 'simulation support') -----
  cCoerceSimple: value to: cTypeString
  <doNotGenerate>
  ^cTypeString caseOf:
+   { [#'char *'] -> [value].
+ [#'unsigned int'] -> [value]. }!
-   { [#'char *'] -> [value] }!

Item was added:
+ ----- Method: ObjectMemory>>isInstanceOfClassLargeNegativeInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargeNegativeInteger: oop
+ <inline: true>
+ "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
+ (because is:instanceOf:compactClassIndex: has an inline: pragma) the
+ phrase (objectMemory splObj: ClassLargeNegativeInteger) is expanded
+ in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
+ ^self
+ is: oop
+ instanceOf: (self splObj: ClassLargeNegativeInteger)
+ compactClassIndex: ClassLargeNegativeIntegerCompactIndex!

Item was added:
+ ----- Method: ObjectMemory>>isInstanceOfClassLargePositiveInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargePositiveInteger: oop
+ <inline: true>
+ "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
+ (because is:instanceOf:compactClassIndex: has an inline: pragma) the
+ phrase (objectMemory splObj: ClassLargePositiveInteger) is expanded
+ in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
+ ^self
+ is: oop
+ instanceOf: (self splObj: ClassLargePositiveInteger)
+ compactClassIndex: ClassLargePositiveIntegerCompactIndex!

Item was added:
+ ----- Method: ObjectMemory>>isLargeIntegerInstance: (in category 'interpreter access') -----
+ isLargeIntegerInstance: oop
+ <inline: true>
+ ^(self isInstanceOfClassLargePositiveInteger: oop)
+ or: [self isInstanceOfClassLargeNegativeInteger: oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asKindOfIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asKindOfIntegerFrom: anInteger
+
+ ^String streamContents: [:aStream | aStream
+ nextPutAll: 'interpreterProxy success: (interpreterProxy isKindOfInteger: (interpreterProxy stackValue: ';
+ nextPutAll: anInteger asString;
+ nextPutAll: ')).';
+ crtab;
+ nextPutAll: (self
+ ccgLoad: aBlock
+ expr: aString
+ asRawOopFrom: anInteger)]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asMemberOfLargeNegativeIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargeNegativeIntegerFrom: anInteger
+
+ ^String streamContents: [:aStream | aStream
+ nextPutAll: 'interpreterProxy success: (interpreterProxy isLargeNegativeIntegerObject: (interpreterProxy stackValue: ';
+ nextPutAll: anInteger asString;
+ nextPutAll: ')).';
+ crtab;
+ nextPutAll: (self
+ ccgLoad: aBlock
+ expr: aString
+ asRawOopFrom: anInteger)]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asMemberOfLargePositiveIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargePositiveIntegerFrom: anInteger
+
+ ^String streamContents: [:aStream | aStream
+ nextPutAll: 'interpreterProxy success: (interpreterProxy isLargePositiveIntegerObject: (interpreterProxy stackValue: ';
+ nextPutAll: anInteger asString;
+ nextPutAll: ')).';
+ crtab;
+ nextPutAll: (self
+ ccgLoad: aBlock
+ expr: aString
+ asRawOopFrom: anInteger)]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asKindOfIntegerFrom: (in category 'simulation') -----
+ ccgLoad: forProlog expr: failBlock asKindOfIntegerFrom: argIndexOrNil
+ ^[:oop|
+   interpreterProxy success: (interpreterProxy isKindOfInteger: oop).
+   oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asMemberOfLargeNegativeIntegerFrom: (in category 'simulation') -----
+ ccgLoad: forProlog expr: failBlock asMemberOfLargeNegativeIntegerFrom: argIndexOrNil
+ ^[:oop|
+   interpreterProxy success: (interpreterProxy isLargeNegativeIntegerObject: oop).
+   oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asMemberOfLargePositiveIntegerFrom: (in category 'simulation') -----
+ ccgLoad: forProlog expr: failBlock asMemberOfLargePositiveIntegerFrom: argIndexOrNil
+ ^[:oop|
+   interpreterProxy success: (interpreterProxy isLargePositiveIntegerObject: oop).
+   oop]!

Item was added:
+ ----- Method: SpurMemoryManager>>isInstanceOfClassLargeNegativeInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargeNegativeInteger: oop
+ "Answer if the oop is a large negative integer instance."
+ ^(self isNonImmediate: oop) and: [(self classIndexOf: oop) = ClassLargeNegativeIntegerCompactIndex]!

Item was added:
+ ----- Method: SpurMemoryManager>>isInstanceOfClassLargePositiveInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargePositiveInteger: oop
+ "Answer if the oop is a large positive integer instance."
+ ^(self isNonImmediate: oop) and: [(self classIndexOf: oop) = ClassLargePositiveIntegerCompactIndex]!

Item was added:
+ ----- Method: SpurMemoryManager>>isLargeIntegerInstance: (in category 'interpreter access') -----
+ isLargeIntegerInstance: oop
+ "Answer if the oop is a large positive or negative integer instance."
+ ^(self isNonImmediate: oop) and: [((self classIndexOf: oop) - ClassLargeNegativeIntegerCompactIndex) asUnsignedInteger <= 1]!

Item was added:
+ ----- Method: StackInterpreter>>isKindOfInteger: (in category 'internal interpreter access') -----
+ isKindOfInteger: oop
+ "Answer true if the oop is kind of Integer (Small or Large)."
+ <api>
+ <inline: true>
+ ^(objectMemory isIntegerObject: oop)
+ or: [objectMemory isLargeIntegerInstance: oop]!

Item was added:
+ ----- Method: StackInterpreter>>isLargeIntegerObject: (in category 'internal interpreter access') -----
+ isLargeIntegerObject: oop
+ <api>
+ <inline: true>
+ ^objectMemory isLargeIntegerInstance: oop!

Item was added:
+ ----- Method: StackInterpreter>>isLargeNegativeIntegerObject: (in category 'internal interpreter access') -----
+ isLargeNegativeIntegerObject: oop
+ <api>
+ <inline: true>
+ ^objectMemory isInstanceOfClassLargeNegativeInteger: oop!

Item was added:
+ ----- Method: StackInterpreter>>isLargePositiveIntegerObject: (in category 'internal interpreter access') -----
+ isLargePositiveIntegerObject: oop
+ <api>
+ <inline: true>
+ ^objectMemory isInstanceOfClassLargePositiveInteger: oop!

Item was changed:
  ----- Method: StackInterpreter>>printStringOf: (in category 'debug printing') -----
  printStringOf: oop
  | fmt len cnt max i |
  <inline: false>
  (objectMemory isImmediate: oop) ifTrue:
  [^self].
  (objectMemory addressCouldBeObj: oop) ifFalse:
  [^self].
  fmt := objectMemory formatOf: oop.
  fmt < objectMemory firstByteFormat ifTrue: [^self].
 
  cnt := (max := 128) min: (len := objectMemory lengthOf: oop).
  i := 0.
 
  ((objectMemory is: oop
   instanceOf: (objectMemory splObj: ClassByteArray)
   compactClassIndex: classByteArrayCompactIndex)
+ or: [(objectMemory isLargeIntegerInstance: oop)])
- or: [(self isInstanceOfClassLargePositiveInteger: oop)
- or: [(self isInstanceOfClassLargeNegativeInteger: oop)]])
  ifTrue:
  [[i < cnt] whileTrue:
  [self printHex: (objectMemory fetchByte: i ofObject: oop).
  i := i + 1]]
  ifFalse:
  [[i < cnt] whileTrue:
  [self cCode:
  [(objectMemory fetchByte: i ofObject: oop) = 13 "Character cr asInteger" ifTrue:
  [self print: '<CR>'.
  i + 1 < len ifTrue:
  [self print: '...'].
  ^self]].
  self printChar: (objectMemory fetchByte: i ofObject: oop).
  i := i + 1]].
  len > max ifTrue:
  [self print: '...'].
  self flush!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>ffiIntegerValueOf: (in category 'callout support') -----
  ffiIntegerValueOf: oop
  "Support for generic callout. Answer an integer value that is coerced as C would do."
  <inline: true>
  "Cheat with a tag test"
  (oop anyMask: BytesPerWord - 1)
  ifTrue:
  [(interpreterProxy isIntegerObject: oop) ifTrue:
  [^interpreterProxy integerValueOf: oop].
  self cppIf: SPURVM
  ifTrue:
  [(interpreterProxy isCharacterObject: oop) ifTrue: "Immediate in Spur"
  [^interpreterProxy characterValueOf: oop].
  (interpreterProxy isFloatObject: oop) ifTrue: "Immediate in 64-bit Spur"
  [^interpreterProxy floatValueOf: oop]]]
  ifFalse:
  [self cppIf: SPURVM
  ifTrue: "No non-immediate characters in Spur"
  []
  ifFalse:
  [(interpreterProxy isCharacterObject: oop) ifTrue:
  [^interpreterProxy characterValueOf: oop]].
  (interpreterProxy isFloatObject: oop) ifTrue:
  [^interpreterProxy floatValueOf: oop].
  oop = interpreterProxy nilObject ifTrue: [^0]. "@@: should we really allow this????"
  oop = interpreterProxy falseObject ifTrue: [^0].
  oop = interpreterProxy trueObject ifTrue: [^1].
+ (interpreterProxy isLargePositiveIntegerObject: oop) ifTrue:
- (interpreterProxy fetchClassOf: oop) = interpreterProxy classLargePositiveInteger ifTrue:
  [self cppIf: BytesPerWord = 8 "Use cppIf: to get the return type of the function right.  Should be sqInt on 32-bits."
  ifTrue: [^interpreterProxy positive64BitValueOf: oop]
  ifFalse: [^interpreterProxy positive32BitValueOf: oop]]].
  ^interpreterProxy signedMachineIntegerValueOf: oop "<- will fail if not integer"!

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.1813.mcz

Nicolas Cellier
 
As suggested by Eliot, the class checks could be defined as macros in the plugin preamble (if internal plugin and if SPURVM...), but this should also be the case of many other vm api selectors (like isIntegerObject: etc...).

As suggested by Levente, this could as well be generalized by link time optimization options of clang/gcc (-flto)...
Or by aggregating vm and internal plugins into a single source file.
We'll see later.

2016-04-20 1:04 GMT+02:00 <[hidden email]>:

Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1813.mcz

==================== Summary ====================

Name: VMMaker.oscog-nice.1813
Author: nice
Time: 20 April 2016, 1:02:48.617 am
UUID: 9ce7e2b2-2956-4228-9744-345c61a693ed
Ancestors: VMMaker.oscog-nice.1812

Revert elimination of type specifications for LargeIntegersPlugin.

Instead, provide a bunch of Integer type checking.
- isIntegerObject: <=> isMemberOf: SmallInteger (already existing)
- isKindOfInteger: <=> isKindOf: Integer
- isLargeIntegerObject= <=> isKindOf: LargePositiveInteger (Squeak) or LargeInteger (Pharo)
- isLargePositiveIntegerObject: <=> isMemberOf: LargePositiveInteger
- isLargeNegativeIntegerObject: <=> isMemberOf: LargeNegativeInteger

Note that this will require a change of svn source for platforms/Cross/vm/sqVirtalMachine.[ch]

=============== Diff against VMMaker.oscog-nice.1812 ===============

Item was changed:
  ----- Method: FFIPlugin>>ffiPushUnsignedLongLongOop: (in category 'callout support') -----
  ffiPushUnsignedLongLongOop: oop
        "Push a longlong type (e.g., a 64bit integer).
        Note: Coercions from float are *not* supported."
        | lowWord highWord length ptr |
        <var: #ptr type:'unsigned char *'>
        oop == interpreterProxy nilObject
                ifTrue:[^self ffiPushUnsignedLong: 0 Long: 0.]. "@@: check this"
        oop == interpreterProxy falseObject
                ifTrue:[^self ffiPushUnsignedLong: 0 Long: 0].
        oop == interpreterProxy trueObject
                ifTrue:[^self ffiPushUnsignedLong: 0 Long: 1].
        (interpreterProxy isIntegerObject: oop) ifTrue:[
                lowWord := interpreterProxy integerValueOf: oop.
                lowWord < 0 ifTrue:[^self ffiFail: FFIErrorCoercionFailed].
                highWord := 0.
        ] ifFalse:[
+               (interpreterProxy isLargePositiveIntegerObject: oop)
-               (interpreterProxy fetchClassOf: oop) = interpreterProxy classLargePositiveInteger
                        ifFalse:[^interpreterProxy primitiveFail].
                (interpreterProxy isBytes: oop) ifFalse:[^self ffiFail: FFIErrorCoercionFailed].
                length := interpreterProxy byteSizeOf: oop.
                length > 8 ifTrue:[^self ffiFail: FFIErrorCoercionFailed].
                lowWord := highWord := 0.
                ptr := interpreterProxy firstIndexableField: oop.
                0 to: (length min: 4)-1 do:[:i|
                        lowWord := lowWord + ((ptr at: i) << (i*8))].
                0 to: (length-5) do:[:i|
                        highWord := highWord + ((ptr at: i+4) << (i*8))].
        ].
        ^self ffiPushUnsignedLong: lowWord Long: highWord.!

Item was changed:
  ----- Method: IA32ABIPlugin>>primAlienReplace (in category 'primitives-accessing') -----
  primAlienReplace
        "Copy some number of bytes from some source object starting at the index
         into the receiver destination object  from startIndex to stopIndex .  The  source
         and destination may be Aliens or byte-indexable objects.  The primitive wll have either
        of the following signatures:
        <Alien | indexableByteSubclass | indexableWordSubclass>
                primReplaceFrom: start <Integer>
                to: stop <Integer>
                with: replacement <Alien | indexableByteSubclass | indexableWordSubclass | Integer>
                startingAt: repStart <Integer> ^<self>
                <primitive: 'primitiveAlienReplace' error: errorCode module: 'IA32ABI'>
        <Anywhere>
                primReplaceIn: dest <Alien | indexableByteSubclass | indexableWordSubclass>
                from: start <Integer>
                to: stop <Integer>
                with: replacement <Alien | indexableByteSubclass | indexableWordSubclass | Integer>
                startingAt: repStart <Integer> ^<self>
                <primitive: 'primitiveAlienReplace' error: errorCode module: 'IA32ABI'>
        "
        | array start stop repl replStart dest src totalLength count |
        <export: true>
        array := interpreterProxy stackValue: 4.
        start := interpreterProxy stackIntegerValue: 3.
        stop := interpreterProxy stackIntegerValue: 2.
        repl := interpreterProxy stackValue: 1.
        replStart := interpreterProxy stackIntegerValue: 0.

        (interpreterProxy failed
         or: [(interpreterProxy isWordsOrBytes: array) not]) ifTrue:
                [^interpreterProxy primitiveFailFor: PrimErrBadArgument].

        (self isAlien: array)
                ifTrue:
                        [totalLength := self sizeField: array.
                         dest := (self startOfData: array withSize: totalLength) + start - 1.
                         totalLength = 0 "no bounds checks for zero-sized (pointer) Aliens"
                                ifTrue: [totalLength := stop]
                                ifFalse: [totalLength := totalLength abs]]
                ifFalse:
                        [totalLength := interpreterProxy byteSizeOf: array.
                         dest := (self startOfByteData: array) + start - 1].
        (start >= 1 and: [start - 1 <= stop and: [stop <= totalLength]])
                ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex].

        (interpreterProxy isIntegerObject: repl)
                ifTrue:
                        [(interpreterProxy integerValueOf: repl) <= 0 ifTrue:
                                [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
                        src := (interpreterProxy integerValueOf: repl) + replStart - 1]
                ifFalse:
+                       [(interpreterProxy isLargePositiveIntegerObject: repl)
-                       [(interpreterProxy fetchClassOf: repl) ==  interpreterProxy classLargePositiveInteger
                                ifTrue:
                                        [src := (interpreterProxy positive32BitValueOf: repl) + replStart - 1.
                                         interpreterProxy failed ifTrue:
                                                [^interpreterProxy primitiveFailFor: PrimErrBadArgument]]
                                ifFalse:
                                        [(self isAlien: repl)
                                                ifTrue:
                                                        [totalLength := self sizeField: repl.
                                                         src := (self startOfData: repl withSize: totalLength) + replStart - 1.
                                                         totalLength = 0 "no bounds checks for zero-sized (pointer) Aliens"
                                                                ifTrue: [totalLength := stop - start + replStart]
                                                                ifFalse: [totalLength := totalLength abs]]
                                                ifFalse:
                                                        [(interpreterProxy isWordsOrBytes: repl) ifFalse:
                                                                [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
                                                         totalLength := interpreterProxy byteSizeOf: repl.
                                                         src := (self startOfByteData: repl) + replStart - 1].
                                        (replStart >= 1 and: [stop - start + replStart <= totalLength]) ifFalse:
                                                [^interpreterProxy primitiveFailFor: PrimErrBadIndex]]].

        (interpreterProxy isOopImmutable: array) ifTrue:
                [^interpreterProxy primitiveFailFor: PrimErrNoModification].

        count := stop - start + 1.
        self cCode: 'memmove((void *)dest,(void *)src,count)'
                inSmalltalk:
                        [count := count + src + dest. "squash unused var compiler warnings"
                         self error: 'not implemented'].

        interpreterProxy pop: interpreterProxy methodArgumentCount!

Item was added:
+ ----- Method: Integer class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+
+       ^cg ccgLoad: aBlock expr: aString asKindOfIntegerFrom: anInteger!

Item was added:
+ ----- Method: Interpreter>>isKindOfInteger: (in category 'plugin primitive support') -----
+ isKindOfInteger: oop
+       "Answer true if the oop is kind of Integer (Small or Large)."
+       <api>
+       <inline: true>
+       ^(self isIntegerObject: oop)
+               or: [self isLargeIntegerInstance: oop]!

Item was added:
+ ----- Method: Interpreter>>isLargeIntegerObject: (in category 'plugin primitive support') -----
+ isLargeIntegerObject: oop
+       ^(self isLargeIntegerInstance: oop)!

Item was added:
+ ----- Method: Interpreter>>isLargeNegativeIntegerObject: (in category 'plugin primitive support') -----
+ isLargeNegativeIntegerObject: oop
+       ^(self isInstanceOfClassLargeNegativeInteger: oop)!

Item was added:
+ ----- Method: Interpreter>>isLargePositiveIntegerObject: (in category 'plugin primitive support') -----
+ isLargePositiveIntegerObject: oop
+       ^(self isInstanceOfClassLargePositiveInteger: oop)!

Item was removed:
- ----- Method: InterpreterPrimitives>>isInstanceOfClassLargeNegativeInteger: (in category 'primitive support') -----
- isInstanceOfClassLargeNegativeInteger: oop
-       <inline: true>
-       "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
-        (because is:instanceOf:compactClassIndex: has an inline: pragma) the
-        phrase (objectMemory splObj: ClassLargeNegativeInteger) is expanded
-        in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
-       ^objectMemory
-               is: oop
-               instanceOf: (objectMemory splObj: ClassLargeNegativeInteger)
-               compactClassIndex: ClassLargeNegativeIntegerCompactIndex!

Item was removed:
- ----- Method: InterpreterPrimitives>>isInstanceOfClassLargePositiveInteger: (in category 'primitive support') -----
- isInstanceOfClassLargePositiveInteger: oop
-       <inline: true>
-       "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
-        (because is:instanceOf:compactClassIndex: has an inline: pragma) the
-        phrase (objectMemory splObj: ClassLargePositiveInteger) is expanded
-        in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
-       ^objectMemory
-               is: oop
-               instanceOf: (objectMemory splObj: ClassLargePositiveInteger)
-               compactClassIndex: ClassLargePositiveIntegerCompactIndex!

Item was added:
+ ----- Method: InterpreterProxy>>isKindOfInteger: (in category 'testing') -----
+ isKindOfInteger: objectOrientedPointer
+       ^objectOrientedPointer isInteger!

Item was added:
+ ----- Method: InterpreterProxy>>isLargeIntegerObject: (in category 'testing') -----
+ isLargeIntegerObject: objectOrientedPointer
+       ^objectOrientedPointer isKindOf: LargePositiveInteger!

Item was added:
+ ----- Method: InterpreterProxy>>isLargeNegativeIntegerObject: (in category 'testing') -----
+ isLargeNegativeIntegerObject: objectOrientedPointer
+       ^objectOrientedPointer isMemberOf: LargeNegativeInteger!

Item was added:
+ ----- Method: InterpreterProxy>>isLargePositiveIntegerObject: (in category 'testing') -----
+ isLargePositiveIntegerObject: objectOrientedPointer
+       ^objectOrientedPointer isMemberOf: LargePositiveInteger!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitAddLarge:with: (in category 'oop functions') -----
  digitAddLarge: firstInteger with: secondInteger
        "Does not need to normalize!!"
        | over firstDigitLen secondDigitLen shortInt shortDigitLen longInt longDigitLen sum newSum neg |
        <var: #over type: #'unsigned int'>
        firstDigitLen := self digitSizeOfLargeInt: firstInteger.
        secondDigitLen := self digitSizeOfLargeInt: secondInteger.
+       neg := interpreterProxy isLargeNegativeIntegerObject: firstInteger.
-       neg := (interpreterProxy fetchClassOf: firstInteger)
-               = interpreterProxy classLargeNegativeInteger.
        firstDigitLen <= secondDigitLen
                ifTrue:
                        [shortInt := firstInteger.
                        shortDigitLen := firstDigitLen.
                        longInt := secondInteger.
                        longDigitLen := secondDigitLen]
                ifFalse:
                        [shortInt := secondInteger.
                        shortDigitLen := secondDigitLen.
                        longInt := firstInteger.
                        longDigitLen := firstDigitLen].
        "       sum := Integer new: len neg: firstInteger negative."
        self remapOop: #(shortInt longInt ) in: [sum := self createLargeIntegerNeg: neg digitLength: longDigitLen].
        over := self
                                cDigitAdd: (self pointerToFirstDigitOfLargeInt: shortInt)
                                len: shortDigitLen
                                with: (self pointerToFirstDigitOfLargeInt: longInt)
                                len: longDigitLen
                                into: (self pointerToFirstDigitOfLargeInt: sum).
        over > 0
                ifTrue:
                        ["sum := sum growby: 1."
                        self remapOop: sum in: [newSum := self createLargeIntegerNeg: neg byteLength: longDigitLen * 4 + 1].
                        self
                                cDigitCopyFrom: (self pointerToFirstDigitOfLargeInt: sum)
                                to: (self pointerToFirstDigitOfLargeInt: newSum)
                                len: longDigitLen.
                        sum := newSum.
                        "C index!!"
                        self cDigitOf: (self pointerToFirstDigitOfLargeInt: sum)
                                at: longDigitLen put: over]
                ifFalse:
                        [sum := neg
                                ifTrue: [self normalizeNegative: sum]
                                ifFalse: [self normalizePositive: sum]].
        ^ sum!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitBitLogic:with:opIndex: (in category 'oop functions') -----
  digitBitLogic: firstInteger with: secondInteger opIndex: opIx
        "Bit logic here is only implemented for positive integers or Zero;
        if rec or arg is negative, it fails."
        | firstLarge secondLarge firstLen secondLen shortLen shortLarge longLen longLarge result |
        (interpreterProxy isIntegerObject: firstInteger)
                ifTrue:
                        [(interpreterProxy integerValueOf: firstInteger)
                                < 0 ifTrue: [^ interpreterProxy primitiveFail].
                        "convert it to a not normalized LargeInteger"
                        self remapOop: secondInteger in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
                ifFalse:
+                       [(interpreterProxy isLargePositiveIntegerObject: firstInteger) ifFalse: [^ interpreterProxy primitiveFail].
-                       [(interpreterProxy fetchClassOf: firstInteger)
-                               = interpreterProxy classLargePositiveInteger ifFalse: [^ interpreterProxy primitiveFail].
                        firstLarge := firstInteger].
        (interpreterProxy isIntegerObject: secondInteger)
                ifTrue:
                        [(interpreterProxy integerValueOf: secondInteger)
                                < 0 ifTrue: [^ interpreterProxy primitiveFail].
                        "convert it to a not normalized LargeInteger"
                        self remapOop: firstLarge in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
                ifFalse:
+                       [(interpreterProxy isLargePositiveIntegerObject: secondInteger) ifFalse: [^ interpreterProxy primitiveFail].
-                       [(interpreterProxy fetchClassOf: secondInteger)
-                               = interpreterProxy classLargePositiveInteger ifFalse: [^ interpreterProxy primitiveFail].
                        secondLarge := secondInteger].
        firstLen := self byteSizeOfLargeInt: firstLarge.
        secondLen := self byteSizeOfLargeInt: secondLarge.
        firstLen < secondLen
                ifTrue:
                        [shortLen := firstLen.
                        shortLarge := firstLarge.
                        longLen := secondLen.
                        longLarge := secondLarge]
                ifFalse:
                        [shortLen := secondLen.
                        shortLarge := secondLarge.
                        longLen := firstLen.
                        longLarge := firstLarge].
        self remapOop: #(shortLarge longLarge ) in: [result := interpreterProxy instantiateClass: interpreterProxy classLargePositiveInteger indexableSize: longLen].
        self
                cDigitOp: opIx
                short: (self pointerToFirstDigitOfLargeInt: shortLarge)
                len: shortLen + 3 // 4
                long: (self pointerToFirstDigitOfLargeInt: longLarge)
                len: longLen + 3 // 4
                into: (self pointerToFirstDigitOfLargeInt: result).
        interpreterProxy failed ifTrue: [^ 0].
        ^ self normalizePositive: result!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitSubLarge:with: (in category 'oop functions') -----
  digitSubLarge: firstInteger with: secondInteger
        "Normalizes."
        | firstDigitLen secondDigitLen larger largeDigitLen smaller smallerDigitLen neg resDigitLen res firstNeg |
+       firstNeg := interpreterProxy isLargeNegativeIntegerObject: firstInteger.
-       firstNeg := (interpreterProxy fetchClassOf: firstInteger)
-                               = interpreterProxy classLargeNegativeInteger.
        firstDigitLen := self digitSizeOfLargeInt: firstInteger.
        secondDigitLen := self digitSizeOfLargeInt: secondInteger.
        firstDigitLen = secondDigitLen ifTrue:
                [[firstDigitLen > 1
                  and: [(self unsafeDigitOfLargeInt: firstInteger at: firstDigitLen) = (self unsafeDigitOfLargeInt: secondInteger at: firstDigitLen)]]
                        whileTrue: [firstDigitLen := firstDigitLen - 1].
                secondDigitLen := firstDigitLen].
        (firstDigitLen < secondDigitLen
         or: [firstDigitLen = secondDigitLen
                 and: [(self unsafeDigitOfLargeInt: firstInteger at: firstDigitLen) < (self unsafeDigitOfLargeInt: secondInteger at: firstDigitLen)]])
                ifTrue:
                        [larger := secondInteger.
                        largeDigitLen := secondDigitLen.
                        smaller := firstInteger.
                        smallerDigitLen := firstDigitLen.
                        neg := firstNeg == false]
                ifFalse:
                        [larger := firstInteger.
                        largeDigitLen := firstDigitLen.
                        smaller := secondInteger.
                        smallerDigitLen := secondDigitLen.
                        neg := firstNeg].
        resDigitLen := largeDigitLen.
        self remapOop: #(smaller larger)
                in: [res := self createLargeIntegerNeg: neg digitLength: resDigitLen].
        self
                cDigitSub: (self pointerToFirstDigitOfLargeInt: smaller)
                len: smallerDigitLen
                with: (self pointerToFirstDigitOfLargeInt: larger)
                len: largeDigitLen
                into: (self pointerToFirstDigitOfLargeInt: res).
        ^neg
                ifTrue: [self normalizeNegative: res]
                ifFalse: [self normalizePositive: res]!

Item was removed:
- ----- Method: LargeIntegersPlugin>>isLargeIntegerOop: (in category 'util') -----
- isLargeIntegerOop: oop
-       | oopClass |
-       oopClass := interpreterProxy fetchClassOf: oop.
-       ^oopClass == interpreterProxy classLargeNegativeInteger or: [oopClass == interpreterProxy classLargePositiveInteger]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>normalize: (in category 'oop functions') -----
  normalize: aLargeInteger
        "Check for leading zeroes and return shortened copy if so."
        self debugCode: [self msg: 'normalize: aLargeInteger'].
+       (interpreterProxy isLargePositiveIntegerObject: aLargeInteger)
-       (interpreterProxy fetchClassOf: aLargeInteger)
-               = interpreterProxy classLargePositiveInteger
                ifTrue: [^ self normalizePositive: aLargeInteger]
                ifFalse: [^ self normalizeNegative: aLargeInteger]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primAnyBitFrom:to: (in category 'Integer primitives') -----
  primAnyBitFrom: from to: to
        | integer large |
        self debugCode: [self msg: 'primAnyBitFrom: from to: to'].
        integer := self
                                primitive: 'primAnyBitFromTo'
+                               parameters: #(#SmallInteger #SmallInteger )
+                               receiver: #Integer.
-                               parameters: #(#SmallInteger #SmallInteger ).
        (interpreterProxy isIntegerObject: integer)
                ifTrue: ["convert it to a not normalized LargeInteger"
                        large := self createLargeFromSmallInteger: integer]
+               ifFalse: [large := integer].
-               ifFalse:
-                       [(self isLargeIntegerOop: integer) ifFalse: [^interpreterProxy primitiveFail].
-                       large := integer].
        ^ (self
                anyBitOfLargeInt: large
                from: from
                to: to)
                asOop: Boolean!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitAdd: (in category 'Integer primitives') -----
  primDigitAdd: secondInteger
        | firstLarge secondLarge firstInteger |
        self debugCode: [self msg: 'primDigitAdd: secondInteger'].
+       firstInteger := self
+                               primitive: 'primDigitAdd'
+                               parameters: #(Integer )
+                               receiver: #Integer.
-       firstInteger := self primitive: 'primDigitAdd'.
        (interpreterProxy isIntegerObject: firstInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self remapOop: secondInteger in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+               ifFalse: [firstLarge := firstInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       firstLarge := firstInteger].
        (interpreterProxy isIntegerObject: secondInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self remapOop: firstLarge in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
+               ifFalse: [secondLarge := secondInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       secondLarge := secondInteger].
        ^ self digitAddLarge: firstLarge with: secondLarge!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitAnd: (in category 'Integer primitives') -----
  primDigitBitAnd: secondInteger
        "Bit logic here is only implemented for positive integers or Zero; if rec
        or arg is negative, it fails."
        | firstInteger |
        self debugCode: [self msg: 'primDigitBitAnd: secondInteger'].
+       firstInteger := self
+                               primitive: 'primDigitBitAnd'
+                               parameters: #(Integer )
+                               receiver: #Integer.
-       firstInteger := self primitive: 'primDigitBitAnd'.
        ^ self
                digitBitLogic: firstInteger
                with: secondInteger
                opIndex: andOpIndex!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitOr: (in category 'Integer primitives') -----
  primDigitBitOr: secondInteger
        "Bit logic here is only implemented for positive integers or Zero; if rec
        or arg is negative, it fails."
        | firstInteger |
        self debugCode: [self msg: 'primDigitBitOr: secondInteger'].
+       firstInteger := self
+                               primitive: 'primDigitBitOr'
+                               parameters: #(Integer )
+                               receiver: #Integer.
-       firstInteger := self primitive: 'primDigitBitOr'.
        ^ self
                digitBitLogic: firstInteger
                with: secondInteger
                opIndex: orOpIndex!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitShiftMagnitude: (in category 'Integer primitives') -----
  primDigitBitShiftMagnitude: shiftCount
        | rShift aLarge anInteger |
        self debugCode: [self msg: 'primDigitBitShiftMagnitude: shiftCount'].
        anInteger := self
                                primitive: 'primDigitBitShiftMagnitude'
+                               parameters: #(#SmallInteger )
+                               receiver: #Integer.
-                               parameters: #(#SmallInteger ).
        (interpreterProxy isIntegerObject: anInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        aLarge := self createLargeFromSmallInteger: anInteger]
+               ifFalse: [aLarge := anInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: anInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       aLarge := anInteger].
        shiftCount >= 0
                ifTrue: [^ self digit: aLarge Lshift: shiftCount]
                ifFalse:
                        [rShift := 0 - shiftCount.
                        ^ self normalize: (self
                                        digit: aLarge
                                        Rshift: rShift
                                        lookfirst: (self digitSizeOfLargeInt: aLarge))]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitXor: (in category 'Integer primitives') -----
  primDigitBitXor: secondInteger
        "Bit logic here is only implemented for positive integers or Zero; if rec
        or arg is negative, it fails."
        | firstInteger |
        self debugCode: [self msg: 'primDigitBitXor: secondInteger'].
+       firstInteger := self
+                               primitive: 'primDigitBitXor'
+                               parameters: #(Integer )
+                               receiver: #Integer.
-       firstInteger := self primitive: 'primDigitBitXor'.
        ^ self
                digitBitLogic: firstInteger
                with: secondInteger
                opIndex: xorOpIndex!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitCompare: (in category 'Integer primitives') -----
  primDigitCompare: secondInteger
+       | firstVal secondVal firstInteger |
-       | firstVal secondVal firstInteger firstIsSmall secondIsSmall |
        self debugCode: [self msg: 'primDigitCompare: secondInteger'].
+       firstInteger := self
+                               primitive: 'primDigitCompare'
+                               parameters: #(#Integer )
+                               receiver: #Integer.
-       firstInteger := self primitive: 'primDigitCompare'.
        "shortcut: aSmallInteger has to be smaller in Magnitude as aLargeInteger"
+       (interpreterProxy isIntegerObject: firstInteger)
+               ifTrue: ["first"
+                       (interpreterProxy isIntegerObject: secondInteger)
+                               ifTrue: ["second"
+                                       (firstVal := interpreterProxy integerValueOf: firstInteger) > (secondVal := interpreterProxy integerValueOf: secondInteger)
-       firstIsSmall := interpreterProxy isIntegerObject: firstInteger.
-       secondIsSmall := interpreterProxy isIntegerObject: secondInteger.
-       firstIsSmall ifFalse: [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail]].
-       secondIsSmall ifFalse: [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail]].
-       firstIsSmall
-               ifTrue:
-                       [secondIsSmall
-                               ifTrue:
-                                       [(firstVal := interpreterProxy integerValueOf: firstInteger) > (secondVal := interpreterProxy integerValueOf: secondInteger)
                                                ifTrue: [^ 1 asOop: SmallInteger"first > second"]
                                                ifFalse: [firstVal < secondVal
                                                                ifTrue: [^ -1 asOop: SmallInteger"first < second"]
                                                                ifFalse: [^ 0 asOop: SmallInteger"first = second"]]]
+                               ifFalse: ["SECOND"
+                                       ^ -1 asOop: SmallInteger"first < SECOND"]]
+               ifFalse: ["FIRST"
+                       (interpreterProxy isIntegerObject: secondInteger)
+                               ifTrue: ["second"
+                                       ^ 1 asOop: SmallInteger"FIRST > second"]
+                               ifFalse: ["SECOND"
+                                       ^ self digitCompareLarge: firstInteger with: secondInteger]]!
-                               ifFalse:
-                                       [^ -1 asOop: SmallInteger"first < SECOND"]]
-               ifFalse:
-                       [secondIsSmall
-                               ifTrue:
-                                       [^ 1 asOop: SmallInteger"FIRST > second"]
-                               ifFalse:
-                                       [^ self digitCompareLarge: firstInteger with: secondInteger]]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitDiv:negative: (in category 'Integer primitives') -----
  primDigitDiv: secondInteger negative: neg
        "Answer the result of dividing firstInteger by secondInteger.
        Fail if parameters are not integers, not normalized or secondInteger is
        zero. "
        | firstAsLargeInteger secondAsLargeInteger firstInteger |
        self debugCode: [self msg: 'primDigitDiv: secondInteger negative: neg'].
        firstInteger := self
                                primitive: 'primDigitDivNegative'
+                               parameters: #(#Integer #Boolean )
+                               receiver: #Integer.
-                               parameters: #(#Oop #Boolean ).
        "Coerce SmallIntegers to corresponding (not normalized) large integers
        and check for zerodivide."
        (interpreterProxy isIntegerObject: firstInteger)
+               ifTrue: ["convert to LargeInteger"
-               ifTrue:
-                       ["convert to LargeInteger"
                        self
                                remapOop: secondInteger
                                in: [firstAsLargeInteger := self createLargeFromSmallInteger: firstInteger]]
                ifFalse:
+                       ["Avoid crashes in case of getting unnormalized args."
+                       (self isNormalized: firstInteger)
+                               ifFalse:
+                                       [self debugCode:
+                                               [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
+                                               self msg: '------> receiver *not* normalized!!'].
+                                       ^ interpreterProxy primitiveFail].
+                       firstAsLargeInteger := firstInteger].
-                       [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       "Avoid crashes in case of getting unnormalized args."
-                       (self isNormalized: firstInteger) ifFalse: [self
-                               debugCode: [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
-                                       self msg: '------> receiver *not* normalized!!'].
-                       ^ interpreterProxy primitiveFail].firstAsLargeInteger := firstInteger].
        (interpreterProxy isIntegerObject: secondInteger)
+               ifTrue: ["check for zerodivide and convert to LargeInteger"
+                       (interpreterProxy integerValueOf: secondInteger)
+                                       = 0
-               ifTrue:
-                       ["check for zerodivide and convert to LargeInteger"
-                       (interpreterProxy integerValueOf: secondInteger) = 0
                                ifTrue: [^ interpreterProxy primitiveFail].
                        self
                                remapOop: firstAsLargeInteger
                                in: [secondAsLargeInteger := self createLargeFromSmallInteger: secondInteger]]
                ifFalse:
+                       ["Avoid crashes in case of getting unnormalized args."
+                       (self isNormalized: secondInteger)
+                               ifFalse:
+                                       [self debugCode:
+                                               [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
+                                               self msg: '------> argument *not* normalized!!'].
+                                       ^ interpreterProxy primitiveFail].
-                       [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       (self isNormalized: secondInteger) ifFalse: [self
-                               debugCode: [self msg: 'ERROR in primDigitDiv: secondInteger negative: neg'.
-                                       self msg: '------> argument *not* normalized!!'].
-                       ^ interpreterProxy primitiveFail].
                        secondAsLargeInteger := secondInteger].
        ^ self
                digitDivLarge: firstAsLargeInteger
                with: secondAsLargeInteger
                negative: neg!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitMultiply:negative: (in category 'Integer primitives') -----
  primDigitMultiply: secondInteger negative: neg
        | firstLarge secondLarge firstInteger |
        self debugCode: [self msg: 'primDigitMultiply: secondInteger negative: neg'].
        firstInteger := self
                                primitive: 'primDigitMultiplyNegative'
+                               parameters: #(#Integer #Boolean )
+                               receiver: #Integer.
-                               parameters: #(#Oop #Boolean ).
        (interpreterProxy isIntegerObject: firstInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self
                                remapOop: secondInteger
                                in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+               ifFalse: [firstLarge := firstInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       firstLarge := firstInteger].
        (interpreterProxy isIntegerObject: secondInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self
                                remapOop: firstLarge
                                in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
+               ifFalse: [secondLarge := secondInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: secondInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       secondLarge := secondInteger].
        ^ self
                digitMultiplyLarge: firstLarge
                with: secondLarge
                negative: neg!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitSubtract: (in category 'Integer primitives') -----
  primDigitSubtract: secondInteger
        | firstLarge secondLarge firstInteger |
        self debugCode: [self msg: 'primDigitSubtract: secondInteger'].
+       firstInteger := self
+                               primitive: 'primDigitSubtract'
+                               parameters: #(#Integer )
+                               receiver: #Integer.
-       firstInteger := self primitive: 'primDigitSubtract'.
        (interpreterProxy isIntegerObject: firstInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self
                                remapOop: secondInteger
                                in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+               ifFalse: [firstLarge := firstInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       firstLarge := firstInteger].
        (interpreterProxy isIntegerObject: secondInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self
                                remapOop: firstLarge
                                in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
+               ifFalse: [secondLarge := secondInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       secondLarge := secondInteger].
        ^ self digitSubLarge: firstLarge with: secondLarge!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primMontgomeryDigitLength (in category 'Integer primitives') -----
  primMontgomeryDigitLength
        self debugCode: [self msg: 'primMontgomeryDigitLength'].
+       self
+                               primitive: 'primMontgomeryDigitLength'
+                               parameters: #()
+                               receiver: #Integer.
-       self primitive: 'primMontgomeryDigitLength'.
        ^interpreterProxy integerObjectOf: 32!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primMontgomeryTimes:modulo:mInvModB: (in category 'Integer primitives') -----
  primMontgomeryTimes: secondOperandInteger modulo: thirdModuloInteger mInvModB: mInverseInteger
        | firstLarge secondLarge firstInteger thirdLarge mInv |
        <var: #mInv type: #'unsigned int'>
        self debugCode: [self msg: 'montgomeryTimes: secondOperandInteger modulo: thirdModuloInteger mInvModB: smallInverseInteger'].
+       firstInteger := self
+                               primitive: 'primMontgomeryTimesModulo'
+                               parameters: #(Integer Integer Integer )
+                               receiver: #Integer.
+        mInv := interpreterProxy positive32BitValueOf: mInverseInteger.
-       firstInteger := self primitive: 'primMontgomeryTimesModulo'.
-       mInv := interpreterProxy positive32BitValueOf: mInverseInteger.
        (interpreterProxy isIntegerObject: firstInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self remapOop: #(secondOperandInteger thirdModuloInteger) in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
+               ifFalse: [firstLarge := firstInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: firstInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       firstLarge := firstInteger].
        (interpreterProxy isIntegerObject: secondOperandInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self remapOop: #(firstLarge thirdModuloInteger) in: [secondLarge := self createLargeFromSmallInteger: secondOperandInteger]]
+               ifFalse: [secondLarge := secondOperandInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: secondOperandInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       secondLarge := secondOperandInteger].
        (interpreterProxy isIntegerObject: thirdModuloInteger)
+               ifTrue: ["convert it to a not normalized LargeInteger"
-               ifTrue:
-                       ["convert it to a not normalized LargeInteger"
                        self remapOop: #(firstLarge secondLarge) in: [thirdLarge := self createLargeFromSmallInteger: thirdModuloInteger]]
+               ifFalse: [thirdLarge := thirdModuloInteger].
-               ifFalse:
-                       [(self isLargeIntegerOop: thirdModuloInteger) ifFalse: [^interpreterProxy primitiveFail].
-                       thirdLarge := thirdModuloInteger].
        ^ self digitMontgomery: firstLarge times: secondLarge modulo: thirdLarge mInvModB: mInv!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primNormalizeNegative (in category 'Integer primitives') -----
  primNormalizeNegative
        | rcvr |
        self debugCode: [self msg: 'primNormalizeNegative'].
+       rcvr := self
+                               primitive: 'primNormalizeNegative'
+                               parameters: #()
+                               receiver: #LargeNegativeInteger.
-       rcvr := self primitive: 'primNormalizeNegative'.
-       (interpreterProxy fetchClassOf: rcvr) == interpreterProxy classLargeNegativeInteger ifFalse: [^interpreterProxy primitiveFail].
        ^ self normalizeNegative: rcvr!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primNormalizePositive (in category 'Integer primitives') -----
  primNormalizePositive
        | rcvr |
        self debugCode: [self msg: 'primNormalizePositive'].
+       rcvr := self
+                               primitive: 'primNormalizePositive'
+                               parameters: #()
+                               receiver: #LargePositiveInteger.
-       rcvr := self primitive: 'primNormalizePositive'.
-       (interpreterProxy fetchClassOf: rcvr) == interpreterProxy classLargePositiveInteger ifFalse: [^interpreterProxy primitiveFail].
        ^ self normalizePositive: rcvr!

Item was added:
+ ----- Method: LargeNegativeInteger class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+
+       ^cg ccgLoad: aBlock expr: aString asMemberOfLargeNegativeIntegerFrom: anInteger!

Item was added:
+ ----- Method: LargePositiveInteger class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+
+       ^cg ccgLoad: aBlock expr: aString asMemberOfLargePositiveIntegerFrom: anInteger!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isKindOfInteger: (in category 'simulation only') -----
+ isKindOfInteger: offset
+       ^coInterpreter isKindOfInteger: offset!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isLargeIntegerObject: (in category 'simulation only') -----
+ isLargeIntegerObject: offset
+       ^coInterpreter isLargeIntegerObject: offset!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isLargeNegativeIntegerObject: (in category 'simulation only') -----
+ isLargeNegativeIntegerObject: offset
+       ^coInterpreter isLargeNegativeIntegerObject: offset!

Item was added:
+ ----- Method: NewCoObjectMemorySimulator>>isLargePositiveIntegerObject: (in category 'simulation only') -----
+ isLargePositiveIntegerObject: offset
+       ^coInterpreter isLargePositiveIntegerObject: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isKindOfInteger: (in category 'simulation only') -----
+ isKindOfInteger: offset
+       ^coInterpreter isKindOfInteger: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isLargeIntegerObject: (in category 'simulation only') -----
+ isLargeIntegerObject: offset
+       ^coInterpreter isLargeIntegerObject: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isLargeNegativeIntegerObject: (in category 'simulation only') -----
+ isLargeNegativeIntegerObject: offset
+       ^coInterpreter isLargeNegativeIntegerObject: offset!

Item was added:
+ ----- Method: NewObjectMemorySimulator>>isLargePositiveIntegerObject: (in category 'simulation only') -----
+ isLargePositiveIntegerObject: offset
+       ^coInterpreter isLargePositiveIntegerObject: offset!

Item was changed:
  ----- Method: ObjectMemory>>cCoerceSimple:to: (in category 'simulation support') -----
  cCoerceSimple: value to: cTypeString
        <doNotGenerate>
        ^cTypeString caseOf:
+          {    [#'char *']                     ->      [value].
+               [#'unsigned int']       ->      [value]. }!
-          {    [#'char *']     ->      [value] }!

Item was added:
+ ----- Method: ObjectMemory>>isInstanceOfClassLargeNegativeInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargeNegativeInteger: oop
+       <inline: true>
+       "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
+        (because is:instanceOf:compactClassIndex: has an inline: pragma) the
+        phrase (objectMemory splObj: ClassLargeNegativeInteger) is expanded
+        in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
+       ^self
+               is: oop
+               instanceOf: (self splObj: ClassLargeNegativeInteger)
+               compactClassIndex: ClassLargeNegativeIntegerCompactIndex!

Item was added:
+ ----- Method: ObjectMemory>>isInstanceOfClassLargePositiveInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargePositiveInteger: oop
+       <inline: true>
+       "N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
+        (because is:instanceOf:compactClassIndex: has an inline: pragma) the
+        phrase (objectMemory splObj: ClassLargePositiveInteger) is expanded
+        in-place and is _not_ evaluated if oop has a non-zero CompactClassIndex."
+       ^self
+               is: oop
+               instanceOf: (self splObj: ClassLargePositiveInteger)
+               compactClassIndex: ClassLargePositiveIntegerCompactIndex!

Item was added:
+ ----- Method: ObjectMemory>>isLargeIntegerInstance: (in category 'interpreter access') -----
+ isLargeIntegerInstance: oop
+       <inline: true>
+       ^(self isInstanceOfClassLargePositiveInteger: oop)
+               or: [self isInstanceOfClassLargeNegativeInteger: oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asKindOfIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asKindOfIntegerFrom: anInteger
+
+       ^String streamContents: [:aStream | aStream
+               nextPutAll: 'interpreterProxy success: (interpreterProxy isKindOfInteger: (interpreterProxy stackValue: ';
+               nextPutAll: anInteger asString;
+               nextPutAll: ')).';
+               crtab;
+               nextPutAll: (self
+                                               ccgLoad: aBlock
+                                               expr: aString
+                                               asRawOopFrom: anInteger)]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asMemberOfLargeNegativeIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargeNegativeIntegerFrom: anInteger
+
+       ^String streamContents: [:aStream | aStream
+               nextPutAll: 'interpreterProxy success: (interpreterProxy isLargeNegativeIntegerObject: (interpreterProxy stackValue: ';
+               nextPutAll: anInteger asString;
+               nextPutAll: ')).';
+               crtab;
+               nextPutAll: (self
+                                               ccgLoad: aBlock
+                                               expr: aString
+                                               asRawOopFrom: anInteger)]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asMemberOfLargePositiveIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargePositiveIntegerFrom: anInteger
+
+       ^String streamContents: [:aStream | aStream
+               nextPutAll: 'interpreterProxy success: (interpreterProxy isLargePositiveIntegerObject: (interpreterProxy stackValue: ';
+               nextPutAll: anInteger asString;
+               nextPutAll: ')).';
+               crtab;
+               nextPutAll: (self
+                                               ccgLoad: aBlock
+                                               expr: aString
+                                               asRawOopFrom: anInteger)]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asKindOfIntegerFrom: (in category 'simulation') -----
+ ccgLoad: forProlog expr: failBlock asKindOfIntegerFrom: argIndexOrNil
+       ^[:oop|
+          interpreterProxy success: (interpreterProxy isKindOfInteger: oop).
+          oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asMemberOfLargeNegativeIntegerFrom: (in category 'simulation') -----
+ ccgLoad: forProlog expr: failBlock asMemberOfLargeNegativeIntegerFrom: argIndexOrNil
+       ^[:oop|
+          interpreterProxy success: (interpreterProxy isLargeNegativeIntegerObject: oop).
+          oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asMemberOfLargePositiveIntegerFrom: (in category 'simulation') -----
+ ccgLoad: forProlog expr: failBlock asMemberOfLargePositiveIntegerFrom: argIndexOrNil
+       ^[:oop|
+          interpreterProxy success: (interpreterProxy isLargePositiveIntegerObject: oop).
+          oop]!

Item was added:
+ ----- Method: SpurMemoryManager>>isInstanceOfClassLargeNegativeInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargeNegativeInteger: oop
+       "Answer if the oop is a large negative integer instance."
+       ^(self isNonImmediate: oop) and: [(self classIndexOf: oop) = ClassLargeNegativeIntegerCompactIndex]!

Item was added:
+ ----- Method: SpurMemoryManager>>isInstanceOfClassLargePositiveInteger: (in category 'interpreter access') -----
+ isInstanceOfClassLargePositiveInteger: oop
+       "Answer if the oop is a large positive integer instance."
+       ^(self isNonImmediate: oop) and: [(self classIndexOf: oop) = ClassLargePositiveIntegerCompactIndex]!

Item was added:
+ ----- Method: SpurMemoryManager>>isLargeIntegerInstance: (in category 'interpreter access') -----
+ isLargeIntegerInstance: oop
+       "Answer if the oop is a large positive or negative integer instance."
+       ^(self isNonImmediate: oop) and: [((self classIndexOf: oop) - ClassLargeNegativeIntegerCompactIndex) asUnsignedInteger <= 1]!

Item was added:
+ ----- Method: StackInterpreter>>isKindOfInteger: (in category 'internal interpreter access') -----
+ isKindOfInteger: oop
+       "Answer true if the oop is kind of Integer (Small or Large)."
+       <api>
+       <inline: true>
+       ^(objectMemory isIntegerObject: oop)
+               or: [objectMemory isLargeIntegerInstance: oop]!

Item was added:
+ ----- Method: StackInterpreter>>isLargeIntegerObject: (in category 'internal interpreter access') -----
+ isLargeIntegerObject: oop
+       <api>
+       <inline: true>
+       ^objectMemory isLargeIntegerInstance: oop!

Item was added:
+ ----- Method: StackInterpreter>>isLargeNegativeIntegerObject: (in category 'internal interpreter access') -----
+ isLargeNegativeIntegerObject: oop
+       <api>
+       <inline: true>
+       ^objectMemory isInstanceOfClassLargeNegativeInteger: oop!

Item was added:
+ ----- Method: StackInterpreter>>isLargePositiveIntegerObject: (in category 'internal interpreter access') -----
+ isLargePositiveIntegerObject: oop
+       <api>
+       <inline: true>
+       ^objectMemory isInstanceOfClassLargePositiveInteger: oop!

Item was changed:
  ----- Method: StackInterpreter>>printStringOf: (in category 'debug printing') -----
  printStringOf: oop
        | fmt len cnt max i |
        <inline: false>
        (objectMemory isImmediate: oop) ifTrue:
                [^self].
        (objectMemory addressCouldBeObj: oop) ifFalse:
                [^self].
        fmt := objectMemory formatOf: oop.
        fmt < objectMemory firstByteFormat ifTrue: [^self].

        cnt := (max := 128) min: (len := objectMemory lengthOf: oop).
        i := 0.

        ((objectMemory is: oop
                  instanceOf: (objectMemory splObj: ClassByteArray)
                  compactClassIndex: classByteArrayCompactIndex)
+       or: [(objectMemory isLargeIntegerInstance: oop)])
-       or: [(self isInstanceOfClassLargePositiveInteger: oop)
-       or: [(self isInstanceOfClassLargeNegativeInteger: oop)]])
                ifTrue:
                        [[i < cnt] whileTrue:
                                [self printHex: (objectMemory fetchByte: i ofObject: oop).
                                 i := i + 1]]
                ifFalse:
                        [[i < cnt] whileTrue:
                                [self cCode:
                                                [(objectMemory fetchByte: i ofObject: oop) = 13 "Character cr asInteger" ifTrue:
                                                        [self print: '<CR>'.
                                                         i + 1 < len ifTrue:
                                                                [self print: '...'].
                                                         ^self]].
                                 self printChar: (objectMemory fetchByte: i ofObject: oop).
                                 i := i + 1]].
        len > max ifTrue:
                [self print: '...'].
        self flush!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>ffiIntegerValueOf: (in category 'callout support') -----
  ffiIntegerValueOf: oop
        "Support for generic callout. Answer an integer value that is coerced as C would do."
        <inline: true>
        "Cheat with a tag test"
        (oop anyMask: BytesPerWord - 1)
                ifTrue:
                        [(interpreterProxy isIntegerObject: oop) ifTrue:
                                [^interpreterProxy integerValueOf: oop].
                        self cppIf: SPURVM
                                ifTrue:
                                        [(interpreterProxy isCharacterObject: oop) ifTrue: "Immediate in Spur"
                                                [^interpreterProxy characterValueOf: oop].
                                         (interpreterProxy isFloatObject: oop) ifTrue: "Immediate in 64-bit Spur"
                                                [^interpreterProxy floatValueOf: oop]]]
                ifFalse:
                        [self cppIf: SPURVM
                                ifTrue: "No non-immediate characters in Spur"
                                        []
                                ifFalse:
                                        [(interpreterProxy isCharacterObject: oop) ifTrue:
                                                [^interpreterProxy characterValueOf: oop]].
                         (interpreterProxy isFloatObject: oop) ifTrue:
                                [^interpreterProxy floatValueOf: oop].
                         oop = interpreterProxy nilObject ifTrue: [^0]. "@@: should we really allow this????"
                         oop = interpreterProxy falseObject ifTrue: [^0].
                         oop = interpreterProxy trueObject ifTrue: [^1].
+                        (interpreterProxy isLargePositiveIntegerObject: oop) ifTrue:
-                        (interpreterProxy fetchClassOf: oop) = interpreterProxy classLargePositiveInteger ifTrue:
                                [self cppIf: BytesPerWord = 8 "Use cppIf: to get the return type of the function right.  Should be sqInt on 32-bits."
                                        ifTrue: [^interpreterProxy positive64BitValueOf: oop]
                                        ifFalse: [^interpreterProxy positive32BitValueOf: oop]]].
        ^interpreterProxy signedMachineIntegerValueOf: oop "<- will fail if not integer"!


Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.1813.mcz

Levente Uzonyi
 
Hi Nicolas,

IMHO the best would still be to use macros for as many of these functions
as possible.
The link-time optimization has its limitations, and it will not really
work for the VM, at least not the way it could provide speedups
comparable to macro use. This is because the optimizer won't optimize
everything blindly. And since these functions are not used from the main
VM code, the optimizer will consider these optimizations unnecessary,
which is probably why only the smallest functions were inlined in my
experimental compilation.
However the optimizer probably inlined many other things and removed some
cruft as well, because it worked on the whole VM. The size of the
resulting binary was 5.1MB instead of the usual 6.3MB.

Levente

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.1813.mcz

Eliot Miranda-2

Hi Levente,


> On Apr 20, 2016, at 4:17 AM, Levente Uzonyi <[hidden email]> wrote:
>
> Hi Nicolas,
>
> IMHO the best would still be to use macros for as many of these functions as possible.
> The link-time optimization has its limitations, and it will not really work for the VM, at least not the way it could provide speedups comparable to macro use.

+1

> This is because the optimizer won't optimize everything blindly. And since these functions are not used from the main VM code, the optimizer will consider these optimizations unnecessary, which is probably why only the smallest functions were inlined in my experimental compilation.
> However the optimizer probably inlined many other things and removed some cruft as well, because it worked on the whole VM. The size of the resulting binary was 5.1MB instead of the usual 6.3MB.

Interesting.  That's a big win.  Looks like LTO should be adopted as broadly as possible.  Did you run external plugin tests?  Anything broken?

>
> Levente
>
Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.1813.mcz

Levente Uzonyi
 
Hi Eliot,

On Wed, 20 Apr 2016, Eliot Miranda wrote:

>
> Hi Levente,
>
>
>> On Apr 20, 2016, at 4:17 AM, Levente Uzonyi <[hidden email]> wrote:
>>
>> Hi Nicolas,
>>
>> IMHO the best would still be to use macros for as many of these functions as possible.
>> The link-time optimization has its limitations, and it will not really work for the VM, at least not the way it could provide speedups comparable to macro use.
>
> +1
>
>> This is because the optimizer won't optimize everything blindly. And since these functions are not used from the main VM code, the optimizer will consider these optimizations unnecessary, which is probably why only the smallest functions were inlined in my experimental compilation.
>> However the optimizer probably inlined many other things and removed some cruft as well, because it worked on the whole VM. The size of the resulting binary was 5.1MB instead of the usual 6.3MB.
>
> Interesting.  That's a big win.  Looks like LTO should be adopted as broadly as possible.  Did you run external plugin tests?  Anything broken?

Since autoconf went nuts from the -flto flag (it couldn't correctly set
the value of HAVE_LIBDL), I had to manually tweak the generated Makefiles
to make the compilation work. Therefore I only added this flag to the
Makefiles in the vm, LargeIntegers and the main build directory, because
what I wanted to see was if this flag can speed primDigitCompare up.
So, once the flag works with autoconf, the actual gain can be bigger.

Levente

>
>>
>> Levente
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.1813.mcz

johnmci
 
for cmake I've elsewhere had to do the follow in the cmake script to set the clang as the linker, and passing -flto to the compiler. 

 set(CMAKE_LINKER "/usr/bin/clang")

 add_definitions("-flto ")



On Wed, Apr 20, 2016 at 9:33 AM, Levente Uzonyi <[hidden email]> wrote:

Hi Eliot,

On Wed, 20 Apr 2016, Eliot Miranda wrote:


Hi Levente,


On Apr 20, 2016, at 4:17 AM, Levente Uzonyi <[hidden email]> wrote:

Hi Nicolas,

IMHO the best would still be to use macros for as many of these functions as possible.
The link-time optimization has its limitations, and it will not really work for the VM, at least not the way it could provide speedups comparable to macro use.

+1

This is because the optimizer won't optimize everything blindly. And since these functions are not used from the main VM code, the optimizer will consider these optimizations unnecessary, which is probably why only the smallest functions were inlined in my experimental compilation.
However the optimizer probably inlined many other things and removed some cruft as well, because it worked on the whole VM. The size of the resulting binary was 5.1MB instead of the usual 6.3MB.

Interesting.  That's a big win.  Looks like LTO should be adopted as broadly as possible.  Did you run external plugin tests?  Anything broken?

Since autoconf went nuts from the -flto flag (it couldn't correctly set the value of HAVE_LIBDL), I had to manually tweak the generated Makefiles to make the compilation work. Therefore I only added this flag to the Makefiles in the vm, LargeIntegers and the main build directory, because what I wanted to see was if this flag can speed primDigitCompare up.
So, once the flag works with autoconf, the actual gain can be bigger.

Levente



Levente





--
===========================================================================
John M. McIntosh. Corporate Smalltalk Consulting Ltd https://www.linkedin.com/in/smalltalk
===========================================================================