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: $)! |
JIT builds still failing. /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:
|
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)
|
Free forum by Nabble | Edit this page |