VM Maker: VMMaker.oscog-eem.1594.mcz

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

VM Maker: VMMaker.oscog-eem.1594.mcz

commits-2
 
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1594.mcz

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

Name: VMMaker.oscog-eem.1594
Author: eem
Time: 13 December 2015, 5:24:57.076 pm
UUID: 79da8b81-d1f3-469a-869c-16c79d12649a
Ancestors: VMMaker.oscog-eem.1593

Cogit:
Don't inline AndCq:R:R: because its translation contains a jump and hence won't work in a statement list expression (e.g. as in x86's genJumpSmallInteger:scratchReg:).

Nuke genJump[Not]SmallInteger:scratch: in favour of genJump[Not]SmallInteger:scratchReg:

Slang:
Eliminate leaves in statement lists generated as expressions.

=============== Diff against VMMaker.oscog-eem.1593 ===============

Item was removed:
- ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratch: (in category 'compile abstract instructions') -----
- genJumpNotSmallInteger: aRegister scratch: scratchReg
- "Generate a test for aRegister containing a SmallInteger and a jump if not, answering the jump.
- If necessary use scratch reg (since testing for SmallInteger may be destructive)."
- <returnTypeC: #'AbstractInstruction *'>
- | jumpNotInt |
- <inline: true>
- <var: 'jumpNotInt' type: #'AbstractInstruction *'>
- jumpNotInt := self genJumpNotSmallInteger: aRegister.
- jumpNotInt asInteger = UnimplementedOperation ifTrue:
- [cogit MoveR: aRegister R: scratchReg.
- jumpNotInt := self genJumpNotSmallIntegerInScratchReg: TempReg].
- ^jumpNotInt!

Item was changed:
  ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratchReg: (in category 'compile abstract instructions') -----
  genJumpNotSmallInteger: aRegister scratchReg: scratch
  "Generate a compare and branch to test if aRegister contains other than a SmallInteger.
  Answer the jump.  Use scratch if required.  Subclasses will override if scratch is needed."
+ <inline: true>
- <returnTypeC: #'AbstractInstruction *'>
  ^self genJumpNotSmallInteger: aRegister!

Item was removed:
- ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratch: (in category 'compile abstract instructions') -----
- genJumpSmallInteger: aRegister scratch: scratchReg
- "Generate a test for aRegister containing a SmallInteger and a jump if so, answering the jump.
- If necessary use scratch reg (since testing for SmallInteger may be destructive)."
- <returnTypeC: #'AbstractInstruction *'>
- | jumpInt |
- <inline: true>
- <var: 'jumpInt' type: #'AbstractInstruction *'>
- jumpInt := self genJumpSmallInteger: aRegister.
- jumpInt asInteger = UnimplementedOperation ifTrue:
- [cogit MoveR: aRegister R: scratchReg.
- jumpInt := self genJumpSmallIntegerInScratchReg: TempReg].
- ^jumpInt!

Item was changed:
  ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratchReg: (in category 'compile abstract instructions') -----
  genJumpSmallInteger: aRegister scratchReg: scratch
  "Generate a compare and branch to test if aRegister contains a SmallInteger.
  Answer the jump.  Use scratch if required.  Subclasses will override if scratch is needed."
- <returnTypeC: #'AbstractInstruction *'>
  ^self genJumpSmallInteger: aRegister!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  "Implement the guts of primitiveAt"
  | formatReg convertToIntAndReturn
   jumpNotIndexable jumpImmediate jumpBadIndex
   jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
  <inline: true>
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #jumpWordTooBig type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
  <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
 
  jumpImmediate := self genJumpImmediate: ReceiverResultReg.
  cogit MoveR: Arg0Reg R: Arg1Reg.
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
   9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpIsArray := cogit JumpZero: 0.
  jumpNotIndexable := cogit JumpBelow: 0.
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpIsWords := cogit JumpAboveOrEqual: 0.
  "For now ignore 64-bit indexability."
  jumpNotIndexable jmpTarget: cogit Label.
  jumpNotIndexable := cogit Jump: 0.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  cogit backEnd byteReadsZeroExtend
  ifTrue:
  [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
  ifFalse:
  [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
  MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
  MoveR: formatReg R: ReceiverResultReg].
  convertToIntAndReturn := cogit Label.
  self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  cogit AndCq: 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpIsWords jmpTarget:
  (cogit CmpR: Arg1Reg R: ClassReg).
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
  cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpHasFixedFields jmpTarget:
  (cogit AndCq: objectMemory classIndexMask R: TempReg).
  cogit MoveR: TempReg R: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  jumpIsContext := cogit JumpZero: 0.
  cogit PushR: ClassReg.
  self genGetClassObjectOfClassIndex: formatReg into: ClassReg scratchReg: TempReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: ClassReg destReg: formatReg.
  cogit PopR: ClassReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit
  AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
  cogit AddR: formatReg R: Arg1Reg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpIsArray jmpTarget:
  (cogit CmpR: Arg1Reg R: ClassReg).
  jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpFixedFieldsOutOfBounds jmpTarget:
  (jumpArrayOutOfBounds jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpWordTooBig jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpIsContext jmpTarget:
  (jumpBadIndex jmpTarget:
  (jumpImmediate jmpTarget: cogit Label))))))))).
 
  ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  "Implement the guts of primitiveAt"
  | formatReg convertToIntAndReturn
   jumpNotIndexable jumpImmediate jumpBadIndex
   jumpIsBytes jumpIsShorts jumpIsWords jumpIsArray jumpHasFixedFields jumpIsContext
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
  <inline: true>
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
  <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
 
  jumpImmediate := self genJumpImmediate: ReceiverResultReg.
  cogit MoveR: Arg0Reg R: Arg1Reg.
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
   9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpIsArray := cogit JumpZero: 0.
  jumpNotIndexable := cogit JumpBelow: 0.
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpIsWords := cogit JumpAboveOrEqual: 0.
  "For now ignore 64-bit indexability."
  jumpNotIndexable jmpTarget: cogit Label.
  jumpNotIndexable := cogit Jump: 0.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  cogit backEnd byteReadsZeroExtend
  ifTrue:
  [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
  ifFalse:
  [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
  MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
  MoveR: formatReg R: ReceiverResultReg].
  convertToIntAndReturn := cogit Label.
  self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  cogit AndCq: 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpIsWords jmpTarget:
  (cogit CmpR: Arg1Reg R: ClassReg).
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >>  (objectMemory shiftForWord - 1) R: Arg1Reg.
  cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpHasFixedFields jmpTarget:
  (cogit AndCq: objectMemory classIndexMask R: TempReg).
  cogit MoveR: TempReg R: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  jumpIsContext := cogit JumpZero: 0.
  self genGetClassObjectOfClassIndex: formatReg into: Scratch0Reg scratchReg: TempReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: Scratch0Reg destReg: formatReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit
  AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
  cogit AddR: formatReg R: Arg1Reg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpIsArray jmpTarget:
  (cogit CmpR: Arg1Reg R: ClassReg).
  jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpFixedFieldsOutOfBounds jmpTarget:
  (jumpArrayOutOfBounds jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpIsContext jmpTarget:
  (jumpBadIndex jmpTarget:
  (jumpImmediate jmpTarget: cogit Label)))))))).
 
  ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveNewWithArg: (in category 'primitive generators') -----
  genInnerPrimitiveNewWithArg: retNoffset
  "Implement primitiveNewWithArg for convenient cases:
  - the receiver has a hash
  - the receiver is variable and not compiled method
  - single word header/num slots < numSlotsMask
  - the result fits in eden
  See superclass method for dynamic frequencies of formats.
  For the moment we implement only arrayFormat, firstByteFormat & firstLongFormat"
 
  | headerReg fillReg instSpecReg byteSizeReg maxSlots
   jumpArrayTooBig jumpByteTooBig jumpLongTooBig
   jumpArrayFormat jumpByteFormat jumpBytePrepDone jumpLongPrepDone
   jumpUnhashed jumpNElementsNonInt jumpFailCuzFixed jumpNoSpace jumpHasSlots fillLoop skip |
  <var: 'skip' type: #'AbstractInstruction *'>
  <var: 'fillLoop' type: #'AbstractInstruction *'>
  <var: 'jumpHasSlots' type: #'AbstractInstruction *'>
  <var: 'jumpNoSpace' type: #'AbstractInstruction *'>
  <var: 'jumpUnhashed' type: #'AbstractInstruction *'>
  <var: 'jumpByteFormat' type: #'AbstractInstruction *'>
  <var: 'jumpByteTooBig' type: #'AbstractInstruction *'>
  <var: 'jumpLongTooBig' type: #'AbstractInstruction *'>
  <var: 'jumpArrayFormat' type: #'AbstractInstruction *'>
  <var: 'jumpArrayTooBig' type: #'AbstractInstruction *'>
  <var: 'jumpFailCuzFixed' type: #'AbstractInstruction *'>
  <var: 'jumpBytePrepDone' type: #'AbstractInstruction *'>
  <var: 'jumpLongPrepDone' type: #'AbstractInstruction *'>
  <var: 'jumpNElementsNonInt' type: #'AbstractInstruction *'>
 
  "header will contain classIndex/class's hash & format & numSlots/fixed size"
  headerReg := SendNumArgsReg.
  "Assume there's an available scratch register on 64-bit machines.  This holds the saved numFixedFileds and then the value to fill with"
  fillReg := Scratch0Reg.
  self assert: (cogit backEnd concreteRegister: fillReg) > 0.
  "inst spec will hold class's instance specification and then byte size"
  instSpecReg := byteSizeReg := ClassReg.
  "The max slots we'll allocate here are those for a single header"
  maxSlots := objectMemory numSlotsMask - 1.
 
  "get freeStart as early as possible so as not to wait later..."
  cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
  "get class's hash & fail if 0"
  self genGetHashFieldNonImmOf: ReceiverResultReg into: headerReg.
  jumpUnhashed := cogit JumpZero: 0.
  "get index and fail if not a +ve integer"
+ jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
- jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
  "get class's format inst var for inst spec (format field)"
  self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: instSpecReg.
  cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth + self numSmallIntegerTagBits R: instSpecReg.
  cogit AndCq: objectMemory formatMask R: instSpecReg.
  "Add format to classIndex/format header now"
  cogit MoveR: instSpecReg R: TempReg.
  cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  cogit AddR: TempReg R: headerReg.
  "get integer value of num fields in fillReg now"
  cogit MoveR: Arg0Reg R: fillReg.
  self genConvertSmallIntegerToIntegerInReg: fillReg.
  "dispatch on format, failing if not variable or if compiled method"
  cogit CmpCq: objectMemory arrayFormat R: instSpecReg.
  jumpArrayFormat := cogit JumpZero: 0.
  cogit CmpCq: objectMemory firstByteFormat R: instSpecReg.
  jumpByteFormat := cogit JumpZero: 0.
  cogit CmpCq: objectMemory firstLongFormat R: instSpecReg.
  jumpFailCuzFixed := cogit JumpNonZero: 0.
 
  cogit CmpCq: (objectMemory integerObjectOf: maxSlots * 2) R: Arg0Reg.
  jumpLongTooBig := cogit JumpAbove: 0.
  "save num elements/slot size to instSpecReg"
  cogit MoveR: fillReg R: instSpecReg.
  "compute odd bits and add into headerReg; oddBits := 2 - nElements bitAnd: 1"
  cogit MoveCq: objectMemory wordSize / 4 R: TempReg.
  cogit SubR: instSpecReg R: TempReg.
  cogit AndCq: objectMemory wordSize / 4 - 1 R: TempReg.
  cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  cogit AddR: TempReg R: headerReg.
  "round up num elements to numSlots in instSpecReg"
  cogit AddCq: objectMemory wordSize / 4 - 1 R: instSpecReg.
  cogit LogicalShiftRightCq: objectMemory shiftForWord - 2 R: instSpecReg.
  cogit MoveCq: 0 R: fillReg.
  jumpLongPrepDone := cogit Jump: 0. "go allocate"
 
  jumpByteFormat jmpTarget:
  (cogit CmpCq: (objectMemory integerObjectOf: maxSlots * objectMemory wordSize) R: Arg0Reg).
  jumpByteTooBig := cogit JumpAbove: 0.
  "save num elements to instSpecReg"
  cogit MoveR: fillReg R: instSpecReg.
  "compute odd bits and add into headerReg; oddBits := 4 - nElements bitAnd: 3"
  cogit MoveCq: objectMemory wordSize R: TempReg.
  cogit SubR: instSpecReg R: TempReg.
  cogit AndCq: objectMemory wordSize - 1 R: TempReg.
  cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  cogit AddR: TempReg R: headerReg.
  "round up num elements to numSlots in instSpecReg"
  cogit AddCq: objectMemory wordSize - 1 R: instSpecReg.
  cogit LogicalShiftRightCq: objectMemory shiftForWord R: instSpecReg.
  cogit MoveCq: 0 R: fillReg.
  jumpBytePrepDone := cogit Jump: 0. "go allocate"
 
  jumpArrayFormat jmpTarget:
  (cogit CmpCq: (objectMemory integerObjectOf: maxSlots) R: Arg0Reg).
  jumpArrayTooBig := cogit JumpAbove: 0.
  "save num elements/slot size to instSpecReg"
  cogit MoveR: fillReg R: instSpecReg.
  cogit MoveCq: objectMemory nilObject R: fillReg.
  "fall through to allocate"
 
  jumpBytePrepDone jmpTarget:
  (jumpLongPrepDone jmpTarget: cogit Label).
 
  "store numSlots to headerReg"
  cogit MoveR: instSpecReg R: TempReg.
  cogit LogicalShiftLeftCq: objectMemory numSlotsFullShift R: TempReg.
  cogit AddR: TempReg R: headerReg.
  "compute byte size; remember 0-sized objects still need 1 slot."
  cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"
  jumpHasSlots := cogit JumpNonZero: 0.
  cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.
  skip := cogit Jump: 0.
  jumpHasSlots jmpTarget:
  (cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg).
  cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.
  skip jmpTarget:
  "check if allocation fits"
  (cogit AddR: Arg1Reg R: byteSizeReg).
  cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
  jumpNoSpace := cogit JumpAboveOrEqual: 0.
  "get result, increment freeStart and write it back. Arg1Reg holds new freeStart, the limit of the object"
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
  "write other half of header (numSlots/0 identityHash)"
  cogit MoveR: headerReg Mw: 0 r: ReceiverResultReg.
  "now fill"
  cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
  fillLoop :=
  cogit MoveR: fillReg Mw: 0 r: Arg1Reg.
  cogit AddCq: 8 R: Arg1Reg.
  cogit CmpR: Arg1Reg R: byteSizeReg.
  cogit JumpAbove: fillLoop.
  cogit RetN: retNoffset.
 
  jumpNoSpace jmpTarget:
  (jumpUnhashed jmpTarget:
  (jumpFailCuzFixed jmpTarget:
  (jumpArrayTooBig jmpTarget:
  (jumpByteTooBig jmpTarget:
  (jumpLongTooBig jmpTarget:
  (jumpNElementsNonInt jmpTarget: cogit Label)))))).
 
  ^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveAsCharacter:inReg: (in category 'primitive generators') -----
  genInnerPrimitiveAsCharacter: retNOffset inReg: reg
  | jumpNotInt jumpOutOfRange |
  <var: 'jumpNotInt' type: #'AbstractInstruction *'>
  <var: 'jumpOutOfRange' type: #'AbstractInstruction *'>
  reg ~= ReceiverResultReg ifTrue:
+ [jumpNotInt := self genJumpNotSmallInteger: reg scratchReg: TempReg].
- [jumpNotInt := self genJumpNotSmallInteger: reg scratch: TempReg].
  cogit MoveR: reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  cogit CmpCq: 1 << 30 - 1 R: TempReg.
  jumpOutOfRange := cogit JumpAbove: 0.
  self genConvertSmallIntegerToCharacterInReg: reg.
  reg ~= ReceiverResultReg ifTrue:
  [cogit MoveR: reg R: ReceiverResultReg].
  cogit RetN: retNOffset.
  jumpOutOfRange jmpTarget: cogit Label.
  reg ~= ReceiverResultReg ifTrue:
  [jumpNotInt jmpTarget: jumpOutOfRange getJmpTarget].
  ^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveObjectAt: (in category 'primitive generators') -----
  genInnerPrimitiveObjectAt: retNOffset
  | headerReg
   jumpBadIndex jumpNotCogMethod jumpBounds jumpNotHeaderIndex |
  <var: #jumpBounds type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpNotCogMethod type: #'AbstractInstruction *'>
  <var: #jumpNotHeaderIndex type: #'AbstractInstruction *'>
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
  "get header into Arg1Reg..."
  cogit MoveMw: objectMemory baseHeaderSize r: ReceiverResultReg R: (headerReg := Arg1Reg).
+ jumpNotCogMethod := self genJumpSmallInteger: headerReg scratchReg: TempReg.
- jumpNotCogMethod := self genJumpSmallInteger: headerReg scratch: TempReg.
  cogit MoveMw: (cogit offset: CogMethod of: #methodHeader) r: headerReg R: headerReg.
  jumpNotCogMethod jmpTarget: (cogit
  CmpCq: (objectMemory integerObjectOf: 1) R: Arg0Reg).
  jumpNotHeaderIndex := cogit JumpNonZero: 0.
  cogit
  MoveR: headerReg R: ReceiverResultReg;
  RetN: retNOffset.
  jumpNotHeaderIndex jmpTarget: (cogit
  AndCq: (objectMemory integerObjectOf: coInterpreter alternateHeaderNumLiteralsMask) R: headerReg).
  cogit
  SubCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg;
  CmpR: headerReg R: Arg0Reg.
  jumpBounds := cogit JumpAbove: 0.
 
  self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  cogit
  AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg;
  MoveXwr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg;
  RetN: retNOffset.
 
  jumpBounds jmpTarget: (cogit
  AddCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg).
  jumpBadIndex jmpTarget: cogit Label.
  ^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
  genInnerPrimitiveStringAt: retNoffset
  "Implement the guts of primitiveStringAt; dispatch on size"
  | formatReg jumpNotIndexable jumpBadIndex done
   jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
  <inline: true>
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #done type: #'AbstractInstruction *'>
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpIsWords type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpWordTooBig type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
 
  cogit MoveR: Arg0Reg R: Arg1Reg.
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
   9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpIsWords := cogit JumpGreaterOrEqual: 0.
  jumpNotIndexable := cogit Jump: 0.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit backEnd byteReadsZeroExtend ifFalse:
  [cogit AndCq: 255 R: ReceiverResultReg].
  done := cogit Label.
  self genConvertIntegerToCharacterInReg: ReceiverResultReg.
  cogit RetN: retNoffset.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  cogit AndCq: 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg;
  CmpR: Arg1Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: done.
 
  jumpIsWords jmpTarget:
  (cogit CmpR: Arg1Reg R: ClassReg).
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
  cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  cogit Jump: done.
 
  jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpWordTooBig jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpBadIndex jmpTarget: cogit Label))))).
 
  ^0!

Item was changed:
  ----- Method: Cogit>>AndCq:R:R: (in category 'abstract instructions') -----
  AndCq: quickConstant R: srcReg R: destReg
+ <inline: false>
- <inline: true>
  <returnTypeC: #'AbstractInstruction *'>
  | first |
  <var: 'first' type: #'AbstractInstruction *'>
  backEnd hasThreeAddressArithmetic ifTrue:
  [^self gen: AndCqRR quickConstant: quickConstant operand: srcReg operand: destReg].
  srcReg = destReg ifTrue:
  [^self gen: AndCqR quickConstant: quickConstant operand: destReg.].
  first := self gen: MoveRR operand: srcReg operand: destReg.
  self gen: AndCqR quickConstant: quickConstant operand: destReg.
  ^first!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>checkQuickConstant:forInstruction: (in category 'compile abstract instructions') -----
  checkQuickConstant: literal forInstruction: anInstruction
  <var: #anInstruction type: #'AbstractInstruction *'>
  <returnTypeC: #'AbstractInstruction *'>
+ <inline: true>
  anInstruction usesOutOfLineLiteral ifTrue:
+ [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 1 << (objectMemory wordSize * 8) - 1]))].
- [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 16rFFFFFFFF]))].
  ^anInstruction!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
  genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
  "Receiver and arg in registers.
  Stack looks like
  return address"
  <var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
  | jumpFailClass jumpFailClass2 jumpFailAlloc jumpFailCheck jumpImmediate jumpNonInt doOp |
  <var: #jumpFailClass type: #'AbstractInstruction *'>
  <var: #jumpFailClass2 type: #'AbstractInstruction *'>
  <var: #jumpFailAlloc type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #jumpNonInt type: #'AbstractInstruction *'>
  <var: #jumpFailCheck type: #'AbstractInstruction *'>
  <var: #doOp type: #'AbstractInstruction *'>
  objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  self MoveR: Arg0Reg R: ClassReg.
  jumpImmediate := objectRepresentation genJumpImmediate: Arg0Reg.
  objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
  objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
  jumpFailClass := self JumpNonZero: 0.
  objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
  doOp := self Label.
  preOpCheckOrNil ifNotNil:
  [jumpFailCheck := self perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].
  self gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
  jumpFailAlloc := objectRepresentation
  genAllocFloatValue: DPFPReg0
  into: SendNumArgsReg
  scratchReg: ClassReg
  scratchReg: TempReg.
  self MoveR: SendNumArgsReg R: ReceiverResultReg.
  self RetN: 0.
  jumpImmediate jmpTarget: self Label.
  objectRepresentation maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: doOp.
  objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
+ [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].
- [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratch: TempReg].
  objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  self ConvertR: ClassReg Rd: DPFPReg1.
  self Jump: doOp.
  "We need to push the register args on two paths; this one and the interpreter primitive path.
  But the interpreter primitive path won't unless regArgsHaveBeenPushed is false."
  self assert: methodOrBlockNumArgs <= self numRegArgs.
  jumpFailClass jmpTarget: self Label.
  objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  [jumpNonInt jmpTarget: jumpFailClass getJmpTarget].
  preOpCheckOrNil ifNotNil:
  [jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].
  backEnd genPushRegisterArgsForNumArgs: methodOrBlockNumArgs scratchReg: SendNumArgsReg.
  jumpFailClass2 := self Jump: 0.
  jumpFailAlloc jmpTarget: self Label.
  self compileFallbackToInterpreterPrimitive: 0.
  jumpFailClass2 jmpTarget: self Label.
  ^0!

Item was changed:
  ----- Method: TReturnNode>>emitCCodeOn:level:generator: (in category 'C code generation') -----
  emitCCodeOn: aStream level: level generator: aCodeGen
 
  (expression isSwitch
  or: [expression isCaseStmt]) ifTrue:
  [^expression emitCCodeOn: aStream addToEndOfCases: self level: level generator: aCodeGen].
 
  (expression isSend and: [expression isValueExpansion]) ifTrue:
  [^self emitValueExpansionOn: aStream level: level generator: aCodeGen].
 
  'void' = aCodeGen currentMethod returnType ifTrue: "If the function is void, don't say 'return x' instead say ' x; return' "
  [expression isLeaf ifFalse:
  [expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen.
  aStream nextPut: $;; crtab: level].
  aStream nextPutAll: 'return'.
  ^self].
  aStream nextPutAll: 'return '.
+ expression
+ emitCCodeAsArgumentOn: aStream
+ level: (expression isStmtList ifTrue: [level + 1] ifFalse: [level])
+ generator: aCodeGen!
- expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen!

Item was changed:
  ----- Method: TStmtListNode>>emitCCodeAsArgumentOn:level:generator: (in category 'C code generation') -----
  emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen
+ | size |
+ (size := statements size) = 1 ifTrue:
-
- | statementWasComment |
- statements size = 1 ifTrue:
  [^statements first emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen].
- statementWasComment := false.
  aStream nextPut: $(. "N.B.  Comma binds weakest of all C operators."
+ statements withIndexDo:
+ [:s :idx| | p1 p2 |
+ p1 := aStream position.
+ s emitCCommentOn: aStream level: level.
+ (s isLeaf and: [s isLabel not and: [idx < statements size]]) ifFalse:
+ [s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen].
+ p2 := aStream position.
+ (idx < size and: [p2 > p1]) ifTrue:
- statements
- do:
- [:s |
- s emitCCommentOn: aStream level: level.
- s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen.
- statementWasComment := s isComment]
- separatedBy:
  [((self endsWithCloseBracket: aStream)
+  or: [s isComment]) ifFalse: [aStream nextPut: $,].
+ aStream crtab: level]].
-  or: [statementWasComment]) ifFalse: [aStream nextPut: $,].
- aStream crtab: level].
  aStream nextPut: $)!

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1594.mcz

Ryan Macnak
 
JIT builds still failing.

/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c: In function ‘genNSSendnumArgsdepthsendTable’:
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23996:15: warning: assignment makes integer from pointer without a cast [enabled by default]
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23997:10: error: called object ‘selector’ is not a function
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23998:9: error: called object ‘numArgs’ is not a function
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23999:7: error: called object ‘depth’ is not a function

On Sun, Dec 13, 2015 at 5:25 PM, <[hidden email]> wrote:

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1594.mcz

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

Name: VMMaker.oscog-eem.1594
Author: eem
Time: 13 December 2015, 5:24:57.076 pm
UUID: 79da8b81-d1f3-469a-869c-16c79d12649a
Ancestors: VMMaker.oscog-eem.1593

Cogit:
Don't inline AndCq:R:R: because its translation contains a jump and hence won't work in a statement list expression (e.g. as in x86's genJumpSmallInteger:scratchReg:).

Nuke genJump[Not]SmallInteger:scratch: in favour of genJump[Not]SmallInteger:scratchReg:

Slang:
Eliminate leaves in statement lists generated as expressions.

=============== Diff against VMMaker.oscog-eem.1593 ===============

Item was removed:
- ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratch: (in category 'compile abstract instructions') -----
- genJumpNotSmallInteger: aRegister scratch: scratchReg
-       "Generate a test for aRegister containing a SmallInteger and a jump if not, answering the jump.
-        If necessary use scratch reg (since testing for SmallInteger may be destructive)."
-       <returnTypeC: #'AbstractInstruction *'>
-       | jumpNotInt |
-       <inline: true>
-       <var: 'jumpNotInt' type: #'AbstractInstruction *'>
-       jumpNotInt := self genJumpNotSmallInteger: aRegister.
-       jumpNotInt asInteger = UnimplementedOperation ifTrue:
-               [cogit MoveR: aRegister R: scratchReg.
-                jumpNotInt := self genJumpNotSmallIntegerInScratchReg: TempReg].
-       ^jumpNotInt!

Item was changed:
  ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratchReg: (in category 'compile abstract instructions') -----
  genJumpNotSmallInteger: aRegister scratchReg: scratch
        "Generate a compare and branch to test if aRegister contains other than a SmallInteger.
         Answer the jump.  Use scratch if required.  Subclasses will override if scratch is needed."
+       <inline: true>
-       <returnTypeC: #'AbstractInstruction *'>
        ^self genJumpNotSmallInteger: aRegister!

Item was removed:
- ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratch: (in category 'compile abstract instructions') -----
- genJumpSmallInteger: aRegister scratch: scratchReg
-       "Generate a test for aRegister containing a SmallInteger and a jump if so, answering the jump.
-        If necessary use scratch reg (since testing for SmallInteger may be destructive)."
-       <returnTypeC: #'AbstractInstruction *'>
-       | jumpInt |
-       <inline: true>
-       <var: 'jumpInt' type: #'AbstractInstruction *'>
-       jumpInt := self genJumpSmallInteger: aRegister.
-       jumpInt asInteger = UnimplementedOperation ifTrue:
-               [cogit MoveR: aRegister R: scratchReg.
-                jumpInt := self genJumpSmallIntegerInScratchReg: TempReg].
-       ^jumpInt!

Item was changed:
  ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratchReg: (in category 'compile abstract instructions') -----
  genJumpSmallInteger: aRegister scratchReg: scratch
        "Generate a compare and branch to test if aRegister contains a SmallInteger.
         Answer the jump.  Use scratch if required.  Subclasses will override if scratch is needed."
-       <returnTypeC: #'AbstractInstruction *'>
        ^self genJumpSmallInteger: aRegister!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
        "Implement the guts of primitiveAt"
        | formatReg convertToIntAndReturn
          jumpNotIndexable jumpImmediate jumpBadIndex
          jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext
          jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
        <inline: true>
        "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
        <var: #jumpIsBytes type: #'AbstractInstruction *'>
        <var: #jumpIsShorts type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpIsContext type: #'AbstractInstruction *'>
        <var: #jumpImmediate type: #'AbstractInstruction *'>
        <var: #jumpWordTooBig type: #'AbstractInstruction *'>
        <var: #jumpNotIndexable type: #'AbstractInstruction *'>
        <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
        <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
        <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>

        jumpImmediate := self genJumpImmediate: ReceiverResultReg.
        cogit MoveR: Arg0Reg R: Arg1Reg.
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
        cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"

        "formatReg := self formatOf: ReceiverResultReg"
        self genGetFormatOf: ReceiverResultReg
                into: (formatReg := SendNumArgsReg)
                leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.

        self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.

        "dispatch on format in a combination of highest dynamic frequency order first and convenience.
                  0 = 0 sized objects (UndefinedObject True False et al)
                  1 = non-indexable objects with inst vars (Point et al)
                  2 = indexable objects with no inst vars (Array et al)
                  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
                  4 = weak indexable objects with inst vars (WeakArray et al)
                  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
                  6 unused, reserved for exotic pointer objects?
                  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
                  8 unused, reserved for exotic non-pointer objects?
                  9 (?) 64-bit indexable
                10 - 11 32-bit indexable
                12 - 15 16-bit indexable
                16 - 23 byte indexable
                24 - 31 compiled method"
        cogit CmpCq: objectMemory firstByteFormat R: formatReg.
        jumpIsBytes := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory arrayFormat R: formatReg.
        jumpIsArray := cogit JumpZero: 0.
        jumpNotIndexable := cogit JumpBelow: 0.
                                        cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
        jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
                                        cogit CmpCq: objectMemory firstShortFormat R: formatReg.
        jumpIsShorts := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory firstLongFormat R: formatReg.
        jumpIsWords := cogit JumpAboveOrEqual: 0.
        "For now ignore 64-bit indexability."
        jumpNotIndexable jmpTarget: cogit Label.
        jumpNotIndexable := cogit Jump: 0.

        jumpIsBytes jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
                cogit AndCq: objectMemory wordSize - 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
        cogit backEnd byteReadsZeroExtend
                ifTrue:
                        [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
                ifFalse:
                        [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
                                MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
                                MoveR: formatReg R: ReceiverResultReg].
        convertToIntAndReturn := cogit Label.
        self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsShorts jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
                cogit AndCq: 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddR: Arg1Reg R: ReceiverResultReg.
        cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpIsWords jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
        cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.
        cogit MoveR: TempReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpHasFixedFields jmpTarget:
                (cogit AndCq: objectMemory classIndexMask R: TempReg).
        cogit MoveR: TempReg R: formatReg.
        cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
        jumpIsContext := cogit JumpZero: 0.
        cogit PushR: ClassReg.
        self genGetClassObjectOfClassIndex: formatReg into: ClassReg scratchReg: TempReg.
        self genLoadSlot: InstanceSpecificationIndex sourceReg: ClassReg destReg: formatReg.
        cogit PopR: ClassReg.
        self genConvertSmallIntegerToIntegerInReg: formatReg.
        cogit
                AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
                SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
        "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
        cogit AddR: formatReg R: Arg1Reg.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsArray jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpFixedFieldsOutOfBounds jmpTarget:
        (jumpArrayOutOfBounds jmpTarget:
        (jumpBytesOutOfBounds jmpTarget:
        (jumpShortsOutOfBounds jmpTarget:
        (jumpWordsOutOfBounds jmpTarget:
        (jumpWordTooBig jmpTarget:
        (jumpNotIndexable jmpTarget:
        (jumpIsContext jmpTarget:
        (jumpBadIndex jmpTarget:
        (jumpImmediate jmpTarget: cogit Label))))))))).

        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
        "Implement the guts of primitiveAt"
        | formatReg convertToIntAndReturn
          jumpNotIndexable jumpImmediate jumpBadIndex
          jumpIsBytes jumpIsShorts jumpIsWords jumpIsArray jumpHasFixedFields jumpIsContext
          jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
        <inline: true>
        "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
        <var: #jumpIsBytes type: #'AbstractInstruction *'>
        <var: #jumpIsShorts type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpIsContext type: #'AbstractInstruction *'>
        <var: #jumpImmediate type: #'AbstractInstruction *'>
        <var: #jumpNotIndexable type: #'AbstractInstruction *'>
        <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
        <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
        <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>

        jumpImmediate := self genJumpImmediate: ReceiverResultReg.
        cogit MoveR: Arg0Reg R: Arg1Reg.
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
        cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"

        "formatReg := self formatOf: ReceiverResultReg"
        self genGetFormatOf: ReceiverResultReg
                into: (formatReg := SendNumArgsReg)
                leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.

        self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.

        "dispatch on format in a combination of highest dynamic frequency order first and convenience.
                  0 = 0 sized objects (UndefinedObject True False et al)
                  1 = non-indexable objects with inst vars (Point et al)
                  2 = indexable objects with no inst vars (Array et al)
                  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
                  4 = weak indexable objects with inst vars (WeakArray et al)
                  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
                  6 unused, reserved for exotic pointer objects?
                  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
                  8 unused, reserved for exotic non-pointer objects?
                  9 (?) 64-bit indexable
                10 - 11 32-bit indexable
                12 - 15 16-bit indexable
                16 - 23 byte indexable
                24 - 31 compiled method"
        cogit CmpCq: objectMemory firstByteFormat R: formatReg.
        jumpIsBytes := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory arrayFormat R: formatReg.
        jumpIsArray := cogit JumpZero: 0.
        jumpNotIndexable := cogit JumpBelow: 0.
                                        cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
        jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
                                        cogit CmpCq: objectMemory firstShortFormat R: formatReg.
        jumpIsShorts := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory firstLongFormat R: formatReg.
        jumpIsWords := cogit JumpAboveOrEqual: 0.
        "For now ignore 64-bit indexability."
        jumpNotIndexable jmpTarget: cogit Label.
        jumpNotIndexable := cogit Jump: 0.

        jumpIsBytes jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
                cogit AndCq: objectMemory wordSize - 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
        cogit backEnd byteReadsZeroExtend
                ifTrue:
                        [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
                ifFalse:
                        [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
                                MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
                                MoveR: formatReg R: ReceiverResultReg].
        convertToIntAndReturn := cogit Label.
        self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsShorts jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
                cogit AndCq: 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddR: Arg1Reg R: ReceiverResultReg.
        cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpIsWords jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >>  (objectMemory shiftForWord - 1) R: Arg1Reg.
        cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.
        cogit MoveR: TempReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpHasFixedFields jmpTarget:
                (cogit AndCq: objectMemory classIndexMask R: TempReg).
        cogit MoveR: TempReg R: formatReg.
        cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
        jumpIsContext := cogit JumpZero: 0.
        self genGetClassObjectOfClassIndex: formatReg into: Scratch0Reg scratchReg: TempReg.
        self genLoadSlot: InstanceSpecificationIndex sourceReg: Scratch0Reg destReg: formatReg.
        self genConvertSmallIntegerToIntegerInReg: formatReg.
        cogit
                AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
                SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
        "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
        cogit AddR: formatReg R: Arg1Reg.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsArray jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpFixedFieldsOutOfBounds jmpTarget:
        (jumpArrayOutOfBounds jmpTarget:
        (jumpBytesOutOfBounds jmpTarget:
        (jumpShortsOutOfBounds jmpTarget:
        (jumpWordsOutOfBounds jmpTarget:
        (jumpNotIndexable jmpTarget:
        (jumpIsContext jmpTarget:
        (jumpBadIndex jmpTarget:
        (jumpImmediate jmpTarget: cogit Label)))))))).

        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveNewWithArg: (in category 'primitive generators') -----
  genInnerPrimitiveNewWithArg: retNoffset
        "Implement primitiveNewWithArg for convenient cases:
        - the receiver has a hash
        - the receiver is variable and not compiled method
        - single word header/num slots < numSlotsMask
        - the result fits in eden
        See superclass method for dynamic frequencies of formats.
        For the moment we implement only arrayFormat, firstByteFormat & firstLongFormat"

        | headerReg fillReg instSpecReg byteSizeReg maxSlots
          jumpArrayTooBig jumpByteTooBig jumpLongTooBig
          jumpArrayFormat jumpByteFormat jumpBytePrepDone jumpLongPrepDone
          jumpUnhashed jumpNElementsNonInt jumpFailCuzFixed jumpNoSpace jumpHasSlots fillLoop skip |
        <var: 'skip' type: #'AbstractInstruction *'>
        <var: 'fillLoop' type: #'AbstractInstruction *'>
        <var: 'jumpHasSlots' type: #'AbstractInstruction *'>
        <var: 'jumpNoSpace' type: #'AbstractInstruction *'>
        <var: 'jumpUnhashed' type: #'AbstractInstruction *'>
        <var: 'jumpByteFormat' type: #'AbstractInstruction *'>
        <var: 'jumpByteTooBig' type: #'AbstractInstruction *'>
        <var: 'jumpLongTooBig' type: #'AbstractInstruction *'>
        <var: 'jumpArrayFormat' type: #'AbstractInstruction *'>
        <var: 'jumpArrayTooBig' type: #'AbstractInstruction *'>
        <var: 'jumpFailCuzFixed' type: #'AbstractInstruction *'>
        <var: 'jumpBytePrepDone' type: #'AbstractInstruction *'>
        <var: 'jumpLongPrepDone' type: #'AbstractInstruction *'>
        <var: 'jumpNElementsNonInt' type: #'AbstractInstruction *'>

        "header will contain classIndex/class's hash & format & numSlots/fixed size"
        headerReg := SendNumArgsReg.
        "Assume there's an available scratch register on 64-bit machines.  This holds the saved numFixedFileds and then the value to fill with"
        fillReg := Scratch0Reg.
        self assert: (cogit backEnd concreteRegister: fillReg) > 0.
        "inst spec will hold class's instance specification and then byte size"
        instSpecReg := byteSizeReg := ClassReg.
        "The max slots we'll allocate here are those for a single header"
        maxSlots := objectMemory numSlotsMask - 1.

        "get freeStart as early as possible so as not to wait later..."
        cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
        "get class's hash & fail if 0"
        self genGetHashFieldNonImmOf: ReceiverResultReg into: headerReg.
        jumpUnhashed := cogit JumpZero: 0.
        "get index and fail if not a +ve integer"
+       jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        "get class's format inst var for inst spec (format field)"
        self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: instSpecReg.
        cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth + self numSmallIntegerTagBits R: instSpecReg.
        cogit AndCq: objectMemory formatMask R: instSpecReg.
        "Add format to classIndex/format header now"
        cogit MoveR: instSpecReg R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "get integer value of num fields in fillReg now"
        cogit MoveR: Arg0Reg R: fillReg.
        self genConvertSmallIntegerToIntegerInReg: fillReg.
        "dispatch on format, failing if not variable or if compiled method"
        cogit CmpCq: objectMemory arrayFormat R: instSpecReg.
        jumpArrayFormat := cogit JumpZero: 0.
        cogit CmpCq: objectMemory firstByteFormat R: instSpecReg.
        jumpByteFormat := cogit JumpZero: 0.
        cogit CmpCq: objectMemory firstLongFormat R: instSpecReg.
        jumpFailCuzFixed := cogit JumpNonZero: 0.

        cogit CmpCq: (objectMemory integerObjectOf: maxSlots * 2) R: Arg0Reg.
        jumpLongTooBig := cogit JumpAbove: 0.
        "save num elements/slot size to instSpecReg"
        cogit MoveR: fillReg R: instSpecReg.
        "compute odd bits and add into headerReg; oddBits := 2 - nElements bitAnd: 1"
        cogit MoveCq: objectMemory wordSize / 4 R: TempReg.
        cogit SubR: instSpecReg R: TempReg.
        cogit AndCq: objectMemory wordSize / 4 - 1 R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "round up num elements to numSlots in instSpecReg"
        cogit AddCq: objectMemory wordSize / 4 - 1 R: instSpecReg.
        cogit LogicalShiftRightCq: objectMemory shiftForWord - 2 R: instSpecReg.
        cogit MoveCq: 0 R: fillReg.
        jumpLongPrepDone := cogit Jump: 0. "go allocate"

        jumpByteFormat jmpTarget:
        (cogit CmpCq: (objectMemory integerObjectOf: maxSlots * objectMemory wordSize) R: Arg0Reg).
        jumpByteTooBig := cogit JumpAbove: 0.
        "save num elements to instSpecReg"
        cogit MoveR: fillReg R: instSpecReg.
        "compute odd bits and add into headerReg; oddBits := 4 - nElements bitAnd: 3"
        cogit MoveCq: objectMemory wordSize R: TempReg.
        cogit SubR: instSpecReg R: TempReg.
        cogit AndCq: objectMemory wordSize - 1 R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "round up num elements to numSlots in instSpecReg"
        cogit AddCq: objectMemory wordSize - 1 R: instSpecReg.
        cogit LogicalShiftRightCq: objectMemory shiftForWord R: instSpecReg.
        cogit MoveCq: 0 R: fillReg.
        jumpBytePrepDone := cogit Jump: 0. "go allocate"

        jumpArrayFormat jmpTarget:
                (cogit CmpCq: (objectMemory integerObjectOf: maxSlots) R: Arg0Reg).
        jumpArrayTooBig := cogit JumpAbove: 0.
        "save num elements/slot size to instSpecReg"
        cogit MoveR: fillReg R: instSpecReg.
        cogit MoveCq: objectMemory nilObject R: fillReg.
        "fall through to allocate"

        jumpBytePrepDone jmpTarget:
        (jumpLongPrepDone jmpTarget: cogit Label).

        "store numSlots to headerReg"
        cogit MoveR: instSpecReg R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory numSlotsFullShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "compute byte size; remember 0-sized objects still need 1 slot."
        cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"
        jumpHasSlots := cogit JumpNonZero: 0.
        cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.
        skip := cogit Jump: 0.
        jumpHasSlots jmpTarget:
        (cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg).
        cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.
        skip jmpTarget:
        "check if allocation fits"
        (cogit AddR: Arg1Reg R: byteSizeReg).
        cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
        jumpNoSpace := cogit JumpAboveOrEqual: 0.
        "get result, increment freeStart and write it back. Arg1Reg holds new freeStart, the limit of the object"
        cogit MoveR: Arg1Reg R: ReceiverResultReg.
        cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
        "write other half of header (numSlots/0 identityHash)"
        cogit MoveR: headerReg Mw: 0 r: ReceiverResultReg.
        "now fill"
        cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
        fillLoop :=
        cogit MoveR: fillReg Mw: 0 r: Arg1Reg.
        cogit AddCq: 8 R: Arg1Reg.
        cogit CmpR: Arg1Reg R: byteSizeReg.
        cogit JumpAbove: fillLoop.
        cogit RetN: retNoffset.

        jumpNoSpace jmpTarget:
        (jumpUnhashed jmpTarget:
        (jumpFailCuzFixed jmpTarget:
        (jumpArrayTooBig jmpTarget:
        (jumpByteTooBig jmpTarget:
        (jumpLongTooBig jmpTarget:
        (jumpNElementsNonInt jmpTarget: cogit Label)))))).

        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveAsCharacter:inReg: (in category 'primitive generators') -----
  genInnerPrimitiveAsCharacter: retNOffset inReg: reg
        | jumpNotInt jumpOutOfRange |
        <var: 'jumpNotInt' type: #'AbstractInstruction *'>
        <var: 'jumpOutOfRange' type: #'AbstractInstruction *'>
        reg ~= ReceiverResultReg ifTrue:
+               [jumpNotInt := self genJumpNotSmallInteger: reg scratchReg: TempReg].
-               [jumpNotInt := self genJumpNotSmallInteger: reg scratch: TempReg].
        cogit MoveR: reg R: TempReg.
        self genConvertSmallIntegerToIntegerInReg: TempReg.
        cogit CmpCq: 1 << 30 - 1 R: TempReg.
        jumpOutOfRange := cogit JumpAbove: 0.
        self genConvertSmallIntegerToCharacterInReg: reg.
        reg ~= ReceiverResultReg ifTrue:
                [cogit MoveR: reg R: ReceiverResultReg].
        cogit RetN: retNOffset.
        jumpOutOfRange jmpTarget: cogit Label.
        reg ~= ReceiverResultReg ifTrue:
                [jumpNotInt jmpTarget: jumpOutOfRange getJmpTarget].
        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveObjectAt: (in category 'primitive generators') -----
  genInnerPrimitiveObjectAt: retNOffset
        | headerReg
          jumpBadIndex jumpNotCogMethod jumpBounds jumpNotHeaderIndex |
        <var: #jumpBounds type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpNotCogMethod type: #'AbstractInstruction *'>
        <var: #jumpNotHeaderIndex type: #'AbstractInstruction *'>
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        "get header into Arg1Reg..."
        cogit MoveMw: objectMemory baseHeaderSize r: ReceiverResultReg R: (headerReg := Arg1Reg).
+       jumpNotCogMethod := self genJumpSmallInteger: headerReg scratchReg: TempReg.
-       jumpNotCogMethod := self genJumpSmallInteger: headerReg scratch: TempReg.
        cogit MoveMw: (cogit offset: CogMethod of: #methodHeader) r: headerReg R: headerReg.
        jumpNotCogMethod jmpTarget: (cogit
                CmpCq: (objectMemory integerObjectOf: 1) R: Arg0Reg).
        jumpNotHeaderIndex := cogit JumpNonZero: 0.
        cogit
                MoveR: headerReg R: ReceiverResultReg;
                RetN: retNOffset.
        jumpNotHeaderIndex jmpTarget: (cogit
                AndCq: (objectMemory integerObjectOf: coInterpreter alternateHeaderNumLiteralsMask) R: headerReg).
        cogit
                SubCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg;
                CmpR: headerReg R: Arg0Reg.
        jumpBounds := cogit JumpAbove: 0.

        self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
        cogit
                AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg;
                MoveXwr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg;
                RetN: retNOffset.

        jumpBounds jmpTarget: (cogit
                AddCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg).
        jumpBadIndex jmpTarget: cogit Label.
        ^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
  genInnerPrimitiveStringAt: retNoffset
        "Implement the guts of primitiveStringAt; dispatch on size"
        | formatReg jumpNotIndexable jumpBadIndex done
          jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig
          jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
        <inline: true>
        "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
        <var: #done type: #'AbstractInstruction *'>
        <var: #jumpIsBytes type: #'AbstractInstruction *'>
        <var: #jumpIsShorts type: #'AbstractInstruction *'>
        <var: #jumpIsWords type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpWordTooBig type: #'AbstractInstruction *'>
        <var: #jumpNotIndexable type: #'AbstractInstruction *'>
        <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>

        cogit MoveR: Arg0Reg R: Arg1Reg.
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
        cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"

        self genGetFormatOf: ReceiverResultReg
                into: (formatReg := SendNumArgsReg)
                leastSignificantHalfOfBaseHeaderIntoScratch: NoReg.

        self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.

        "dispatch on format in a combination of highest dynamic frequency order first and convenience.
                  0 = 0 sized objects (UndefinedObject True False et al)
                  1 = non-indexable objects with inst vars (Point et al)
                  2 = indexable objects with no inst vars (Array et al)
                  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
                  4 = weak indexable objects with inst vars (WeakArray et al)
                  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
                  6 unused, reserved for exotic pointer objects?
                  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
                  8 unused, reserved for exotic non-pointer objects?
                  9 (?) 64-bit indexable
                10 - 11 32-bit indexable
                12 - 15 16-bit indexable
                16 - 23 byte indexable
                24 - 31 compiled method"
        cogit CmpCq: objectMemory firstByteFormat R: formatReg.
        jumpIsBytes := cogit JumpGreaterOrEqual: 0.
                                        cogit CmpCq: objectMemory firstShortFormat R: formatReg.
        jumpIsShorts := cogit JumpGreaterOrEqual: 0.
                                        cogit CmpCq: objectMemory firstLongFormat R: formatReg.
        jumpIsWords := cogit JumpGreaterOrEqual: 0.
        jumpNotIndexable := cogit Jump: 0.

        jumpIsBytes jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
                cogit AndCq: objectMemory wordSize - 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
        cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit backEnd byteReadsZeroExtend ifFalse:
                        [cogit AndCq: 255 R: ReceiverResultReg].
        done := cogit Label.
        self genConvertIntegerToCharacterInReg: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsShorts jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
                cogit AndCq: 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddR: Arg1Reg R: ReceiverResultReg.
        cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
        cogit Jump: done.

        jumpIsWords jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
        cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
        cogit MoveR: TempReg R: ReceiverResultReg.
        cogit Jump: done.

        jumpBytesOutOfBounds jmpTarget:
        (jumpShortsOutOfBounds jmpTarget:
        (jumpWordsOutOfBounds jmpTarget:
        (jumpWordTooBig jmpTarget:
        (jumpNotIndexable jmpTarget:
        (jumpBadIndex jmpTarget: cogit Label))))).

        ^0!

Item was changed:
  ----- Method: Cogit>>AndCq:R:R: (in category 'abstract instructions') -----
  AndCq: quickConstant R: srcReg R: destReg
+       <inline: false>
-       <inline: true>
        <returnTypeC: #'AbstractInstruction *'>
        | first |
        <var: 'first' type: #'AbstractInstruction *'>
        backEnd hasThreeAddressArithmetic ifTrue:
                [^self gen: AndCqRR quickConstant: quickConstant operand: srcReg operand: destReg].
        srcReg = destReg ifTrue:
                [^self gen: AndCqR quickConstant: quickConstant operand: destReg.].
        first := self gen: MoveRR operand: srcReg operand: destReg.
        self gen: AndCqR quickConstant: quickConstant operand: destReg.
        ^first!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>checkQuickConstant:forInstruction: (in category 'compile abstract instructions') -----
  checkQuickConstant: literal forInstruction: anInstruction
        <var: #anInstruction type: #'AbstractInstruction *'>
        <returnTypeC: #'AbstractInstruction *'>
+       <inline: true>
        anInstruction usesOutOfLineLiteral ifTrue:
+               [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 1 << (objectMemory wordSize * 8) - 1]))].
-               [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 16rFFFFFFFF]))].
        ^anInstruction!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
  genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
        "Receiver and arg in registers.
         Stack looks like
                return address"
        <var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
        | jumpFailClass jumpFailClass2 jumpFailAlloc jumpFailCheck jumpImmediate jumpNonInt doOp |
        <var: #jumpFailClass type: #'AbstractInstruction *'>
        <var: #jumpFailClass2 type: #'AbstractInstruction *'>
        <var: #jumpFailAlloc type: #'AbstractInstruction *'>
        <var: #jumpImmediate type: #'AbstractInstruction *'>
        <var: #jumpNonInt type: #'AbstractInstruction *'>
        <var: #jumpFailCheck type: #'AbstractInstruction *'>
        <var: #doOp type: #'AbstractInstruction *'>
        objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
        self MoveR: Arg0Reg R: ClassReg.
        jumpImmediate := objectRepresentation genJumpImmediate: Arg0Reg.
        objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
        objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
        jumpFailClass := self JumpNonZero: 0.
        objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
        doOp := self Label.
        preOpCheckOrNil ifNotNil:
                [jumpFailCheck := self perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].
        self gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
        jumpFailAlloc := objectRepresentation
                                                genAllocFloatValue: DPFPReg0
                                                into: SendNumArgsReg
                                                scratchReg: ClassReg
                                                scratchReg: TempReg.
        self MoveR: SendNumArgsReg R: ReceiverResultReg.
        self RetN: 0.
        jumpImmediate jmpTarget: self Label.
        objectRepresentation maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: doOp.
        objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
+               [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].
-               [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratch: TempReg].
        objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
        self ConvertR: ClassReg Rd: DPFPReg1.
        self Jump: doOp.
        "We need to push the register args on two paths; this one and the interpreter primitive path.
        But the interpreter primitive path won't unless regArgsHaveBeenPushed is false."
        self assert: methodOrBlockNumArgs <= self numRegArgs.
        jumpFailClass jmpTarget: self Label.
        objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
                [jumpNonInt jmpTarget: jumpFailClass getJmpTarget].
        preOpCheckOrNil ifNotNil:
                [jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].
        backEnd genPushRegisterArgsForNumArgs: methodOrBlockNumArgs scratchReg: SendNumArgsReg.
        jumpFailClass2 := self Jump: 0.
        jumpFailAlloc jmpTarget: self Label.
        self compileFallbackToInterpreterPrimitive: 0.
        jumpFailClass2 jmpTarget: self Label.
        ^0!

Item was changed:
  ----- Method: TReturnNode>>emitCCodeOn:level:generator: (in category 'C code generation') -----
  emitCCodeOn: aStream level: level generator: aCodeGen

        (expression isSwitch
         or: [expression isCaseStmt]) ifTrue:
                [^expression emitCCodeOn: aStream addToEndOfCases: self level: level generator: aCodeGen].

        (expression isSend and: [expression isValueExpansion]) ifTrue:
                [^self emitValueExpansionOn: aStream level: level generator: aCodeGen].

        'void' = aCodeGen currentMethod returnType ifTrue: "If the function is void, don't say 'return x' instead say ' x; return' "
                [expression isLeaf ifFalse:
                        [expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen.
                         aStream nextPut: $;; crtab: level].
                 aStream nextPutAll: 'return'.
                 ^self].
        aStream nextPutAll: 'return '.
+       expression
+               emitCCodeAsArgumentOn: aStream
+               level: (expression isStmtList ifTrue: [level + 1] ifFalse: [level])
+               generator: aCodeGen!
-       expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen!

Item was changed:
  ----- Method: TStmtListNode>>emitCCodeAsArgumentOn:level:generator: (in category 'C code generation') -----
  emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen
+       | size |
+       (size := statements size) = 1 ifTrue:
-
-       | statementWasComment |
-       statements size = 1 ifTrue:
                [^statements first emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen].
-       statementWasComment := false.
        aStream nextPut: $(. "N.B.  Comma binds weakest of all C operators."
+       statements withIndexDo:
+               [:s :idx| | p1 p2 |
+               p1 := aStream position.
+               s emitCCommentOn: aStream level: level.
+               (s isLeaf and: [s isLabel not and: [idx < statements size]]) ifFalse:
+                       [s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen].
+               p2 := aStream position.
+               (idx < size and: [p2 > p1]) ifTrue:
-       statements
-               do:
-                       [:s |
-                       s emitCCommentOn: aStream level: level.
-                       s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen.
-                       statementWasComment := s isComment]
-               separatedBy:
                        [((self endsWithCloseBracket: aStream)
+                         or: [s isComment]) ifFalse: [aStream nextPut: $,].
+                        aStream crtab: level]].
-                         or: [statementWasComment]) ifFalse: [aStream nextPut: $,].
-                       aStream crtab: level].
        aStream nextPut: $)!


Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1594.mcz

Eliot Miranda-2
 
Hi Ryan, sorry about the instability.  It's just while I get the x64 JIT to work.  I expect to have the builds fixed today (wed) or tmrw at the latest

_,,,^..^,,,_ (phone)

On Dec 13, 2015, at 6:27 PM, Ryan Macnak <[hidden email]> wrote:

JIT builds still failing.

/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c: In function ‘genNSSendnumArgsdepthsendTable’:
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23996:15: warning: assignment makes integer from pointer without a cast [enabled by default]
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23997:10: error: called object ‘selector’ is not a function
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23998:9: error: called object ‘numArgs’ is not a function
/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23999:7: error: called object ‘depth’ is not a function

On Sun, Dec 13, 2015 at 5:25 PM, <[hidden email]> wrote:

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1594.mcz

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

Name: VMMaker.oscog-eem.1594
Author: eem
Time: 13 December 2015, 5:24:57.076 pm
UUID: 79da8b81-d1f3-469a-869c-16c79d12649a
Ancestors: VMMaker.oscog-eem.1593

Cogit:
Don't inline AndCq:R:R: because its translation contains a jump and hence won't work in a statement list expression (e.g. as in x86's genJumpSmallInteger:scratchReg:).

Nuke genJump[Not]SmallInteger:scratch: in favour of genJump[Not]SmallInteger:scratchReg:

Slang:
Eliminate leaves in statement lists generated as expressions.

=============== Diff against VMMaker.oscog-eem.1593 ===============

Item was removed:
- ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratch: (in category 'compile abstract instructions') -----
- genJumpNotSmallInteger: aRegister scratch: scratchReg
-       "Generate a test for aRegister containing a SmallInteger and a jump if not, answering the jump.
-        If necessary use scratch reg (since testing for SmallInteger may be destructive)."
-       <returnTypeC: #'AbstractInstruction *'>
-       | jumpNotInt |
-       <inline: true>
-       <var: 'jumpNotInt' type: #'AbstractInstruction *'>
-       jumpNotInt := self genJumpNotSmallInteger: aRegister.
-       jumpNotInt asInteger = UnimplementedOperation ifTrue:
-               [cogit MoveR: aRegister R: scratchReg.
-                jumpNotInt := self genJumpNotSmallIntegerInScratchReg: TempReg].
-       ^jumpNotInt!

Item was changed:
  ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratchReg: (in category 'compile abstract instructions') -----
  genJumpNotSmallInteger: aRegister scratchReg: scratch
        "Generate a compare and branch to test if aRegister contains other than a SmallInteger.
         Answer the jump.  Use scratch if required.  Subclasses will override if scratch is needed."
+       <inline: true>
-       <returnTypeC: #'AbstractInstruction *'>
        ^self genJumpNotSmallInteger: aRegister!

Item was removed:
- ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratch: (in category 'compile abstract instructions') -----
- genJumpSmallInteger: aRegister scratch: scratchReg
-       "Generate a test for aRegister containing a SmallInteger and a jump if so, answering the jump.
-        If necessary use scratch reg (since testing for SmallInteger may be destructive)."
-       <returnTypeC: #'AbstractInstruction *'>
-       | jumpInt |
-       <inline: true>
-       <var: 'jumpInt' type: #'AbstractInstruction *'>
-       jumpInt := self genJumpSmallInteger: aRegister.
-       jumpInt asInteger = UnimplementedOperation ifTrue:
-               [cogit MoveR: aRegister R: scratchReg.
-                jumpInt := self genJumpSmallIntegerInScratchReg: TempReg].
-       ^jumpInt!

Item was changed:
  ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratchReg: (in category 'compile abstract instructions') -----
  genJumpSmallInteger: aRegister scratchReg: scratch
        "Generate a compare and branch to test if aRegister contains a SmallInteger.
         Answer the jump.  Use scratch if required.  Subclasses will override if scratch is needed."
-       <returnTypeC: #'AbstractInstruction *'>
        ^self genJumpSmallInteger: aRegister!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
        "Implement the guts of primitiveAt"
        | formatReg convertToIntAndReturn
          jumpNotIndexable jumpImmediate jumpBadIndex
          jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext
          jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
        <inline: true>
        "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
        <var: #jumpIsBytes type: #'AbstractInstruction *'>
        <var: #jumpIsShorts type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpIsContext type: #'AbstractInstruction *'>
        <var: #jumpImmediate type: #'AbstractInstruction *'>
        <var: #jumpWordTooBig type: #'AbstractInstruction *'>
        <var: #jumpNotIndexable type: #'AbstractInstruction *'>
        <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
        <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
        <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>

        jumpImmediate := self genJumpImmediate: ReceiverResultReg.
        cogit MoveR: Arg0Reg R: Arg1Reg.
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
        cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"

        "formatReg := self formatOf: ReceiverResultReg"
        self genGetFormatOf: ReceiverResultReg
                into: (formatReg := SendNumArgsReg)
                leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.

        self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.

        "dispatch on format in a combination of highest dynamic frequency order first and convenience.
                  0 = 0 sized objects (UndefinedObject True False et al)
                  1 = non-indexable objects with inst vars (Point et al)
                  2 = indexable objects with no inst vars (Array et al)
                  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
                  4 = weak indexable objects with inst vars (WeakArray et al)
                  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
                  6 unused, reserved for exotic pointer objects?
                  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
                  8 unused, reserved for exotic non-pointer objects?
                  9 (?) 64-bit indexable
                10 - 11 32-bit indexable
                12 - 15 16-bit indexable
                16 - 23 byte indexable
                24 - 31 compiled method"
        cogit CmpCq: objectMemory firstByteFormat R: formatReg.
        jumpIsBytes := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory arrayFormat R: formatReg.
        jumpIsArray := cogit JumpZero: 0.
        jumpNotIndexable := cogit JumpBelow: 0.
                                        cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
        jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
                                        cogit CmpCq: objectMemory firstShortFormat R: formatReg.
        jumpIsShorts := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory firstLongFormat R: formatReg.
        jumpIsWords := cogit JumpAboveOrEqual: 0.
        "For now ignore 64-bit indexability."
        jumpNotIndexable jmpTarget: cogit Label.
        jumpNotIndexable := cogit Jump: 0.

        jumpIsBytes jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
                cogit AndCq: objectMemory wordSize - 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
        cogit backEnd byteReadsZeroExtend
                ifTrue:
                        [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
                ifFalse:
                        [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
                                MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
                                MoveR: formatReg R: ReceiverResultReg].
        convertToIntAndReturn := cogit Label.
        self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsShorts jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
                cogit AndCq: 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddR: Arg1Reg R: ReceiverResultReg.
        cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpIsWords jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
        cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.
        cogit MoveR: TempReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpHasFixedFields jmpTarget:
                (cogit AndCq: objectMemory classIndexMask R: TempReg).
        cogit MoveR: TempReg R: formatReg.
        cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
        jumpIsContext := cogit JumpZero: 0.
        cogit PushR: ClassReg.
        self genGetClassObjectOfClassIndex: formatReg into: ClassReg scratchReg: TempReg.
        self genLoadSlot: InstanceSpecificationIndex sourceReg: ClassReg destReg: formatReg.
        cogit PopR: ClassReg.
        self genConvertSmallIntegerToIntegerInReg: formatReg.
        cogit
                AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
                SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
        "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
        cogit AddR: formatReg R: Arg1Reg.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsArray jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpFixedFieldsOutOfBounds jmpTarget:
        (jumpArrayOutOfBounds jmpTarget:
        (jumpBytesOutOfBounds jmpTarget:
        (jumpShortsOutOfBounds jmpTarget:
        (jumpWordsOutOfBounds jmpTarget:
        (jumpWordTooBig jmpTarget:
        (jumpNotIndexable jmpTarget:
        (jumpIsContext jmpTarget:
        (jumpBadIndex jmpTarget:
        (jumpImmediate jmpTarget: cogit Label))))))))).

        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
        "Implement the guts of primitiveAt"
        | formatReg convertToIntAndReturn
          jumpNotIndexable jumpImmediate jumpBadIndex
          jumpIsBytes jumpIsShorts jumpIsWords jumpIsArray jumpHasFixedFields jumpIsContext
          jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
        <inline: true>
        "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
        <var: #jumpIsBytes type: #'AbstractInstruction *'>
        <var: #jumpIsShorts type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpIsContext type: #'AbstractInstruction *'>
        <var: #jumpImmediate type: #'AbstractInstruction *'>
        <var: #jumpNotIndexable type: #'AbstractInstruction *'>
        <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
        <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
        <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>

        jumpImmediate := self genJumpImmediate: ReceiverResultReg.
        cogit MoveR: Arg0Reg R: Arg1Reg.
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
        cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"

        "formatReg := self formatOf: ReceiverResultReg"
        self genGetFormatOf: ReceiverResultReg
                into: (formatReg := SendNumArgsReg)
                leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.

        self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.

        "dispatch on format in a combination of highest dynamic frequency order first and convenience.
                  0 = 0 sized objects (UndefinedObject True False et al)
                  1 = non-indexable objects with inst vars (Point et al)
                  2 = indexable objects with no inst vars (Array et al)
                  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
                  4 = weak indexable objects with inst vars (WeakArray et al)
                  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
                  6 unused, reserved for exotic pointer objects?
                  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
                  8 unused, reserved for exotic non-pointer objects?
                  9 (?) 64-bit indexable
                10 - 11 32-bit indexable
                12 - 15 16-bit indexable
                16 - 23 byte indexable
                24 - 31 compiled method"
        cogit CmpCq: objectMemory firstByteFormat R: formatReg.
        jumpIsBytes := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory arrayFormat R: formatReg.
        jumpIsArray := cogit JumpZero: 0.
        jumpNotIndexable := cogit JumpBelow: 0.
                                        cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
        jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
                                        cogit CmpCq: objectMemory firstShortFormat R: formatReg.
        jumpIsShorts := cogit JumpAboveOrEqual: 0.
                                        cogit CmpCq: objectMemory firstLongFormat R: formatReg.
        jumpIsWords := cogit JumpAboveOrEqual: 0.
        "For now ignore 64-bit indexability."
        jumpNotIndexable jmpTarget: cogit Label.
        jumpNotIndexable := cogit Jump: 0.

        jumpIsBytes jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
                cogit AndCq: objectMemory wordSize - 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
        cogit backEnd byteReadsZeroExtend
                ifTrue:
                        [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
                ifFalse:
                        [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
                                MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
                                MoveR: formatReg R: ReceiverResultReg].
        convertToIntAndReturn := cogit Label.
        self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsShorts jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
                cogit AndCq: 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddR: Arg1Reg R: ReceiverResultReg.
        cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpIsWords jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >>  (objectMemory shiftForWord - 1) R: Arg1Reg.
        cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.
        cogit MoveR: TempReg R: ReceiverResultReg.
        cogit Jump: convertToIntAndReturn.

        jumpHasFixedFields jmpTarget:
                (cogit AndCq: objectMemory classIndexMask R: TempReg).
        cogit MoveR: TempReg R: formatReg.
        cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
        jumpIsContext := cogit JumpZero: 0.
        self genGetClassObjectOfClassIndex: formatReg into: Scratch0Reg scratchReg: TempReg.
        self genLoadSlot: InstanceSpecificationIndex sourceReg: Scratch0Reg destReg: formatReg.
        self genConvertSmallIntegerToIntegerInReg: formatReg.
        cogit
                AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
                SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
        "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
        cogit AddR: formatReg R: Arg1Reg.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsArray jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpFixedFieldsOutOfBounds jmpTarget:
        (jumpArrayOutOfBounds jmpTarget:
        (jumpBytesOutOfBounds jmpTarget:
        (jumpShortsOutOfBounds jmpTarget:
        (jumpWordsOutOfBounds jmpTarget:
        (jumpNotIndexable jmpTarget:
        (jumpIsContext jmpTarget:
        (jumpBadIndex jmpTarget:
        (jumpImmediate jmpTarget: cogit Label)))))))).

        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveNewWithArg: (in category 'primitive generators') -----
  genInnerPrimitiveNewWithArg: retNoffset
        "Implement primitiveNewWithArg for convenient cases:
        - the receiver has a hash
        - the receiver is variable and not compiled method
        - single word header/num slots < numSlotsMask
        - the result fits in eden
        See superclass method for dynamic frequencies of formats.
        For the moment we implement only arrayFormat, firstByteFormat & firstLongFormat"

        | headerReg fillReg instSpecReg byteSizeReg maxSlots
          jumpArrayTooBig jumpByteTooBig jumpLongTooBig
          jumpArrayFormat jumpByteFormat jumpBytePrepDone jumpLongPrepDone
          jumpUnhashed jumpNElementsNonInt jumpFailCuzFixed jumpNoSpace jumpHasSlots fillLoop skip |
        <var: 'skip' type: #'AbstractInstruction *'>
        <var: 'fillLoop' type: #'AbstractInstruction *'>
        <var: 'jumpHasSlots' type: #'AbstractInstruction *'>
        <var: 'jumpNoSpace' type: #'AbstractInstruction *'>
        <var: 'jumpUnhashed' type: #'AbstractInstruction *'>
        <var: 'jumpByteFormat' type: #'AbstractInstruction *'>
        <var: 'jumpByteTooBig' type: #'AbstractInstruction *'>
        <var: 'jumpLongTooBig' type: #'AbstractInstruction *'>
        <var: 'jumpArrayFormat' type: #'AbstractInstruction *'>
        <var: 'jumpArrayTooBig' type: #'AbstractInstruction *'>
        <var: 'jumpFailCuzFixed' type: #'AbstractInstruction *'>
        <var: 'jumpBytePrepDone' type: #'AbstractInstruction *'>
        <var: 'jumpLongPrepDone' type: #'AbstractInstruction *'>
        <var: 'jumpNElementsNonInt' type: #'AbstractInstruction *'>

        "header will contain classIndex/class's hash & format & numSlots/fixed size"
        headerReg := SendNumArgsReg.
        "Assume there's an available scratch register on 64-bit machines.  This holds the saved numFixedFileds and then the value to fill with"
        fillReg := Scratch0Reg.
        self assert: (cogit backEnd concreteRegister: fillReg) > 0.
        "inst spec will hold class's instance specification and then byte size"
        instSpecReg := byteSizeReg := ClassReg.
        "The max slots we'll allocate here are those for a single header"
        maxSlots := objectMemory numSlotsMask - 1.

        "get freeStart as early as possible so as not to wait later..."
        cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
        "get class's hash & fail if 0"
        self genGetHashFieldNonImmOf: ReceiverResultReg into: headerReg.
        jumpUnhashed := cogit JumpZero: 0.
        "get index and fail if not a +ve integer"
+       jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        "get class's format inst var for inst spec (format field)"
        self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: instSpecReg.
        cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth + self numSmallIntegerTagBits R: instSpecReg.
        cogit AndCq: objectMemory formatMask R: instSpecReg.
        "Add format to classIndex/format header now"
        cogit MoveR: instSpecReg R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "get integer value of num fields in fillReg now"
        cogit MoveR: Arg0Reg R: fillReg.
        self genConvertSmallIntegerToIntegerInReg: fillReg.
        "dispatch on format, failing if not variable or if compiled method"
        cogit CmpCq: objectMemory arrayFormat R: instSpecReg.
        jumpArrayFormat := cogit JumpZero: 0.
        cogit CmpCq: objectMemory firstByteFormat R: instSpecReg.
        jumpByteFormat := cogit JumpZero: 0.
        cogit CmpCq: objectMemory firstLongFormat R: instSpecReg.
        jumpFailCuzFixed := cogit JumpNonZero: 0.

        cogit CmpCq: (objectMemory integerObjectOf: maxSlots * 2) R: Arg0Reg.
        jumpLongTooBig := cogit JumpAbove: 0.
        "save num elements/slot size to instSpecReg"
        cogit MoveR: fillReg R: instSpecReg.
        "compute odd bits and add into headerReg; oddBits := 2 - nElements bitAnd: 1"
        cogit MoveCq: objectMemory wordSize / 4 R: TempReg.
        cogit SubR: instSpecReg R: TempReg.
        cogit AndCq: objectMemory wordSize / 4 - 1 R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "round up num elements to numSlots in instSpecReg"
        cogit AddCq: objectMemory wordSize / 4 - 1 R: instSpecReg.
        cogit LogicalShiftRightCq: objectMemory shiftForWord - 2 R: instSpecReg.
        cogit MoveCq: 0 R: fillReg.
        jumpLongPrepDone := cogit Jump: 0. "go allocate"

        jumpByteFormat jmpTarget:
        (cogit CmpCq: (objectMemory integerObjectOf: maxSlots * objectMemory wordSize) R: Arg0Reg).
        jumpByteTooBig := cogit JumpAbove: 0.
        "save num elements to instSpecReg"
        cogit MoveR: fillReg R: instSpecReg.
        "compute odd bits and add into headerReg; oddBits := 4 - nElements bitAnd: 3"
        cogit MoveCq: objectMemory wordSize R: TempReg.
        cogit SubR: instSpecReg R: TempReg.
        cogit AndCq: objectMemory wordSize - 1 R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "round up num elements to numSlots in instSpecReg"
        cogit AddCq: objectMemory wordSize - 1 R: instSpecReg.
        cogit LogicalShiftRightCq: objectMemory shiftForWord R: instSpecReg.
        cogit MoveCq: 0 R: fillReg.
        jumpBytePrepDone := cogit Jump: 0. "go allocate"

        jumpArrayFormat jmpTarget:
                (cogit CmpCq: (objectMemory integerObjectOf: maxSlots) R: Arg0Reg).
        jumpArrayTooBig := cogit JumpAbove: 0.
        "save num elements/slot size to instSpecReg"
        cogit MoveR: fillReg R: instSpecReg.
        cogit MoveCq: objectMemory nilObject R: fillReg.
        "fall through to allocate"

        jumpBytePrepDone jmpTarget:
        (jumpLongPrepDone jmpTarget: cogit Label).

        "store numSlots to headerReg"
        cogit MoveR: instSpecReg R: TempReg.
        cogit LogicalShiftLeftCq: objectMemory numSlotsFullShift R: TempReg.
        cogit AddR: TempReg R: headerReg.
        "compute byte size; remember 0-sized objects still need 1 slot."
        cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"
        jumpHasSlots := cogit JumpNonZero: 0.
        cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.
        skip := cogit Jump: 0.
        jumpHasSlots jmpTarget:
        (cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg).
        cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.
        skip jmpTarget:
        "check if allocation fits"
        (cogit AddR: Arg1Reg R: byteSizeReg).
        cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
        jumpNoSpace := cogit JumpAboveOrEqual: 0.
        "get result, increment freeStart and write it back. Arg1Reg holds new freeStart, the limit of the object"
        cogit MoveR: Arg1Reg R: ReceiverResultReg.
        cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
        "write other half of header (numSlots/0 identityHash)"
        cogit MoveR: headerReg Mw: 0 r: ReceiverResultReg.
        "now fill"
        cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
        fillLoop :=
        cogit MoveR: fillReg Mw: 0 r: Arg1Reg.
        cogit AddCq: 8 R: Arg1Reg.
        cogit CmpR: Arg1Reg R: byteSizeReg.
        cogit JumpAbove: fillLoop.
        cogit RetN: retNoffset.

        jumpNoSpace jmpTarget:
        (jumpUnhashed jmpTarget:
        (jumpFailCuzFixed jmpTarget:
        (jumpArrayTooBig jmpTarget:
        (jumpByteTooBig jmpTarget:
        (jumpLongTooBig jmpTarget:
        (jumpNElementsNonInt jmpTarget: cogit Label)))))).

        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveAsCharacter:inReg: (in category 'primitive generators') -----
  genInnerPrimitiveAsCharacter: retNOffset inReg: reg
        | jumpNotInt jumpOutOfRange |
        <var: 'jumpNotInt' type: #'AbstractInstruction *'>
        <var: 'jumpOutOfRange' type: #'AbstractInstruction *'>
        reg ~= ReceiverResultReg ifTrue:
+               [jumpNotInt := self genJumpNotSmallInteger: reg scratchReg: TempReg].
-               [jumpNotInt := self genJumpNotSmallInteger: reg scratch: TempReg].
        cogit MoveR: reg R: TempReg.
        self genConvertSmallIntegerToIntegerInReg: TempReg.
        cogit CmpCq: 1 << 30 - 1 R: TempReg.
        jumpOutOfRange := cogit JumpAbove: 0.
        self genConvertSmallIntegerToCharacterInReg: reg.
        reg ~= ReceiverResultReg ifTrue:
                [cogit MoveR: reg R: ReceiverResultReg].
        cogit RetN: retNOffset.
        jumpOutOfRange jmpTarget: cogit Label.
        reg ~= ReceiverResultReg ifTrue:
                [jumpNotInt jmpTarget: jumpOutOfRange getJmpTarget].
        ^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveObjectAt: (in category 'primitive generators') -----
  genInnerPrimitiveObjectAt: retNOffset
        | headerReg
          jumpBadIndex jumpNotCogMethod jumpBounds jumpNotHeaderIndex |
        <var: #jumpBounds type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpNotCogMethod type: #'AbstractInstruction *'>
        <var: #jumpNotHeaderIndex type: #'AbstractInstruction *'>
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        "get header into Arg1Reg..."
        cogit MoveMw: objectMemory baseHeaderSize r: ReceiverResultReg R: (headerReg := Arg1Reg).
+       jumpNotCogMethod := self genJumpSmallInteger: headerReg scratchReg: TempReg.
-       jumpNotCogMethod := self genJumpSmallInteger: headerReg scratch: TempReg.
        cogit MoveMw: (cogit offset: CogMethod of: #methodHeader) r: headerReg R: headerReg.
        jumpNotCogMethod jmpTarget: (cogit
                CmpCq: (objectMemory integerObjectOf: 1) R: Arg0Reg).
        jumpNotHeaderIndex := cogit JumpNonZero: 0.
        cogit
                MoveR: headerReg R: ReceiverResultReg;
                RetN: retNOffset.
        jumpNotHeaderIndex jmpTarget: (cogit
                AndCq: (objectMemory integerObjectOf: coInterpreter alternateHeaderNumLiteralsMask) R: headerReg).
        cogit
                SubCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg;
                CmpR: headerReg R: Arg0Reg.
        jumpBounds := cogit JumpAbove: 0.

        self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
        cogit
                AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg;
                MoveXwr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg;
                RetN: retNOffset.

        jumpBounds jmpTarget: (cogit
                AddCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg).
        jumpBadIndex jmpTarget: cogit Label.
        ^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
  genInnerPrimitiveStringAt: retNoffset
        "Implement the guts of primitiveStringAt; dispatch on size"
        | formatReg jumpNotIndexable jumpBadIndex done
          jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig
          jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
        <inline: true>
        "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
        <var: #done type: #'AbstractInstruction *'>
        <var: #jumpIsBytes type: #'AbstractInstruction *'>
        <var: #jumpIsShorts type: #'AbstractInstruction *'>
        <var: #jumpIsWords type: #'AbstractInstruction *'>
        <var: #jumpBadIndex type: #'AbstractInstruction *'>
        <var: #jumpWordTooBig type: #'AbstractInstruction *'>
        <var: #jumpNotIndexable type: #'AbstractInstruction *'>
        <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
        <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>

        cogit MoveR: Arg0Reg R: Arg1Reg.
+       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
-       jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
        self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
        cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"

        self genGetFormatOf: ReceiverResultReg
                into: (formatReg := SendNumArgsReg)
                leastSignificantHalfOfBaseHeaderIntoScratch: NoReg.

        self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.

        "dispatch on format in a combination of highest dynamic frequency order first and convenience.
                  0 = 0 sized objects (UndefinedObject True False et al)
                  1 = non-indexable objects with inst vars (Point et al)
                  2 = indexable objects with no inst vars (Array et al)
                  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
                  4 = weak indexable objects with inst vars (WeakArray et al)
                  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
                  6 unused, reserved for exotic pointer objects?
                  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
                  8 unused, reserved for exotic non-pointer objects?
                  9 (?) 64-bit indexable
                10 - 11 32-bit indexable
                12 - 15 16-bit indexable
                16 - 23 byte indexable
                24 - 31 compiled method"
        cogit CmpCq: objectMemory firstByteFormat R: formatReg.
        jumpIsBytes := cogit JumpGreaterOrEqual: 0.
                                        cogit CmpCq: objectMemory firstShortFormat R: formatReg.
        jumpIsShorts := cogit JumpGreaterOrEqual: 0.
                                        cogit CmpCq: objectMemory firstLongFormat R: formatReg.
        jumpIsWords := cogit JumpGreaterOrEqual: 0.
        jumpNotIndexable := cogit Jump: 0.

        jumpIsBytes jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
                cogit AndCq: objectMemory wordSize - 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
        cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
        cogit backEnd byteReadsZeroExtend ifFalse:
                        [cogit AndCq: 255 R: ReceiverResultReg].
        done := cogit Label.
        self genConvertIntegerToCharacterInReg: ReceiverResultReg.
        cogit RetN: retNoffset.

        jumpIsShorts jmpTarget:
                (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
                cogit AndCq: 1 R: formatReg.
                cogit SubR: formatReg R: ClassReg;
                CmpR: Arg1Reg R: ClassReg.
        jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddR: Arg1Reg R: ReceiverResultReg.
        cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
        cogit Jump: done.

        jumpIsWords jmpTarget:
                (cogit CmpR: Arg1Reg R: ClassReg).
        jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
        cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
        cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
        jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
        cogit MoveR: TempReg R: ReceiverResultReg.
        cogit Jump: done.

        jumpBytesOutOfBounds jmpTarget:
        (jumpShortsOutOfBounds jmpTarget:
        (jumpWordsOutOfBounds jmpTarget:
        (jumpWordTooBig jmpTarget:
        (jumpNotIndexable jmpTarget:
        (jumpBadIndex jmpTarget: cogit Label))))).

        ^0!

Item was changed:
  ----- Method: Cogit>>AndCq:R:R: (in category 'abstract instructions') -----
  AndCq: quickConstant R: srcReg R: destReg
+       <inline: false>
-       <inline: true>
        <returnTypeC: #'AbstractInstruction *'>
        | first |
        <var: 'first' type: #'AbstractInstruction *'>
        backEnd hasThreeAddressArithmetic ifTrue:
                [^self gen: AndCqRR quickConstant: quickConstant operand: srcReg operand: destReg].
        srcReg = destReg ifTrue:
                [^self gen: AndCqR quickConstant: quickConstant operand: destReg.].
        first := self gen: MoveRR operand: srcReg operand: destReg.
        self gen: AndCqR quickConstant: quickConstant operand: destReg.
        ^first!

Item was changed:
  ----- Method: OutOfLineLiteralsManager>>checkQuickConstant:forInstruction: (in category 'compile abstract instructions') -----
  checkQuickConstant: literal forInstruction: anInstruction
        <var: #anInstruction type: #'AbstractInstruction *'>
        <returnTypeC: #'AbstractInstruction *'>
+       <inline: true>
        anInstruction usesOutOfLineLiteral ifTrue:
+               [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 1 << (objectMemory wordSize * 8) - 1]))].
-               [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 16rFFFFFFFF]))].
        ^anInstruction!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
  genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
        "Receiver and arg in registers.
         Stack looks like
                return address"
        <var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
        | jumpFailClass jumpFailClass2 jumpFailAlloc jumpFailCheck jumpImmediate jumpNonInt doOp |
        <var: #jumpFailClass type: #'AbstractInstruction *'>
        <var: #jumpFailClass2 type: #'AbstractInstruction *'>
        <var: #jumpFailAlloc type: #'AbstractInstruction *'>
        <var: #jumpImmediate type: #'AbstractInstruction *'>
        <var: #jumpNonInt type: #'AbstractInstruction *'>
        <var: #jumpFailCheck type: #'AbstractInstruction *'>
        <var: #doOp type: #'AbstractInstruction *'>
        objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
        self MoveR: Arg0Reg R: ClassReg.
        jumpImmediate := objectRepresentation genJumpImmediate: Arg0Reg.
        objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
        objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
        jumpFailClass := self JumpNonZero: 0.
        objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
        doOp := self Label.
        preOpCheckOrNil ifNotNil:
                [jumpFailCheck := self perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].
        self gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
        jumpFailAlloc := objectRepresentation
                                                genAllocFloatValue: DPFPReg0
                                                into: SendNumArgsReg
                                                scratchReg: ClassReg
                                                scratchReg: TempReg.
        self MoveR: SendNumArgsReg R: ReceiverResultReg.
        self RetN: 0.
        jumpImmediate jmpTarget: self Label.
        objectRepresentation maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: doOp.
        objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
+               [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].
-               [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratch: TempReg].
        objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
        self ConvertR: ClassReg Rd: DPFPReg1.
        self Jump: doOp.
        "We need to push the register args on two paths; this one and the interpreter primitive path.
        But the interpreter primitive path won't unless regArgsHaveBeenPushed is false."
        self assert: methodOrBlockNumArgs <= self numRegArgs.
        jumpFailClass jmpTarget: self Label.
        objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
                [jumpNonInt jmpTarget: jumpFailClass getJmpTarget].
        preOpCheckOrNil ifNotNil:
                [jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].
        backEnd genPushRegisterArgsForNumArgs: methodOrBlockNumArgs scratchReg: SendNumArgsReg.
        jumpFailClass2 := self Jump: 0.
        jumpFailAlloc jmpTarget: self Label.
        self compileFallbackToInterpreterPrimitive: 0.
        jumpFailClass2 jmpTarget: self Label.
        ^0!

Item was changed:
  ----- Method: TReturnNode>>emitCCodeOn:level:generator: (in category 'C code generation') -----
  emitCCodeOn: aStream level: level generator: aCodeGen

        (expression isSwitch
         or: [expression isCaseStmt]) ifTrue:
                [^expression emitCCodeOn: aStream addToEndOfCases: self level: level generator: aCodeGen].

        (expression isSend and: [expression isValueExpansion]) ifTrue:
                [^self emitValueExpansionOn: aStream level: level generator: aCodeGen].

        'void' = aCodeGen currentMethod returnType ifTrue: "If the function is void, don't say 'return x' instead say ' x; return' "
                [expression isLeaf ifFalse:
                        [expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen.
                         aStream nextPut: $;; crtab: level].
                 aStream nextPutAll: 'return'.
                 ^self].
        aStream nextPutAll: 'return '.
+       expression
+               emitCCodeAsArgumentOn: aStream
+               level: (expression isStmtList ifTrue: [level + 1] ifFalse: [level])
+               generator: aCodeGen!
-       expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen!

Item was changed:
  ----- Method: TStmtListNode>>emitCCodeAsArgumentOn:level:generator: (in category 'C code generation') -----
  emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen
+       | size |
+       (size := statements size) = 1 ifTrue:
-
-       | statementWasComment |
-       statements size = 1 ifTrue:
                [^statements first emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen].
-       statementWasComment := false.
        aStream nextPut: $(. "N.B.  Comma binds weakest of all C operators."
+       statements withIndexDo:
+               [:s :idx| | p1 p2 |
+               p1 := aStream position.
+               s emitCCommentOn: aStream level: level.
+               (s isLeaf and: [s isLabel not and: [idx < statements size]]) ifFalse:
+                       [s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen].
+               p2 := aStream position.
+               (idx < size and: [p2 > p1]) ifTrue:
-       statements
-               do:
-                       [:s |
-                       s emitCCommentOn: aStream level: level.
-                       s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen.
-                       statementWasComment := s isComment]
-               separatedBy:
                        [((self endsWithCloseBracket: aStream)
+                         or: [s isComment]) ifFalse: [aStream nextPut: $,].
+                        aStream crtab: level]].
-                         or: [statementWasComment]) ifFalse: [aStream nextPut: $,].
-                       aStream crtab: level].
        aStream nextPut: $)!