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

commits at source.squeak.org commits at source.squeak.org
Tue May 20 02:04:27 UTC 2014


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

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

Name: VMMaker.oscog-eem.723
Author: eem
Time: 19 May 2014, 7:01:33.987 pm
UUID: 7e7f66ea-1471-4c21-9040-bd4ba88fea7f
Ancestors: VMMaker.oscog-eem.722

and of course the MirrorNew prims are option: #NewspeakVM

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

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveMirrorNew: (in category 'primitive generators') -----
  genInnerPrimitiveMirrorNew: retNoffset
  	"Implement 1-arg (instantiateFixedClass:) primitiveNew for convenient cases:
  	- the class argument has a hash
  	- the class argument is fixed size (excluding ephemerons to save instructions & miniscule time)
  	- single word header/num slots < numSlotsMask
  	- the result fits in eden (actually below scavengeThreshold)"
  
+ 	<option: #NewspeakVM>
  	| halfHeaderReg fillReg instSpecReg byteSizeReg
  	  jumpImmediate jumpUnhashed jumpNotFixedPointers jumpTooSmall jumpBadFormat
  	  jumpNoSpace jumpTooBig jumpHasSlots jumpVariableOrEphemeron
  	  fillLoop skip |
  	<var: 'skip' type: #'AbstractInstruction *'>
  	<var: 'fillLoop' type: #'AbstractInstruction *'>
  	<var: 'jumpTooBig' type: #'AbstractInstruction *'>
  	<var: 'jumpHasSlots' type: #'AbstractInstruction *'>
  	<var: 'jumpNoSpace' type: #'AbstractInstruction *'>
  	<var: 'jumpTooSmall' type: #'AbstractInstruction *'>
  	<var: 'jumpUnhashed' type: #'AbstractInstruction *'>
  	<var: 'jumpImmediate' type: #'AbstractInstruction *'>
  	<var: 'jumpBadFormat' type: #'AbstractInstruction *'>
  	<var: 'jumpNotFixedPointers' type: #'AbstractInstruction *'>
  	<var: 'jumpVariableOrEphemeron' type: #'AbstractInstruction *'>
  
  	"half header will contain 1st half of header (classIndex/class's hash & format),
  	 then 2nd half of header (numSlots/fixed size) and finally fill value (nilObject)."
  	halfHeaderReg := fillReg := SendNumArgsReg.
  	"inst spec will hold class's instance specification, then byte size and finally end of new object."
  	instSpecReg := byteSizeReg := ClassReg.
  
  	"get freeStart as early as possible so as not to wait later..."
  	cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
  
  	"validate class arg; sigh, this mirror crap hobbles unfairly; there is a better way with selector namespaces..."
  	cogit MoveR: Arg0Reg R: TempReg.
  	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
  
  	"Is the class arg pointers with at least 3 fields?"
  	self genGetFormatOf: Arg0Reg
  		into: TempReg
  		leastSignificantHalfOfBaseHeaderIntoScratch: nil.
  	cogit CmpCq: objectMemory nonIndexablePointerFormat R: TempReg.
  	jumpNotFixedPointers := cogit JumpNonZero: 0.
  	
  	self genGetRawSlotSizeOfNonImm: Arg0Reg into: TempReg.
  	cogit CmpCq: InstanceSpecificationIndex + 1 R: TempReg.
  	jumpTooSmall := cogit JumpLess: 0.
  
  	"get class's hash & fail if 0"
  	self genGetHashFieldNonImmOf: Arg0Reg into: halfHeaderReg.
  	jumpUnhashed := cogit JumpZero: 0.
  
  	"get class's format inst var for both inst spec (format field) and num fixed fields"
  	self genLoadSlot: InstanceSpecificationIndex sourceReg: Arg0Reg destReg: instSpecReg.
  	cogit MoveR: instSpecReg R: TempReg.
  	jumpBadFormat := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	self genConvertSmallIntegerToIntegerInReg: instSpecReg.
  	cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth R: TempReg.
  	cogit AndCq: objectMemory formatMask R: TempReg.
  	cogit AndCq: objectMemory fixedFieldsOfClassFormatMask R: instSpecReg.
  	"fail if not fixed or if ephemeron (rare beasts so save the cycles)"
  	cogit CmpCq: objectMemory nonIndexablePointerFormat R: TempReg.
  	jumpVariableOrEphemeron := cogit JumpAbove: 0.
  	cogit CmpCq: objectMemory numSlotsMask R: instSpecReg.
  	jumpTooBig := cogit JumpAboveOrEqual: 0.
  	"Add format to classIndex/format half header; other word contains numSlots"
  	cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  	cogit AddR: TempReg R: halfHeaderReg.
  	"write half header now; it frees halfHeaderReg"
  	cogit MoveR: halfHeaderReg Mw: 0 r: Arg1Reg.
  	"save unrounded numSlots for header"
  	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 (freeSize + byteSize < scavengeThreshold); scavengeThreshold is constant."
  	cogit AddR: Arg1Reg R: byteSizeReg.
  	cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
  	jumpNoSpace := cogit JumpAboveOrEqual: 0.
  	"write back new freeStart; get result. byteSizeReg holds new freeStart, the limit of the object"
  	cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	"write other half of header (numSlots/identityHash)"
  	cogit MoveR: halfHeaderReg Mw: 4 r: Arg1Reg.
  	"now fill"
  	cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
  	cogit MoveCq: objectMemory nilObject R: fillReg.
  	"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.
  
  	jumpNotFixedPointers jmpTarget:
  	(jumpBadFormat jmpTarget:
  	(jumpTooSmall jmpTarget:
  	(jumpImmediate jmpTarget:
  	(jumpUnhashed jmpTarget:
  	(jumpVariableOrEphemeron jmpTarget:
  	(jumpTooBig jmpTarget:
  	(jumpNoSpace jmpTarget: cogit Label))))))).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveMirrorNewWithArg: (in category 'primitive generators') -----
  genInnerPrimitiveMirrorNewWithArg: retNoffset
  	"Implement instantiateVariableClass:withSize: for convenient cases:
  	- the class argument has a hash
  	- the class argument 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"
  
+ 	<option: #NewspeakVM>
  	| halfHeaderReg fillReg instSpecReg byteSizeReg maxSlots
  	  jumpArrayTooBig jumpByteTooBig jumpLongTooBig
  	  jumpArrayFormat jumpByteFormat jumpBytePrepDone jumpLongPrepDone
  	  jumpUnhashed jumpTooSmall jumpImmediate jumpNotFixedPointers
  	  jumpNElementsNonInt jumpFailCuzFixed jumpNoSpace jumpHasSlots fillLoop skip |
  	<var: 'skip' type: #'AbstractInstruction *'>
  	<var: 'fillLoop' type: #'AbstractInstruction *'>	
  	<var: 'jumpHasSlots' type: #'AbstractInstruction *'>
  	<var: 'jumpNoSpace' type: #'AbstractInstruction *'>
  	<var: 'jumpTooSmall' type: #'AbstractInstruction *'>
  	<var: 'jumpUnhashed' type: #'AbstractInstruction *'>
  	<var: 'jumpImmediate' 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 *'>
  	<var: 'jumpNotFixedPointers' 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.
  
  	"check size and fail if not a +ve integer"
  	cogit MoveR: Arg1Reg R: TempReg.
  	jumpNElementsNonInt := self genJumpNotSmallIntegerInScratchReg: TempReg.
  
  	"Is the class arg pointers with at least 3 fields?"
  	cogit MoveR: Arg0Reg R: TempReg.
  	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
  
  	self genGetFormatOf: Arg0Reg
  		into: TempReg
  		leastSignificantHalfOfBaseHeaderIntoScratch: nil.
  	cogit CmpCq: objectMemory nonIndexablePointerFormat R: TempReg.
  	jumpNotFixedPointers := cogit JumpNonZero: 0.
  	
  	self genGetRawSlotSizeOfNonImm: Arg0Reg into: TempReg.
  	cogit CmpCq: InstanceSpecificationIndex + 1 R: TempReg.
  	jumpTooSmall := cogit JumpLess: 0.
  
  	"get class's hash & fail if 0"
  	self genGetHashFieldNonImmOf: Arg0Reg into: halfHeaderReg.
  	jumpUnhashed := cogit JumpZero: 0.
  
  	"The basicNew: code (genInnerPrimitiveNewWithArg:) expects class in ReceiverResultReg
  	 and size in Arg0Reg.  Shuffle args to match, undoing on failure."
  	cogit
  		PushR: ReceiverResultReg;
  		MoveR: Arg0Reg R: ReceiverResultReg;
  		MoveR: Arg1Reg R: Arg0Reg.
  
  	"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 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 MoveCq: 0 R: TempReg.
  	cogit PushR: TempReg.
  	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 MoveCq: 0 R: TempReg.
  	cogit PushR: TempReg.
  	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 MoveCw: objectMemory nilObject R: TempReg.
  	cogit PushR: TempReg.
  	"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 PopR: TempReg. "discard pushed receiver"
  	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).
  
  	jumpFailCuzFixed jmpTarget:
  	(jumpArrayTooBig jmpTarget:
  	(jumpByteTooBig jmpTarget:
  	(jumpLongTooBig jmpTarget: cogit Label))).
  
  	"unshuffle arguments"
  	cogit
  		MoveR: Arg0Reg R: Arg1Reg;
  		MoveR: ReceiverResultReg R: Arg0Reg;
  		PopR: ReceiverResultReg.
  
  	jumpUnhashed jmpTarget:
  	(jumpImmediate jmpTarget:
  	(jumpNotFixedPointers jmpTarget:
  	(jumpTooSmall jmpTarget:
  	(jumpNElementsNonInt jmpTarget: cogit Label)))).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveNew: (in category 'primitive generators') -----
  genInnerPrimitiveNew: retNoffset
+ 	"Implement primitiveNew for convenient cases:
+ 	- the receiver has a hash
+ 	- the receiver is fixed size (excluding ephemerons to save instructions & miniscule time)
- 	"Implement 1-arg (instantiateFixedClass:) primitiveNew for convenient cases:
- 	- the class argument has a hash
- 	- the class argument is fixed size (excluding ephemerons to save instructions & miniscule time)
  	- single word header/num slots < numSlotsMask
  	- the result fits in eden (actually below scavengeThreshold)"
  
  	| halfHeaderReg fillReg instSpecReg byteSizeReg
+ 	  jumpUnhashed jumpVariableOrEphemeron jumpNoSpace jumpTooBig jumpHasSlots
- 	  jumpImmediate jumpUnhashed jumpNotFixedPointers jumpTooSmall jumpBadFormat
- 	  jumpNoSpace jumpTooBig jumpHasSlots jumpVariableOrEphemeron
  	  fillLoop skip |
  	<var: 'skip' type: #'AbstractInstruction *'>
  	<var: 'fillLoop' type: #'AbstractInstruction *'>
  	<var: 'jumpTooBig' type: #'AbstractInstruction *'>
  	<var: 'jumpHasSlots' type: #'AbstractInstruction *'>
  	<var: 'jumpNoSpace' type: #'AbstractInstruction *'>
- 	<var: 'jumpTooSmall' type: #'AbstractInstruction *'>
  	<var: 'jumpUnhashed' type: #'AbstractInstruction *'>
- 	<var: 'jumpImmediate' type: #'AbstractInstruction *'>
- 	<var: 'jumpBadFormat' type: #'AbstractInstruction *'>
- 	<var: 'jumpNotFixedPointers' type: #'AbstractInstruction *'>
  	<var: 'jumpVariableOrEphemeron' type: #'AbstractInstruction *'>
  
  	"half header will contain 1st half of header (classIndex/class's hash & format),
  	 then 2nd half of header (numSlots/fixed size) and finally fill value (nilObject)."
  	halfHeaderReg := fillReg := SendNumArgsReg.
  	"inst spec will hold class's instance specification, then byte size and finally end of new object."
  	instSpecReg := byteSizeReg := ClassReg.
  
  	"get freeStart as early as possible so as not to wait later..."
  	cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
- 
- 	"validate class arg; sigh, this mirror crap hobbles unfairly; there is a better way with selector namespaces..."
- 	cogit MoveR: Arg0Reg R: TempReg.
- 	jumpImmediate := cogit genJumpImmediateInScratchReg: TempReg.
- 
- 	"Is the class arg pointers with at least 3 fields?"
- 	self genGetFormatOf: Arg0Reg
- 		into: TempReg
- 		leastSignificantHalfOfBaseHeaderIntoScratch: nil.
- 	cogit CmpCq: objectMemory nonIndexablePointerFormat R: TempReg.
- 	jumpNotFixedPointers := cogit JumpNonZero: 0.
- 	
- 	self genGetRawSlotSizeOfNonImm: Arg0Reg into: TempReg.
- 	self CmpCq: InstanceSpecificationIndex + 1 R: TempReg.
- 	jumpTooSmall := cogit JumpLess: 0.
- 
  	"get class's hash & fail if 0"
+ 	self genGetHashFieldNonImmOf: ReceiverResultReg into: halfHeaderReg.
- 	self genGetHashFieldNonImmOf: Arg0Reg into: halfHeaderReg.
  	jumpUnhashed := cogit JumpZero: 0.
- 
  	"get class's format inst var for both inst spec (format field) and num fixed fields"
+ 	self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: TempReg.
+ 	self genConvertSmallIntegerToIntegerInReg: TempReg.
+ 	cogit MoveR: TempReg R: instSpecReg.
- 	self genLoadSlot: InstanceSpecificationIndex sourceReg: Arg0Reg destReg: instSpecReg.
- 	cogit MoveR: instSpecReg R: TempReg.
- 	jumpBadFormat := cogit genJumpNotSmallIntegerInScratchReg: TempReg.
- 	self genConvertSmallIntegerToIntegerInReg: instSpecReg.
  	cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth R: TempReg.
  	cogit AndCq: objectMemory formatMask R: TempReg.
  	cogit AndCq: objectMemory fixedFieldsOfClassFormatMask R: instSpecReg.
  	"fail if not fixed or if ephemeron (rare beasts so save the cycles)"
  	cogit CmpCq: objectMemory nonIndexablePointerFormat R: TempReg.
  	jumpVariableOrEphemeron := cogit JumpAbove: 0.
  	cogit CmpCq: objectMemory numSlotsMask R: instSpecReg.
  	jumpTooBig := cogit JumpAboveOrEqual: 0.
  	"Add format to classIndex/format half header; other word contains numSlots"
  	cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  	cogit AddR: TempReg R: halfHeaderReg.
  	"write half header now; it frees halfHeaderReg"
  	cogit MoveR: halfHeaderReg Mw: 0 r: Arg1Reg.
  	"save unrounded numSlots for header"
  	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 (freeSize + byteSize < scavengeThreshold); scavengeThreshold is constant."
  	cogit AddR: Arg1Reg R: byteSizeReg.
  	cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
  	jumpNoSpace := cogit JumpAboveOrEqual: 0.
  	"write back new freeStart; get result. byteSizeReg holds new freeStart, the limit of the object"
  	cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	"write other half of header (numSlots/identityHash)"
  	cogit MoveR: halfHeaderReg Mw: 4 r: Arg1Reg.
  	"now fill"
  	cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
  	cogit MoveCq: objectMemory nilObject R: fillReg.
  	"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.
  
+ 	jumpUnhashed jmpTarget:
- 	jumpNotFixedPointers jmpTarget:
- 	(jumpBadFormat jmpTarget:
- 	(jumpTooSmall jmpTarget:
- 	(jumpImmediate jmpTarget:
- 	(jumpUnhashed jmpTarget:
  	(jumpVariableOrEphemeron jmpTarget:
  	(jumpTooBig jmpTarget:
+ 	(jumpNoSpace jmpTarget: cogit Label))).
- 	(jumpNoSpace jmpTarget: cogit Label))))))).
  
  	^0!



More information about the Vm-dev mailing list