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

commits at source.squeak.org commits at source.squeak.org
Sat Dec 5 02:04:09 UTC 2015


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

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

Name: VMMaker.oscog-eem.1550
Author: eem
Time: 4 December 2015, 6:02:26.372 pm
UUID: 4b7ae25c-2439-4e33-aa5f-fb0210af3ca0
Ancestors: VMMaker.oscog-eem.1549

x64 Cogit:
Provide a convenience method to hide the inconvenience of checking for UndefinedOperation in uses of genJump[Not]SmallInteger:.

Reefactor to share genInnerPrimitiveStringAt: between 32- and 64-bit Spur obj reps.

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

Item was added:
+ ----- 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 added:
+ ----- 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 removed:
- ----- 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: Arg1Reg.
- 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
- 	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 added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genConvertSmallIntegerToCharacterInReg: (in category 'compile abstract instructions') -----
+ genConvertSmallIntegerToCharacterInReg: reg
+ 	"Convert the SmallInteger in reg to a Character, assuming
+ 	 the SmallInteger's value is a valid character."
+ 	self assert: (objectMemory characterTag = 2 and: [objectMemory smallIntegerTag = 1]).
+ 	cogit AddCq: 1 R: reg!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  	"Implement the guts of primitiveAt"
  	| formatReg jumpNotIndexable jumpImmediate jumpBadIndex
  	  jumpBytesDone jumpShortsDone jumpWordsDone jumpFixedFieldsDone
  	  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: #jumpBytesDone type: #'AbstractInstruction *'>
  	<var: #jumpShortsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordsDone 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: Arg0Reg R: Arg1Reg.
+ 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.
- 	jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
- 	jumpBadIndex asInteger = UnimplementedOperation ifTrue:
- 		[cogit MoveR: Arg0Reg R: TempReg.
- 		 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 - 1) R: Arg1Reg.
  	cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: 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.
  	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.
  	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:
  	(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"
  	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 scratch: TempReg.
- 	jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg.
- 	jumpNElementsNonInt asInteger = UnimplementedOperation ifTrue:
- 		[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 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 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.
  	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: TempReg 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.
  	"store numSlots to headerReg"
  	cogit MoveR: instSpecReg R: TempReg.
  	cogit LogicalShiftLeftCq: objectMemory numSlotsFullShift R: TempReg.
  	cogit AddR: TempReg R: headerReg.
  	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: TempReg 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.
  	"round up to allocationUnit"
  	jumpHasSlots jmpTarget:
  	(cogit MoveR: byteSizeReg R: TempReg).
  	cogit AddR: TempReg R: byteSizeReg.
  	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 scratch: TempReg].
- 		[jumpNotInt := self genJumpNotSmallInteger: reg].
  	cogit MoveR: reg R: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: TempReg.
+ 	cogit CmpCq: 1 << 30 - 1 R: 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 added:
+ ----- 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 scratch: 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.
+ 	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!



More information about the Vm-dev mailing list