[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