[Vm-dev] VM Maker: VMMaker.oscog-eem.1331.mcz

commits at source.squeak.org commits at source.squeak.org
Sat May 30 19:03:11 UTC 2015


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

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

Name: VMMaker.oscog-eem.1331
Author: eem
Time: 30 May 2015, 12:00:50.505 pm
UUID: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e
Ancestors: VMMaker.oscog-eem.1330

Cogit:
Refactor genGetFormatOf:into:baseHeaderIntoScratch:
to genGetFormatOf:into: and implement it for SqueakV3.

Use genJumpImmediate: et al in various basic
access primitives.

Document that genJump[Not]SmallInteger: can't
always be done with a single register (e.g. Spur64).

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

Item was changed:
  SharedPool subclass: #CogCompilationConstants
  	instanceVariableNames: ''
+ 	classVariableNames: 'BadRegisterSet NumSendTrampolines SSBaseOffset SSConstant SSIllegal SSRegister SSSpill UnimplementedOperation'
- 	classVariableNames: 'BadRegisterSet NumSendTrampolines SSBaseOffset SSConstant SSIllegal SSRegister SSSpill'
  	poolDictionaries: ''
  	category: 'VMMaker-JIT'!

Item was added:
+ ----- Method: CogObjectRepresentation>>genGetFormatOf:into: (in category 'compile abstract instructions') -----
+ genGetFormatOf: srcReg into: destReg
+ 	"Get the format field of the object in srcReg into destReg.
+ 	 srcReg may equal destReg."
+ 	self subclassResponsibility!

Item was added:
+ ----- Method: CogObjectRepresentation>>genJumpImmediate: (in category 'compile abstract instructions') -----
+ genJumpImmediate: aRegister
+ 	"Generate a compare and branch to test if aRegister contains an immediate.
+ 	 Answer the jump."
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	self subclassResponsibility
+ 	!

Item was added:
+ ----- Method: CogObjectRepresentation>>genJumpNotImmediate: (in category 'compile abstract instructions') -----
+ genJumpNotImmediate: aRegister
+ 	"Generate a compare and branch to test if aRegister contains a non-immediate.
+ 	 Answer the jump."
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	self subclassResponsibility
+ 	!

Item was added:
+ ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger: (in category 'compile abstract instructions') -----
+ genJumpNotSmallInteger: aRegister
+ 	"Generate a compare and branch to test if aRegister contains other than a SmallInteger.
+ 	 Answer the jump, or UnimplementedOperation if this cannot be done with a single register."
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	<inline: true>
+ 	^cogit cCoerceSimple: UnimplementedOperation to: #'AbstractInstruction *'!

Item was added:
+ ----- Method: CogObjectRepresentation>>genJumpSmallInteger: (in category 'compile abstract instructions') -----
+ genJumpSmallInteger: aRegister
+ 	"Generate a compare and branch to test if aRegister contains a SmallInteger.
+ 	 Answer the jump, or UnimplementedOperation if this cannot be done with
+ 	 a single register."
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	<inline: true>
+ 	^cogit cCoerceSimple: UnimplementedOperation to: #'AbstractInstruction *'!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  	"Implement the guts of primitiveAt"
  	| formatReg jumpNotIndexable jumpImmediate jumpBadIndex
  	  jumpBytesDone jumpShortsDone jumpWordsDone jumpFixedFieldsDone
  	  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: #jumpBytesDone type: #'AbstractInstruction *'>
  	<var: #jumpShortsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordTooBig type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  	<var: #jumpFixedFieldsDone 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: ReceiverResultReg R: TempReg.
- 	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
- 	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
+ 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
- 	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: 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 MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  	jumpBytesDone := cogit Jump: 0.
  
  	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.
  	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  	jumpShortsDone := cogit Jump: 0.
  
  	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.
  	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  	jumpWordsDone := cogit Jump: 0.
  
  	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.
  	jumpFixedFieldsDone := cogit Jump: 0.
  
  	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.
  
  	jumpFixedFieldsDone jmpTarget:
  	(jumpWordsDone jmpTarget:
  	(jumpShortsDone jmpTarget:
  	(jumpBytesDone jmpTarget:
  		(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: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAtPut: (in category 'primitive generators') -----
  genInnerPrimitiveAtPut: retNoffset
  	"Implement the guts of primitiveAtPut"
  	| formatReg jumpImmediate jumpBadIndex
  	  jumpNotIndexablePointers jumpNotIndexableBits
  	  jumpIsContext jumpIsCompiledMethod jumpIsBytes jumpHasFixedFields
  	  jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds
  	  jumpWordsOutOfBounds jumpBytesOutOfBounds jumpBytesOutOfRange
  	  jumpNonSmallIntegerValue jumpShortsUnsupported jumpNotPointers
  	  |
  	<inline: true>
  	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  	<var: #jumpIsBytes type: #'AbstractInstruction *'>
  	<var: #jumpBadIndex type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexableBits type: #'AbstractInstruction *'>
  	<var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortsUnsupported type: #'AbstractInstruction *'>
  	<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexablePointers type: #'AbstractInstruction *'>
  
+ 	jumpImmediate := self genJumpImmediate: ReceiverResultReg.
+ 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
- 	cogit MoveR: ReceiverResultReg R: TempReg.
- 	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
- 	cogit MoveR: Arg0Reg R: TempReg.
- 	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  	cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
  
  	"formatReg := self formatOf: ReceiverResultReg"
  	self genGetFormatOf: ReceiverResultReg
  		into: (formatReg := SendNumArgsReg)
  		leastSignificantHalfOfBaseHeaderIntoScratch: nil.
  
  	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 weakArrayFormat R: formatReg.
  	jumpNotPointers := cogit JumpAbove: 0.
  	"optimistic store check; assume index in range (almost always is)."
  	self genStoreCheckReceiverReg: ReceiverResultReg
  		valueReg: Arg1Reg
  		scratchReg: TempReg
  		inFrame: false.
  
  	cogit CmpCq: objectMemory arrayFormat R: formatReg.
  	jumpNotIndexablePointers := cogit JumpBelow: 0.
  	jumpHasFixedFields := cogit JumpNonZero: 0.
  	cogit CmpR: Arg0Reg R: ClassReg.
  	jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	cogit MoveR: Arg1Reg Xwr: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  
  	jumpHasFixedFields jmpTarget: cogit Label.
  	self genGetClassIndexOfNonImm: ReceiverResultReg into: formatReg.
  	cogit CmpCq: ClassMethodContextCompactIndex R: formatReg.
  	jumpIsContext := cogit JumpZero: 0.
  	"get # fixed fields in formatReg"
  	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.
  	cogit SubR: formatReg R: ClassReg.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: formatReg.
  	cogit CmpR: Arg0Reg R: ClassReg.
  	jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddR: formatReg R: Arg0Reg.
  	cogit MoveR: Arg1Reg Xwr: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  
  	jumpNotPointers jmpTarget:
  		(cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg).
  	jumpIsCompiledMethod := cogit JumpAboveOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	jumpNonSmallIntegerValue := self genJumpNotSmallIntegerInScratchReg: TempReg.
  					cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  	jumpIsBytes := cogit JumpAboveOrEqual: 0.
  					cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  	jumpShortsUnsupported := cogit JumpAboveOrEqual: 0.
  					cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  	"For now ignore 64-bit indexability."
  	jumpNotIndexableBits := cogit JumpBelow: 0.
  
  	cogit CmpR: Arg0Reg R: ClassReg.
  	jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: TempReg.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	cogit MoveR: TempReg Xwr: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  
  	jumpIsBytes jmpTarget:
  		(cogit CmpCq: (objectMemory integerObjectOf: 255) R: Arg1Reg).
  	jumpBytesOutOfRange := cogit JumpAbove: 0.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg.
  	cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  	cogit SubR: formatReg R: ClassReg;
  	CmpR: Arg0Reg R: ClassReg.
  	jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: TempReg.
  	cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  	cogit MoveR: TempReg Xbr: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  
  	"there are no shorts as yet.  so this is dead code:
  	jumpIsShorts jmpTarget:
  		(cogit CmpCq: (objectMemory integerObjectOf: 65535) R: Arg1Reg).
  	jumpShortsOutOfRange := cogit JumpAbove: 0.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg.
  	cogit AndCq: 1 R: formatReg.
  	cogit SubR: formatReg R: ClassReg;
  	CmpR: Arg0Reg R: ClassReg.
  	jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	cogit genConvertSmallIntegerToIntegerInReg: TempReg.
  	cogit AddR: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: TempReg M16: objectMemory baseHeaderSize r: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	jumpShortsDone := cogit Jump: 0."
  
  	jumpIsContext jmpTarget: 
  	(jumpNotIndexableBits jmpTarget:
  	(jumpBytesOutOfRange jmpTarget:
  	(jumpIsCompiledMethod jmpTarget:
  	(jumpArrayOutOfBounds jmpTarget:
  	(jumpBytesOutOfBounds jmpTarget:
  	(jumpShortsUnsupported jmpTarget:
  	(jumpWordsOutOfBounds jmpTarget:
  	(jumpNotIndexablePointers jmpTarget:
  	(jumpNonSmallIntegerValue jmpTarget:
  	(jumpFixedFieldsOutOfBounds jmpTarget: cogit Label)))))))))).
  
  	cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  	self genConvertIntegerToSmallIntegerInReg: Arg0Reg.
  
  	jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveIdentityHash: (in category 'primitive generators') -----
  genInnerPrimitiveIdentityHash: retNoffset
  	| jumpImm jumpSI jumpNotSet ret |
  	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpImm type: #'AbstractInstruction *'>
  	<var: #jumpNotSet type: #'AbstractInstruction *'>
+ 	jumpImm := self genJumpImmediate: ReceiverResultReg.
- 	cogit MoveR: ReceiverResultReg R: ClassReg.
- 	jumpImm := self genJumpImmediateInScratchReg: ClassReg.
  	self genGetHashFieldNonImmOf: ReceiverResultReg asSmallIntegerInto: TempReg.
  	cogit CmpCq: ConstZero R: TempReg.
  	jumpNotSet := cogit JumpZero: 0.
  	cogit MoveR: TempReg R: ReceiverResultReg.
  	ret := cogit RetN: retNoffset.
+ 	jumpImm jmpTarget: cogit Label.
+ 	jumpSI := self genJumpSmallInteger: ReceiverResultReg.
- 	jumpImm jmpTarget: (cogit MoveR: ReceiverResultReg R: ClassReg).
- 	jumpSI := self genJumpSmallIntegerInScratchReg: ClassReg.
  	jumpSI jmpTarget: ret.
  	self genConvertCharacterToSmallIntegerInReg: ReceiverResultReg.
  	cogit Jump: ret.
  	jumpNotSet jmpTarget: cogit Label.
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>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"
  
  	| halfHeaderReg 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 *'>
  
  	"half header will contain 1st half of header (classIndex/class's hash & format),
  	 then 2nd half of header (numSlots) and finally fill value (nilObject)."
  	halfHeaderReg := fillReg := SendNumArgsReg.
  	"inst spec will hold class's instance specification and then byte size and finally numSlots half of header"
  	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: halfHeaderReg.
  	jumpUnhashed := cogit JumpZero: 0.
  	"get index and fail if not a +ve integer"
+ 	jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg.
- 	cogit MoveR: Arg0Reg R: TempReg.
- 	jumpNElementsNonInt := self genJumpNotSmallIntegerInScratchReg: 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 half header now"
  	cogit MoveR: instSpecReg R: TempReg.
  	cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  	cogit AddR: TempReg R: halfHeaderReg.
  	"get integer value of num fields in TempReg now"
  	cogit MoveR: Arg0Reg R: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: TempReg.
  	"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) R: Arg0Reg.
  	jumpLongTooBig := cogit JumpAbove: 0.
  	"save num elements/slot size to instSpecReg"
  	cogit MoveR: TempReg R: instSpecReg.
  	"push fill value"
  	cogit PushCq: 0.
  	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: TempReg R: instSpecReg.
  	"compute odd bits and add into halfHeaderReg; 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: halfHeaderReg.
  	"round up num elements to numSlots in instSpecReg"
  	cogit AddCq: objectMemory wordSize - 1 R: instSpecReg.
  	cogit LogicalShiftRightCq: objectMemory shiftForWord R: instSpecReg.
  	"push fill value"
  	cogit PushCq: 0.
  	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: TempReg R: instSpecReg.
  	"push fill value"
  	cogit PushCw: objectMemory nilObject.
  	"fall through to allocate"
  
  	jumpBytePrepDone jmpTarget:
  	(jumpLongPrepDone jmpTarget: cogit Label).
  
  	"write half header now; it frees halfHeaderReg"
  	cogit MoveR: halfHeaderReg Mw: 0 r: Arg1Reg.
  	"save numSlots to halfHeaderReg"
  	cogit MoveR: instSpecReg R: halfHeaderReg.
  	"compute byte size; remember 0-sized objects still need 1 slot & allocation is
  	 rounded up to 8 bytes."
  	cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"
  	jumpHasSlots := cogit JumpNonZero: 0.
  	cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.
  	skip := cogit Jump: 0.
  	"round up to allocationUnit"
  	jumpHasSlots jmpTarget:
  	(cogit MoveR: byteSizeReg R: TempReg).
  	cogit AndCq: 1 R: TempReg.
  	cogit AddR: TempReg R: byteSizeReg.
  	cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.
  	skip jmpTarget:
  	"shift halfHeaderReg to put numSlots in correct place"
  	(cogit LogicalShiftLeftCq: objectMemory numSlotsHalfShift R: halfHeaderReg).
  	"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: halfHeaderReg Mw: 4 r: ReceiverResultReg.
  	"now fill"
  	cogit PopR: fillReg.
  	cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
  	"at least two words; so can make this a [fill 2 words. reached limit?] whileFalse"
  	fillLoop := 
  	cogit MoveR: fillReg Mw: 0 r: Arg1Reg.
  	cogit MoveR: fillReg Mw: 4 r: Arg1Reg.
  	cogit AddCq: 8 R: Arg1Reg.
  	cogit CmpR: Arg1Reg R: byteSizeReg.
  	cogit JumpAbove: fillLoop.
  	cogit RetN: retNoffset.
  
  	"pop discarded fill value & fall through to failure"
  	jumpNoSpace jmpTarget: (cogit PopR: TempReg).
  
  	jumpUnhashed jmpTarget:
  	(jumpFailCuzFixed jmpTarget:
  	(jumpArrayTooBig jmpTarget:
  	(jumpByteTooBig jmpTarget:
  	(jumpLongTooBig jmpTarget:
  	(jumpNElementsNonInt jmpTarget: cogit Label))))).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>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: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
+ 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
- 	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
  
  	self genGetFormatOf: ReceiverResultReg
  		into: (formatReg := SendNumArgsReg)
  		leastSignificantHalfOfBaseHeaderIntoScratch: nil.
  
  	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.
  	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: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveStringAtPut: (in category 'primitive generators') -----
  genInnerPrimitiveStringAtPut: retNoffset
  	"Implement the guts of primitiveStringAtPut"
+ 	| formatReg jumpBadIndex jumpBadArg jumpWordsDone jumpBytesOutOfRange
- 	| formatReg jumpImmediate jumpBadIndex jumpBadArg
- 	  jumpWordsDone jumpBytesOutOfRange
  	  jumpIsBytes jumpNotString jumpIsCompiledMethod
  	  jumpBytesOutOfBounds jumpWordsOutOfBounds jumpShortsUnsupported |
  	<inline: true>
  	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  	<var: #jumpBadArg type: #'AbstractInstruction *'>
  	<var: #jumpIsBytes type: #'AbstractInstruction *'>
  	<var: #jumpBadIndex type: #'AbstractInstruction *'>
- 	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpWordsDone type: #'AbstractInstruction *'>
  	<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortsUnsupported type: #'AbstractInstruction *'>
  	<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  
+ 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
- 	cogit MoveR: ReceiverResultReg R: TempReg.
- 	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
- 	cogit MoveR: Arg0Reg R: TempReg.
- 	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	cogit MoveR: Arg1Reg R: TempReg.
  	jumpBadArg := self genJumpNotCharacterInScratchReg: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  	cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
  
  	"formatReg := self formatOf: ReceiverResultReg"
  	self genGetFormatOf: ReceiverResultReg
  		into: (formatReg := SendNumArgsReg)
  		leastSignificantHalfOfBaseHeaderIntoScratch: nil.
  
  	self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
  
  	"dispatch on format; words and/or bytes.
  		  0 to 8 = pointer objects, forwarders, reserved.
  		  9 (?) 64-bit indexable
  		10 - 11 32-bit indexable
  		12 - 15 16-bit indexable (but unused)
  		16 - 23 byte indexable
  		24 - 31 compiled method"
  	cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  	jumpNotString := cogit JumpBelowOrEqual: 0.
  					cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  	jumpIsCompiledMethod := cogit JumpAboveOrEqual: 0.
  					cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  	jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  	jumpShortsUnsupported := cogit JumpGreaterOrEqual: 0.
  
  	cogit CmpR: Arg0Reg R: ClassReg.
  	jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: TempReg.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	cogit MoveR: TempReg Xwr: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	jumpWordsDone := cogit Jump: 0.
  
  	"there are no shorts as yet.  so this is dead code:
  	jumpIsShorts jmpTarget:
  		(cogit CmpCq: (objectMemory integerObjectOf: 65535) R: Arg1Reg).
  	jumpShortsOutOfRange := cogit JumpAbove: 0.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg.
  	cogit AndCq: 1 R: formatReg.
  	cogit SubR: formatReg R: ClassReg;
  	CmpR: Arg0Reg R: ClassReg.
  	jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	cogit genConvertSmallIntegerToIntegerInReg: TempReg.
  	cogit AddR: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: TempReg M16: objectMemory baseHeaderSize r: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	jumpShortsDone := cogit Jump: 0."
  
  	jumpIsBytes jmpTarget:
  		(cogit CmpCq: (objectMemory characterObjectOf: 255) R: Arg1Reg).
  	jumpBytesOutOfRange := cogit JumpAbove: 0.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg.
  	cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  	cogit SubR: formatReg R: ClassReg;
  	CmpR: Arg0Reg R: ClassReg.
  	jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit MoveR: Arg1Reg R: TempReg.
  	self genConvertCharacterToCodeInReg: TempReg.
  	cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  	cogit MoveR: TempReg Xbr: Arg0Reg R: ReceiverResultReg.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  
  	jumpWordsDone jmpTarget:
  		(cogit RetN: retNoffset).
  
  	jumpBadArg jmpTarget:
  	(jumpNotString jmpTarget:
  	(jumpBytesOutOfRange jmpTarget:
  	(jumpIsCompiledMethod jmpTarget:
  	(jumpBytesOutOfBounds jmpTarget:
  	(jumpShortsUnsupported jmpTarget:
  	(jumpWordsOutOfBounds jmpTarget: cogit Label)))))).
  
  	cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  	self genConvertIntegerToSmallIntegerInReg: Arg0Reg.
  
+ 	jumpBadIndex jmpTarget: cogit Label.
- 	jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label).
  
  	^0!

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genJumpNotSmallInteger: (in category 'compile abstract instructions') -----
+ genJumpNotSmallInteger: aRegister
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	cogit TstCq: 1 R: aRegister.
+ 	^cogit JumpZero: 0!

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>genGetFormatOf:into: (in category 'compile abstract instructions') -----
+ genGetFormatOf: srcReg into: destReg
+ 	"Get the format field of the object in srcReg into destReg.
+ 	 srcReg may equal destReg."
+ 	^self genGetBits: objectMemory formatMask ofFormatByteOf: srcReg into: destReg baseHeaderIntoScratch: nil!

Item was removed:
- ----- Method: CogObjectRepresentationForSpur>>genGetFormatOf:into:baseHeaderIntoScratch: (in category 'compile abstract instructions') -----
- genGetFormatOf: sourceReg into: destReg baseHeaderIntoScratch: scratchReg
- 	self genGetBits: objectMemory formatMask ofFormatByteOf: sourceReg into: destReg baseHeaderIntoScratch: scratchReg.
- 	^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].
- 		[cogit MoveR: reg R: TempReg.
- 		 jumpNotInt := self genJumpNotSmallIntegerInScratchReg: 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>>genInnerPrimitiveIdentical:orNotIf: (in category 'primitive generators') -----
  genInnerPrimitiveIdentical: retNoffset orNotIf: orNot
  	| jumpImmediate jumpCmp |
  	<var: #jumpCmp type: #'AbstractInstruction *'>
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
- 	cogit MoveR: Arg0Reg R: TempReg.
- 	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
  	self genEnsureObjInRegNotForwarded: Arg0Reg scratchReg: TempReg.
  	jumpImmediate jmpTarget:
  		(cogit CmpR: Arg0Reg R: ReceiverResultReg).
  	jumpCmp := orNot
  					ifTrue: [cogit JumpZero: 0]
  					ifFalse: [cogit JumpNonZero: 0].
  	cogit genMoveTrueR: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpCmp jmpTarget: (cogit genMoveFalseR: ReceiverResultReg).
  	cogit RetN: retNoffset.
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveSize: (in category 'primitive generators') -----
  genInnerPrimitiveSize: retNoffset
  	| jumpImm jumpNotIndexable jumpIsContext |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpImm type: #'AbstractInstruction *'>
- 	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
+ 	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
+ 	jumpImm := self genJumpImmediate: ReceiverResultReg.
- 	cogit MoveR: ReceiverResultReg R: TempReg.
- 	jumpImm := self genJumpImmediateInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
  	self genConvertIntegerToSmallIntegerInReg: ClassReg.
  	cogit MoveR: ClassReg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpImm jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)).
  	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genGetFormatOf:into: (in category 'primitive generators') -----
+ genGetFormatOf: srcReg into: destReg
+ 	"Get the format field of the object in srcReg into destReg.
+ 	 srcReg may equal destReg."
+ 	<inline: true>
+ 	cogit
+ 		MoveMw: 0 r: srcReg R: destReg;
+ 		LogicalShiftRightCq: objectMemory instFormatFieldLSB R: destReg;
+ 		AndCq: self instFormatFieldMask R: destReg.
+ 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  	| jumpSI jumpNotSI jumpNotIndexable jumpIsContext jumpBounds jumpFmtGt4 jumpFmtEq2 jumpFmtLt8 jumpFmtGt11 jumpLarge |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpBounds type: #'AbstractInstruction *'>
  	<var: #jumpFmtGt4 type: #'AbstractInstruction *'>
  	<var: #jumpFmtEq2 type: #'AbstractInstruction *'>
  	<var: #jumpFmtLt8 type: #'AbstractInstruction *'>
  	<var: #jumpFmtGt11 type: #'AbstractInstruction *'>
  	<var: #jumpLarge type: #'AbstractInstruction *'>
+ 	jumpSI := self genJumpSmallInteger: ReceiverResultReg.
- 	cogit MoveR: ReceiverResultReg R: TempReg.
- 	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
- 	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
+ 	jumpNotSI := self genJumpNotSmallInteger: Arg0Reg.
- 	jumpNotSI := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
  	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg.
  	cogit CmpR: ClassReg R: Arg1Reg.
  	jumpBounds := cogit JumpAboveOrEqual: 0.
  	"This is tedious.  Because of register pressure on x86 (and the baroque
  	 complexity of the size computation) we have to recompute the format
  	 because it may have been smashed computing the fixed fields.  But at
  	 least we have the fixed fields, if any, in formatReg and recomputing
  	 these is more expensive than recomputing format.  In any case this
  	 should still be faster than the interpreter and we hope this object
  	 representation's days are numbered."
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: ClassReg;	"self baseHeader: receiver"
  		LogicalShiftRightCq: objectMemory instFormatFieldLSB R: ClassReg;
  		AndCq: self instFormatFieldMask R: ClassReg;	"self formatOfHeader: ClassReg"
  		CmpCq: 4 R: ClassReg.
  	jumpFmtGt4 := cogit JumpGreater: 0.
  	cogit CmpCq: 2 R: ClassReg.	"Common case, e.g. Array, has format = 2"
  	jumpFmtEq2 := cogit JumpZero: 0.
  	cogit AddR: SendNumArgsReg R: Arg1Reg. "Add fixed fields to index"
  	jumpFmtEq2 jmpTarget: cogit Label.
  	cogit "Too lazy [knackered, more like. ed.] to define index with displacement addressing right now"
  		AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: Arg1Reg;
  		MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg;
  		RetN: retNoffset.
  	jumpFmtGt4 jmpTarget: cogit Label.
  	"Byte objects have formats 8 through 15, Compiled methods being 12 through 15;
  	 fail for CompiledMethod allowing the CoInterpeter to impose stricter bounds checks."
  	cogit CmpCq: 8 R: ClassReg.
  	jumpFmtLt8 := cogit JumpLess: 0.
  	cogit CmpCq: 11 R: ClassReg.
  	jumpFmtGt11 := cogit JumpGreater: 0.
  	cogit
  		AddCq: objectMemory baseHeaderSize R: Arg1Reg;
  		MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpFmtLt8 jmpTarget: cogit Label.
  	self assert: objectMemory wordSize = 4. "documenting my laziness"
  	cogit "Too lazy [knackered, more like. ed.] to define index with displacement addressing right now"
  		AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: Arg1Reg;
  		MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg;
  		CmpCq: 16r3FFFFFFF R: ReceiverResultReg.
  	jumpLarge := cogit JumpAbove: 0.
  	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpLarge jmpTarget: (cogit CallRT: cePositive32BitIntegerTrampoline).
  	cogit
  		MoveR: TempReg R: ReceiverResultReg;
  		RetN: retNoffset.
  	jumpSI jmpTarget:
  	(jumpNotSI jmpTarget:
  	(jumpNotIndexable jmpTarget:
  	(jumpIsContext jmpTarget:
  	(jumpBounds jmpTarget:
  	(jumpFmtGt11 jmpTarget:
  		cogit Label))))).
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveIdentityHash: (in category 'primitive generators') -----
  genInnerPrimitiveIdentityHash: retNOffset
  	| jumpSI |
  	<var: #jumpSI type: #'AbstractInstruction *'>
+ 	jumpSI := self genJumpSmallInteger: ReceiverResultReg.
- 	cogit MoveR: ReceiverResultReg R: ClassReg.
- 	jumpSI := self genJumpSmallIntegerInScratchReg: ClassReg.
  	self genGetHashFieldNonImmOf: ReceiverResultReg asSmallIntegerInto: TempReg.
  	cogit MoveR: TempReg R: ReceiverResultReg.
  	cogit RetN: retNOffset.
  	jumpSI jmpTarget: cogit Label.
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveSize: (in category 'primitive generators') -----
  genInnerPrimitiveSize: retNoffset
  	| jumpSI jumpNotIndexable jumpIsContext |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpSI type: #'AbstractInstruction *'>
- 	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
+ 	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
+ 	jumpSI := self genJumpSmallInteger: ReceiverResultReg.
- 	cogit MoveR: ReceiverResultReg R: TempReg.
- 	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
  	self genConvertIntegerToSmallIntegerInReg: ClassReg.
  	cogit MoveR: ClassReg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpSI jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)).
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
  genInnerPrimitiveStringAt: retNOffset
+ 	| jumpNotSI jumpNotByteIndexable jumpBounds jumpShortHeader jumpSkip |
- 	| jumpSI jumpNotSI jumpNotByteIndexable jumpBounds jumpShortHeader jumpSkip |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
- 	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpNotByteIndexable type: #'AbstractInstruction *'>
  	<var: #jumpBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortHeader type: #'AbstractInstruction *'>
  	<var: #jumpSkip type: #'AbstractInstruction *'>
- 	cogit MoveR: ReceiverResultReg R: TempReg.
- 	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
- 	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
+ 	jumpNotSI := self genJumpNotSmallInteger: Arg0Reg.
- 	jumpNotSI := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: TempReg;	"self baseHeader: receiver"
  		MoveR: TempReg R: ClassReg;					"copy header word; we'll need it later"
  		LogicalShiftRightCq: objectMemory instFormatFieldLSB R: TempReg;
  		AndCq: self instFormatFieldMask R: TempReg;	"self formatOfHeader: destReg"
  		MoveR: TempReg R: SendNumArgsReg;
  		AndCq: 3 R: SendNumArgsReg;					"get odd bytes from format (if it turns out to be bytes)"
  		SubR: SendNumArgsReg R: TempReg;
  		CmpCq: 8 R: TempReg.							"check format is 8"
  	jumpNotByteIndexable := cogit JumpNonZero: 0.
  	cogit
  		MoveR: ClassReg R: TempReg;
  		AndCq: TypeMask R: TempReg;
  		CmpCq: HeaderTypeSizeAndClass R: TempReg.	"(hdr bitAnd: TypeMask) = HeaderTypeSizeAndClass"
  	jumpShortHeader := cogit JumpNonZero: 0.
  	self assert: Size4Bit = 0.
  	cogit
  		MoveMw: 0 - (2 * objectMemory wordSize) r: ReceiverResultReg R: ClassReg; "(self sizeHeader: oop) bitAnd: LongSizeMask"
  		AndCq: LongSizeMask signedIntFromLong R: ClassReg.
  	jumpSkip :=  cogit Jump: 0.
  	jumpShortHeader jmpTarget: (cogit AndCq: SizeMask R: ClassReg).	"hdr bitAnd: SizeMask"
  	jumpSkip jmpTarget: (cogit SubCq: objectMemory baseHeaderSize R: ClassReg). "sz - BaseHeaderSize"
  	cogit SubR: SendNumArgsReg R: ClassReg. "sz - (fmt bitAnd: 3)"
  	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg.
  	cogit CmpR: ClassReg R: Arg1Reg.
  	jumpBounds := cogit JumpAboveOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  	cogit genMoveConstant: objectMemory characterTable R: Arg0Reg.
  	cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg;
  		AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: ReceiverResultReg.
  	cogit MoveXwr: ReceiverResultReg R: Arg0Reg R: ReceiverResultReg.
  	cogit RetN: retNOffset.
+ 	jumpNotSI jmpTarget:
- 	jumpSI jmpTarget:
- 	(jumpNotSI jmpTarget:
  	(jumpNotByteIndexable jmpTarget:
  	(jumpBounds jmpTarget:
+ 		cogit Label)).
- 		cogit Label))).
  	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genJumpNotImmediate: (in category 'compile abstract instructions') -----
+ genJumpNotImmediate: aRegister
+ 	<inline: true>
+ 	^self genJumpNotSmallInteger: aRegister!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genJumpNotSmallInteger: (in category 'compile abstract instructions') -----
+ genJumpNotSmallInteger: aRegister
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	cogit TstCq: 1 R: aRegister.
+ 	^cogit JumpZero: 0!

Item was changed:
  ----- Method: Cogit class>>initializeErrorCodes (in category 'class initialization') -----
  initializeErrorCodes
  	"External errors, returned to or from cog:selector:"
  	NotFullyInitialized := -1.
  	InsufficientCodeSpace := -2.
  	MethodTooBig := -4.
  	YoungSelectorInPIC := -5.
  	EncounteredUnknownBytecode := -6.
  	UnimplementedPrimitive := -7.
  	ShouldNotJIT := -8.
  	MaxNegativeErrorCode := ShouldNotJIT.
  	"Internal errors returned by generator routines to other generator routines"
  	BadRegisterSet := 1.
+ 	UnimplementedOperation := 2.
  	"Internal successes answered by CogObjectRepresentation to JIT, etc"
+ 	UnfailingPrimitive := 3!
- 	UnfailingPrimitive := 2.!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveClosureValue (in category 'primitive generators') -----
  genPrimitiveClosureValue
  	"Check the argument count.  Fail if wrong.
  	 Get the method from the outerContext and see if it is cogged.  If so, jump to the
  	 block entry or the no-context-switch entry, as appropriate, and we're done.  If not,
  	 invoke the interpreter primitive."
  	| jumpFailNArgs jumpFail1 jumpFail2 jumpFail3 jumpFail4 jumpBCMethod primitiveRoutine result |
  	<var: #jumpFail5 type: #'AbstractInstruction *'>
  	<var: #jumpFail2 type: #'AbstractInstruction *'>
  	<var: #jumpFail3 type: #'AbstractInstruction *'>
  	<var: #jumpFail4 type: #'AbstractInstruction *'>
  	<var: #jumpFailNArgs type: #'AbstractInstruction *'>
  	<var: #jumpBCMethod type: #'AbstractInstruction *'>
  	<var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
  	objectRepresentation genLoadSlot: ClosureNumArgsIndex sourceReg: ReceiverResultReg destReg: TempReg.
  	self CmpCq: (objectMemory integerObjectOf: methodOrBlockNumArgs) R: TempReg.
  	jumpFailNArgs := self JumpNonZero: 0.
  	objectRepresentation genLoadSlot: ClosureOuterContextIndex sourceReg: ReceiverResultReg destReg: ClassReg.
  	jumpFail1 := objectRepresentation genJumpImmediate: ClassReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: TempReg.
  	objectRepresentation genCmpClassMethodContextCompactIndexR: TempReg.
  	jumpFail2 := self JumpNonZero: 0.
  	objectRepresentation genLoadSlot: MethodIndex sourceReg: ClassReg destReg: SendNumArgsReg.
  	jumpFail3 := objectRepresentation genJumpImmediate: SendNumArgsReg.
+ 	objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg.
- 	objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg baseHeaderIntoScratch: nil.
  	self CmpCq: objectMemory firstCompiledMethodFormat R: TempReg.
  	jumpFail4 := self JumpLess: 0.
  	objectRepresentation genLoadSlot: HeaderIndex sourceReg: SendNumArgsReg destReg: ClassReg.
  	jumpBCMethod := objectRepresentation genJumpSmallInteger: ClassReg.
  	self MoveM16: (self offset: CogMethod of: #blockEntryOffset) r: ClassReg R: TempReg.
  	self AddR: ClassReg R: TempReg.
  	primitiveRoutine := coInterpreter
  							functionPointerForCompiledMethod: methodObj
  							primitiveIndex: primitiveIndex.
  	primitiveRoutine = #primitiveClosureValueNoContextSwitch ifTrue:
  		[blockNoContextSwitchOffset = nil ifTrue:
  			[^NotFullyInitialized].
  		 self SubCq: blockNoContextSwitchOffset R: TempReg].
  	self JumpR: TempReg.
  	jumpBCMethod jmpTarget: (jumpFail1 jmpTarget: (jumpFail2 jmpTarget: (jumpFail3 jmpTarget: (jumpFail4 jmpTarget: self Label)))).
  	(result := self compileInterpreterPrimitive: primitiveRoutine) < 0 ifTrue:
  		[^result].
  	jumpFailNArgs jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: VMClass class>>initializeMiscConstants (in category 'initialization') -----
  initializeMiscConstants
  	"Falsify the `what type of VM is this?' flags that are defined in the various interp.h files,
  	 or in the case of VMBIGENDIAN the various sqConfig.h files.
  	 Subclass implementations need to include a super initializeMiscConstants"
  
  	| omc |
  	VMBIGENDIAN class. "Mention this for the benefit of CCodeGenerator>>emitCConstantsOn:"
  	self isInterpreterClass ifTrue:
  		[STACKVM := COGVM := COGMTVM := false].
  
  	initializationOptions ifNil: [self initializationOptions: Dictionary new].
  	omc := initializationOptions at: #ObjectMemory ifAbsent: nil.
  	(omc isNil and: [self defaultObjectMemoryClass notNil]) ifTrue:
  		[omc := initializationOptions at: #ObjectMemory put: self defaultObjectMemoryClass name].
  	initializationOptions
  		at: #SqueakV3ObjectMemory	"the good ole default"
+ 			ifAbsentPut: (omc
- 			put: (omc
  					ifNil: [true]
  					ifNotNil: [(Smalltalk at: omc) includesBehavior: ObjectMemory]);
  		at: #SpurObjectMemory		"the new contender"
+ 			ifAbsentPut: (omc
- 			put: (omc
  					ifNil: [false]
  					ifNotNil: [(Smalltalk at: omc) includesBehavior: SpurMemoryManager]).
  
  	"Use ifAbsentPut: so that they will get copied back to the
  	 VMMaker's options and dead code will likely be eliminated."
  	PharoVM := initializationOptions at: #PharoVM ifAbsentPut: [false].
  	NewspeakVM := initializationOptions at: #NewspeakVM ifAbsentPut: [false].
  	SistaVM := initializationOptions at: #SistaVM ifAbsentPut: [false].
  	MULTIPLEBYTECODESETS := initializationOptions at: #MULTIPLEBYTECODESETS ifAbsentPut: [false].
  	"N.B.  Not yet implemented."
  	IMMUTABILITY := initializationOptions at: #IMMUTABILITY ifAbsentPut: [false].
  
  	"These for scripts etc... Usually they should get set by an Interpreter class's initializeMiscConstantsWith:"
  	(initializationOptions includesKey: #STACKVM) ifTrue:
  		[STACKVM := initializationOptions at: #STACKVM].
  	(initializationOptions includesKey: #COGVM) ifTrue:
  		[COGVM := initializationOptions at: #COGVM].
  	(initializationOptions includesKey: #COGMTVM) ifTrue:
  		[COGMTVM := initializationOptions at: #COGMTVM]!



More information about the Vm-dev mailing list