[Vm-dev] VM Maker: VMMaker.oscog-eem.1179.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Apr 10 22:58:41 UTC 2015
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1179.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1179
Author: eem
Time: 10 April 2015, 3:12:02.167 pm
UUID: f8947e83-b2c5-440a-9ac2-4d4dbfe69448
Ancestors: VMMaker.oscog-eem.1178
Fix several slips in inline primitive generation:
Object>>at:put: needs to include a store check.
Some register allocation code was wrong.
Some results needed converting to SmallIntegers
and recording results as pushed on the sim stack.
extendedPushBytecode /does/ need a frame.
Change calPrimitiveBytecode to
genCallPrimitiveBytecode in the Cogit.
remove the misnomer genConvertIntegerToSmallIntegerInScratchReg:
Fix some receivers for simulation (self => stackPages etc).
Add a workable callInlinePrimitive: for StackDepthFinder.
=============== Diff against VMMaker.oscog-eem.1178 ===============
Item was changed:
----- Method: CoInterpreter>>divorceSomeMachineCodeFramesWithMethod: (in category 'frame access') -----
divorceSomeMachineCodeFramesWithMethod: cogMethod
"Divorce at most one frame (since the divorce may cause the containing
page to be split) and answer whether a frame was divorced."
<var: #cogMethod type: #'CogMethod *'>
| divorcedSome |
<var: #aPage type: #'StackPage *'>
divorcedSome := false.
0 to: numStackPages - 1 do:
[:i| | aPage |
aPage := stackPages stackPageAt: i.
(stackPages isFree: aPage) ifFalse:
["this to avoid assert in externalDivorceFrame:andContext:"
+ stackPages markStackPageMostRecentlyUsed: stackPage.
- self markStackPageMostRecentlyUsed: stackPage.
(self divorceAMachineCodeFrameWithCogMethod: cogMethod in: aPage) ifTrue:
[divorcedSome := true]]].
^divorcedSome!
Item was removed:
- ----- Method: CogObjectRepresentationFor32BitSpur>>genConvertIntegerToSmallIntegerInScratchReg: (in category 'compile abstract instructions') -----
- genConvertIntegerToSmallIntegerInScratchReg: scratchReg
- cogit LogicalShiftLeftCq: 1 R: scratchReg.
- cogit AddCq: 1 R: scratchReg.
- ^0!
Item was changed:
----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
genInnerPrimitiveAt: retNoffset
"Implement the guts of primitiveAt"
| formatReg jumpNotIndexable jumpSmallSize 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: #jumpSmallSize 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 *'>
cogit MoveR: ReceiverResultReg R: TempReg.
jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
cogit MoveR: Arg0Reg R: TempReg.
cogit MoveR: Arg0Reg R: Arg1Reg.
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.
"get numSlots into ClassReg."
cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
jumpSmallSize := cogit JumpBelow: 0.
cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
"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"
jumpSmallSize jmpTarget:
(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.
- self genConvertIntegerToSmallIntegerInScratchReg: 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.
- self genConvertIntegerToSmallIntegerInScratchReg: 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
jumpSmallSize 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: #jumpSmallSize 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 *'>
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: TempReg.
"get numSlots into ClassReg."
cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
jumpSmallSize := cogit JumpBelow: 0.
cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
"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"
jumpSmallSize jmpTarget:
(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.
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.
- self genConvertIntegerToSmallIntegerInScratchReg: Arg0Reg.
jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label).
^0!
Item was changed:
----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveStringAtPut: (in category 'primitive generators') -----
genInnerPrimitiveStringAtPut: retNoffset
"Implement the guts of primitiveStringAtPut"
| formatReg jumpSmallSize 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: #jumpSmallSize type: #'AbstractInstruction *'>
<var: #jumpImmediate type: #'AbstractInstruction *'>
<var: #jumpWordsDone type: #'AbstractInstruction *'>
<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
<var: #jumpShortsUnsupported type: #'AbstractInstruction *'>
<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
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: TempReg.
"get numSlots into ClassReg."
cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
jumpSmallSize := cogit JumpBelow: 0.
cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
"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"
jumpSmallSize jmpTarget:
(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.
- self genConvertIntegerToSmallIntegerInScratchReg: Arg0Reg.
jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label).
^0!
Item was removed:
- ----- Method: CogObjectRepresentationForSqueakV3>>genConvertIntegerToSmallIntegerInScratchReg: (in category 'compile abstract instructions') -----
- genConvertIntegerToSmallIntegerInScratchReg: scratchReg
- cogit LogicalShiftLeftCq: 1 R: scratchReg.
- cogit AddCq: 1 R: scratchReg.
- ^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 *'>
cogit MoveR: ReceiverResultReg R: TempReg.
jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
cogit MoveR: Arg0Reg R: TempReg.
cogit MoveR: Arg0Reg R: Arg1Reg.
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.
- self genConvertIntegerToSmallIntegerInScratchReg: 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 added:
+ ----- Method: CurrentImageCoInterpreterFacade>>methodClassOf: (in category 'object map') -----
+ methodClassOf: methodOop
+ ^self oopForObject: (self objectForOop: methodOop) methodClass!
Item was changed:
----- Method: SimpleStackBasedCogit class>>initializeBytecodeTableForNewspeakV3PlusClosures (in category 'class initialization') -----
initializeBytecodeTableForNewspeakV3PlusClosures
"SimpleStackBasedCogit initializeBytecodeTableForNewspeakV3PlusClosures"
NSSendIsPCAnnotated := true. "IsNSSendCall used by PushImplicitReceiver"
FirstSpecialSelector := 176.
self flag:
'Special selector send class must be inlined to agree with the interpreter, which
inlines class. If class is sent to e.g. a general instance of ProtoObject then unless
class is inlined there will be an MNU. It must be that the Cointerpreter and Cogit
have identical semantics. We get away with not hardwiring the other special
selectors either because in the Cointerpreter they are not inlined or because they
are inlined only to instances of classes for which there will always be a method.'.
self generatorTableFrom: #(
(1 0 15 genPushReceiverVariableBytecode)
(1 16 31 genPushTemporaryVariableBytecode)
(1 32 63 genPushLiteralConstantBytecode needsFrameNever: 1)
(1 64 95 genPushLiteralVariableBytecode needsFrameNever: 1)
(1 96 103 genStoreAndPopReceiverVariableBytecode needsFrameNever: -1) "N.B. not frameless if immutability"
(1 104 111 genStoreAndPopTemporaryVariableBytecode)
(1 112 112 genPushReceiverBytecode)
(1 113 113 genPushConstantTrueBytecode needsFrameNever: 1)
(1 114 114 genPushConstantFalseBytecode needsFrameNever: 1)
(1 115 115 genPushConstantNilBytecode needsFrameNever: 1)
(1 116 119 genPushQuickIntegerConstantBytecode needsFrameNever: 1)
"method returns in blocks need a frame because of nonlocalReturn:through:"
(1 120 120 genReturnReceiver return needsFrameIfInBlock: isMappedInBlock 0)
(1 121 121 genReturnTrue return needsFrameIfInBlock: isMappedInBlock 0)
(1 122 122 genReturnFalse return needsFrameIfInBlock: isMappedInBlock 0)
(1 123 123 genReturnNil return needsFrameIfInBlock: isMappedInBlock 0)
(1 124 124 genReturnTopFromMethod return needsFrameIfInBlock: isMappedInBlock -1)
(1 125 125 genReturnTopFromBlock return needsFrameNever: -1)
(3 126 126 unknownBytecode) "Was non-absent Newspeak super"
(2 127 127 unknownBytecode) "Was push implicit receiver"
+ (2 128 128 extendedPushBytecode)
- (2 128 128 extendedPushBytecode needsFrameNever: 1)
(2 129 129 extendedStoreBytecode)
(2 130 130 extendedStoreAndPopBytecode)
(2 131 131 genExtendedSendBytecode isMapped)
(3 132 132 doubleExtendedDoAnythingBytecode isMapped)
(2 133 133 genExtendedSuperBytecode isMapped)
(2 134 134 genSecondExtendedSendBytecode isMapped)
(1 135 135 genPopStackBytecode needsFrameNever: -1)
(1 136 136 duplicateTopBytecode needsFrameNever: 1)
(1 137 137 genPushActiveContextBytecode)
(2 138 138 genPushNewArrayBytecode)
+ (3 139 139 genCallPrimitiveBytecode)
- (3 139 139 callPrimitiveBytecode)
(3 140 140 genPushRemoteTempLongBytecode)
(3 141 141 genStoreRemoteTempLongBytecode)
(3 142 142 genStoreAndPopRemoteTempLongBytecode)
(4 143 143 genPushClosureCopyCopiedValuesBytecode block v3:Block:Code:Size:)
(1 144 151 genShortUnconditionalJump branch v3:ShortForward:Branch:Distance:)
(1 152 159 genShortJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(2 160 163 genLongUnconditionalBackwardJump branch isMapped "because of interrupt check"
v3:Long:Branch:Distance:)
(2 164 167 genLongUnconditionalForwardJump branch v3:Long:Branch:Distance:)
(2 168 171 genLongJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean"
v3:LongForward:Branch:Distance:)
(2 172 175 genLongJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:LongForward:Branch:Distance:)
(1 176 197 genSpecialSelectorSend isMapped)
(1 198 198 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
(1 199 199 genSpecialSelectorClass needsFrameNever: notMapped 0) "not mapped because it is directly inlined (for now)"
(1 200 207 genSpecialSelectorSend isMapped)
(1 208 223 genSendLiteralSelector0ArgsBytecode isMapped)
(1 224 239 genSendLiteralSelector1ArgBytecode isMapped)
(1 240 255 genSendLiteralSelector2ArgsBytecode isMapped))!
Item was changed:
----- Method: SimpleStackBasedCogit class>>initializeBytecodeTableForNewspeakV4 (in category 'class initialization') -----
initializeBytecodeTableForNewspeakV4
"SimpleStackBasedCogit initializeBytecodeTableForNewspeakV4"
NSSendIsPCAnnotated := false. "IsNSSendCall used by SendAbsentImplicit"
FirstSpecialSelector := 80.
self flag:
'Special selector send class must be inlined to agree with the interpreter, which
inlines class. If class is sent to e.g. a general instance of ProtoObject then unless
class is inlined there will be an MNU. It must be that the Cointerpreter and Cogit
have identical semantics. We get away with not hardwiring the other special
selectors either because in the Cointerpreter they are not inlined or because they
are inlined only to instances of classes for which there will always be a method.'.
self generatorTableFrom: #(
"1 byte bytecodes"
(1 0 15 genPushReceiverVariableBytecode)
(1 16 31 genPushLiteralVariable16CasesBytecode needsFrameNever: 1)
(1 32 63 genPushLiteralConstantBytecode needsFrameNever: 1)
(1 64 75 genPushTemporaryVariableBytecode)
(1 76 76 genPushReceiverBytecode)
(1 77 77 genExtPushPseudoVariableOrOuterBytecode)
(1 78 78 genPushConstantZeroBytecode)
(1 79 79 genPushConstantOneBytecode)
(1 80 101 genSpecialSelectorSend isMapped) "#+ #- #< #> #<= #>= #= #~= #* #/ #\\ #@ #bitShift: #// #bitAnd: #bitOr: #at: #at:put: #size #next #nextPut: #atEnd"
(1 102 102 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
(1 103 103 genSpecialSelectorClass needsFrameNever: notMapped 0) "not mapped because it is directly inlined (for now)"
(1 104 111 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
(1 112 127 genSendLiteralSelector0ArgsBytecode isMapped)
(1 128 143 genSendLiteralSelector1ArgBytecode isMapped)
(1 144 159 genSendLiteralSelector2ArgsBytecode isMapped)
(1 160 175 genSendAbsentImplicit0ArgsBytecode isMapped hasIRC)
(1 176 183 genStoreAndPopReceiverVariableBytecode needsFrameNever: -1) "N.B. not frameless if immutability"
(1 184 191 genStoreAndPopTemporaryVariableBytecode)
(1 192 199 genShortUnconditionalJump branch v3:ShortForward:Branch:Distance:)
(1 200 207 genShortJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(1 208 215 genShortJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(1 216 216 genReturnReceiver return needsFrameIfInBlock: isMappedInBlock 0)
(1 217 217 genReturnTopFromMethod return needsFrameIfInBlock: isMappedInBlock -1)
(1 218 218 genExtReturnTopFromBlock return needsFrameNever: -1)
(1 219 219 duplicateTopBytecode needsFrameNever: 1)
(1 220 220 genPopStackBytecode needsFrameNever: -1)
(1 221 221 genExtNopBytecode needsFrameNever: 0)
(1 222 223 unknownBytecode)
"2 byte bytecodes"
(2 224 224 extABytecode extension)
(2 225 225 extBBytecode extension)
(2 226 226 genExtPushReceiverVariableBytecode)
(2 227 227 genExtPushLiteralVariableBytecode needsFrameNever: 1)
(2 228 228 genExtPushLiteralBytecode needsFrameNever: 1)
(2 229 229 genExtPushIntegerBytecode needsFrameNever: 1)
(2 230 230 genLongPushTemporaryVariableBytecode)
(2 231 231 genPushNewArrayBytecode)
(2 232 232 genExtStoreReceiverVariableBytecode)
(2 233 233 genExtStoreLiteralVariableBytecode)
(2 234 234 genLongStoreTemporaryVariableBytecode)
(2 235 235 genExtStoreAndPopReceiverVariableBytecode)
(2 236 236 genExtStoreAndPopLiteralVariableBytecode)
(2 237 237 genLongStoreAndPopTemporaryVariableBytecode)
(2 238 238 genExtSendBytecode isMapped)
(2 239 239 genExtSendSuperBytecode isMapped)
(2 240 240 genExtSendAbsentImplicitBytecode isMapped hasIRC)
(2 241 241 genExtSendAbsentDynamicSuperBytecode isMapped)
(2 242 242 genExtUnconditionalJump branch isMapped "because of interrupt check" v4:Long:Branch:Distance:)
(2 243 243 genExtJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
(2 244 244 genExtJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
(2 245 245 genExtSendAbsentSelfBytecode isMapped)
(2 246 248 unknownBytecode)
"3 byte bytecodes"
+ (3 249 249 genCallPrimitiveBytecode)
- (3 249 249 callPrimitiveBytecode)
(3 250 250 genPushRemoteTempLongBytecode)
(3 251 251 genStoreRemoteTempLongBytecode)
(3 252 252 genStoreAndPopRemoteTempLongBytecode)
(3 253 253 genExtPushClosureBytecode block v4:Block:Code:Size:)
(3 254 254 genExtSendAbsentOuterBytecode isMapped hasIRC)
(3 255 255 unknownBytecode))!
Item was changed:
----- Method: SimpleStackBasedCogit class>>initializeBytecodeTableForSqueakV3PlusClosures (in category 'class initialization') -----
initializeBytecodeTableForSqueakV3PlusClosures
"SimpleStackBasedCogit initializeBytecodeTableForSqueakV3PlusClosures"
FirstSpecialSelector := 176.
self flag:
'Special selector send class must be inlined to agree with the interpreter, which
inlines class. If class is sent to e.g. a general instance of ProtoObject then unless
class is inlined there will be an MNU. It must be that the Cointerpreter and Cogit
have identical semantics. We get away with not hardwiring the other special
selectors either because in the Cointerpreter they are not inlined or because they
are inlined only to instances of classes for which there will always be a method.'.
self generatorTableFrom: #(
(1 0 15 genPushReceiverVariableBytecode)
(1 16 31 genPushTemporaryVariableBytecode)
(1 32 63 genPushLiteralConstantBytecode needsFrameNever: 1)
(1 64 95 genPushLiteralVariableBytecode needsFrameNever: 1)
(1 96 103 genStoreAndPopReceiverVariableBytecode needsFrameNever: -1) "N.B. not frameless if immutability"
(1 104 111 genStoreAndPopTemporaryVariableBytecode)
(1 112 112 genPushReceiverBytecode)
(1 113 113 genPushConstantTrueBytecode needsFrameNever: 1)
(1 114 114 genPushConstantFalseBytecode needsFrameNever: 1)
(1 115 115 genPushConstantNilBytecode needsFrameNever: 1)
(1 116 119 genPushQuickIntegerConstantBytecode needsFrameNever: 1)
"method returns in blocks need a frame because of nonlocalReturn:through:"
(1 120 120 genReturnReceiver return needsFrameIfInBlock: isMappedInBlock 0)
(1 121 121 genReturnTrue return needsFrameIfInBlock: isMappedInBlock 0)
(1 122 122 genReturnFalse return needsFrameIfInBlock: isMappedInBlock 0)
(1 123 123 genReturnNil return needsFrameIfInBlock: isMappedInBlock 0)
(1 124 124 genReturnTopFromMethod return needsFrameIfInBlock: isMappedInBlock -1)
(1 125 125 genReturnTopFromBlock return needsFrameNever: -1)
(1 126 127 unknownBytecode)
+ (2 128 128 extendedPushBytecode)
- (2 128 128 extendedPushBytecode needsFrameNever: 1)
(2 129 129 extendedStoreBytecode)
(2 130 130 extendedStoreAndPopBytecode)
(2 131 131 genExtendedSendBytecode isMapped)
(3 132 132 doubleExtendedDoAnythingBytecode isMapped)
(2 133 133 genExtendedSuperBytecode isMapped)
(2 134 134 genSecondExtendedSendBytecode isMapped)
(1 135 135 genPopStackBytecode needsFrameNever: -1)
(1 136 136 duplicateTopBytecode needsFrameNever: 1)
(1 137 137 genPushActiveContextBytecode)
(2 138 138 genPushNewArrayBytecode)),
((initializationOptions at: #SpurObjectMemory ifAbsent: [false])
+ ifTrue: [#((3 139 139 genCallPrimitiveBytecode))]
- ifTrue: [#((3 139 139 callPrimitiveBytecode))]
ifFalse: [#((1 139 139 unknownBytecode))]),
#(
(3 140 140 genPushRemoteTempLongBytecode)
(3 141 141 genStoreRemoteTempLongBytecode)
(3 142 142 genStoreAndPopRemoteTempLongBytecode)
(4 143 143 genPushClosureCopyCopiedValuesBytecode block v3:Block:Code:Size:)
(1 144 151 genShortUnconditionalJump branch v3:ShortForward:Branch:Distance:)
(1 152 159 genShortJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(2 160 163 genLongUnconditionalBackwardJump branch isMapped "because of interrupt check"
v3:Long:Branch:Distance:)
(2 164 167 genLongUnconditionalForwardJump branch v3:Long:Branch:Distance:)
(2 168 171 genLongJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean"
v3:LongForward:Branch:Distance:)
(2 172 175 genLongJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:LongForward:Branch:Distance:)
(1 176 197 genSpecialSelectorSend isMapped)
(1 198 198 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
(1 199 199 genSpecialSelectorClass needsFrameNever: notMapped 0) "not mapped because it is directly inlined (for now)"
(1 200 207 genSpecialSelectorSend isMapped)
(1 208 223 genSendLiteralSelector0ArgsBytecode isMapped)
(1 224 239 genSendLiteralSelector1ArgBytecode isMapped)
(1 240 255 genSendLiteralSelector2ArgsBytecode isMapped))!
Item was removed:
- ----- Method: SimpleStackBasedCogit>>callPrimitiveBytecode (in category 'bytecode generators') -----
- callPrimitiveBytecode
- "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)
- NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)
- SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256)
- m=1 means inlined primitive, no hard return after execution."
- self assert: (primitiveIndex = (byte1 + (byte2 << 8))
- or: [primitiveIndex = 0 "disabled primitives, e.g. stream prims"
- and: [(coInterpreter primitiveIndexOf: methodObj) = (byte1 + (byte2 << 8))]]).
- ^0!
Item was changed:
----- Method: SimpleStackBasedCogit>>genCallPrimitiveBytecode (in category 'bytecode generators') -----
genCallPrimitiveBytecode
+ "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)
+ NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)
+ SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256)
+ m=1 means inlined primitive, no hard return after execution."
+ bytecodePC ~= initialPC ifTrue:
+ [^EncounteredUnknownBytecode].
+ self assert: (primitiveIndex = (byte1 + (byte2 << 8))
+ or: [primitiveIndex = 0 "disabled primitives, e.g. stream prims"
+ and: [(coInterpreter primitiveIndexOf: methodObj) = (byte1 + (byte2 << 8))]]).
+ ^0!
- "SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution."
- "This makes sense only for the optimizing JITs"
- ^EncounteredUnknownBytecode!
Item was added:
+ ----- Method: StackDepthFinder>>callInlinePrimitive: (in category 'instruction decoding') -----
+ callInlinePrimitive: primitiveIndex
+ "The convention for inline primitives is that the argument count is primitiveIndex // 1000 - 1,
+ so receiverless 0-arg prims are from 0 to 999 (does this even make sense?), 0-arg prims
+ are from 1 to 1999, 2-arg prims from 1000 to 1999, and so on."
+ self drop: (primitiveIndex // 1000 - 1 max: 0)!
Item was changed:
----- Method: StackToRegisterMappingCogit class>>initializeBytecodeTableForNewspeakV4 (in category 'class initialization') -----
initializeBytecodeTableForNewspeakV4
"StackToRegisterMappingCogit initializeBytecodeTableForNewspeakV4"
numPushNilsFunction := #v4:Num:Push:Nils:.
pushNilSizeFunction := #v4PushNilSize:numInitialNils:.
NSSendIsPCAnnotated := true. "IsNSSendCall used by SendAbsentImplicit"
FirstSpecialSelector := 80.
self flag:
'Special selector send class must be inlined to agree with the interpreter, which
inlines class. If class is sent to e.g. a general instance of ProtoObject then unless
class is inlined there will be an MNU. It must be that the Cointerpreter and Cogit
have identical semantics. We get away with not hardwiring the other special
selectors either because in the Cointerpreter they are not inlined or because they
are inlined only to instances of classes for which there will always be a method.'.
self generatorTableFrom: #(
"1 byte bytecodes"
(1 0 15 genPushReceiverVariableBytecode needsFrameNever: 1)
(1 16 31 genPushLiteralVariable16CasesBytecode needsFrameNever: 1)
(1 32 63 genPushLiteralConstantBytecode needsFrameNever: 1)
(1 64 75 genPushTemporaryVariableBytecode needsFrameIfMod16GENumArgs: 1)
(1 76 76 genPushReceiverBytecode needsFrameNever: 1)
(1 77 77 genExtPushPseudoVariableOrOuterBytecode needsFrameIfExtBGT2: 1)
(1 78 78 genPushConstantZeroBytecode needsFrameNever: 1)
(1 79 79 genPushConstantOneBytecode needsFrameNever: 1)
(1 80 80 genSpecialSelectorArithmetic isMapped AddRR)
(1 81 81 genSpecialSelectorArithmetic isMapped SubRR)
(1 82 82 genSpecialSelectorComparison isMapped JumpLess)
(1 83 83 genSpecialSelectorComparison isMapped JumpGreater)
(1 84 84 genSpecialSelectorComparison isMapped JumpLessOrEqual)
(1 85 85 genSpecialSelectorComparison isMapped JumpGreaterOrEqual)
(1 86 86 genSpecialSelectorComparison isMapped JumpZero)
(1 87 87 genSpecialSelectorComparison isMapped JumpNonZero)
(1 88 93 genSpecialSelectorSend isMapped) " #* #/ #\\ #@ #bitShift: //"
(1 94 94 genSpecialSelectorArithmetic isMapped AndRR)
(1 95 95 genSpecialSelectorArithmetic isMapped OrRR)
(1 96 101 genSpecialSelectorSend isMapped) "#at: #at:put: #size #next #nextPut: #atEnd"
(1 102 102 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
(1 103 103 genSpecialSelectorClass needsFrameIfStackGreaterThanOne: notMapped 0) "not mapped because it is directly inlined (for now)"
(1 104 111 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
(1 112 127 genSendLiteralSelector0ArgsBytecode isMapped)
(1 128 143 genSendLiteralSelector1ArgBytecode isMapped)
(1 144 159 genSendLiteralSelector2ArgsBytecode isMapped)
(1 160 175 genSendAbsentImplicit0ArgsBytecode isMapped hasIRC)
(1 176 183 genStoreAndPopReceiverVariableBytecode needsFrameNever: -1) "N.B. not frameless if immutability"
(1 184 191 genStoreAndPopTemporaryVariableBytecode)
(1 192 199 genShortUnconditionalJump branch v3:ShortForward:Branch:Distance:)
(1 200 207 genShortJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(1 208 215 genShortJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(1 216 216 genReturnReceiver return needsFrameIfInBlock: isMappedInBlock 0)
(1 217 217 genReturnTopFromMethod return needsFrameIfInBlock: isMappedInBlock -1)
(1 218 218 genExtReturnTopFromBlock return needsFrameNever: -1)
(1 219 219 duplicateTopBytecode needsFrameNever: 1)
(1 220 220 genPopStackBytecode needsFrameNever: -1)
(1 221 221 genExtNopBytecode needsFrameNever: 0)
(1 222 223 unknownBytecode)
"2 byte bytecodes"
(2 224 224 extABytecode extension needsFrameNever: 0)
(2 225 225 extBBytecode extension needsFrameNever: 0)
(2 226 226 genExtPushReceiverVariableBytecode)
(2 227 227 genExtPushLiteralVariableBytecode needsFrameNever: 1)
(2 228 228 genExtPushLiteralBytecode needsFrameNever: 1)
(2 229 229 genExtPushIntegerBytecode needsFrameNever: 1)
(2 230 230 genLongPushTemporaryVariableBytecode)
(2 231 231 genPushNewArrayBytecode)
(2 232 232 genExtStoreReceiverVariableBytecode)
(2 233 233 genExtStoreLiteralVariableBytecode)
(2 234 234 genLongStoreTemporaryVariableBytecode)
(2 235 235 genExtStoreAndPopReceiverVariableBytecode)
(2 236 236 genExtStoreAndPopLiteralVariableBytecode)
(2 237 237 genLongStoreAndPopTemporaryVariableBytecode)
(2 238 238 genExtSendBytecode isMapped)
(2 239 239 genExtSendSuperBytecode isMapped)
(2 240 240 genExtSendAbsentImplicitBytecode isMapped hasIRC)
(2 241 241 genExtSendAbsentDynamicSuperBytecode isMapped)
(2 242 242 genExtUnconditionalJump branch isMapped "because of interrupt check" v4:Long:Branch:Distance:)
(2 243 243 genExtJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
(2 244 244 genExtJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
(2 245 245 genExtSendAbsentSelfBytecode isMapped)
(2 246 248 unknownBytecode)
"3 byte bytecodes"
+ (3 249 249 genCallPrimitiveBytecode)
- (3 249 249 callPrimitiveBytecode)
(3 250 250 genPushRemoteTempLongBytecode)
(3 251 251 genStoreRemoteTempLongBytecode)
(3 252 252 genStoreAndPopRemoteTempLongBytecode)
(3 253 253 genExtPushClosureBytecode block v4:Block:Code:Size:)
(3 254 254 genExtSendAbsentOuterBytecode isMapped hasIRC)
(3 255 255 unknownBytecode))!
Item was changed:
----- Method: StackToRegisterMappingCogit class>>initializeBytecodeTableForSqueakV3PlusClosures (in category 'class initialization') -----
initializeBytecodeTableForSqueakV3PlusClosures
"StackToRegisterMappingCogit initializeBytecodeTableForSqueakV3PlusClosures"
numPushNilsFunction := #v3:Num:Push:Nils:.
pushNilSizeFunction := #v3PushNilSize:numInitialNils:.
FirstSpecialSelector := 176.
self flag:
'Special selector send class must be inlined to agree with the interpreter, which
inlines class. If class is sent to e.g. a general instance of ProtoObject then unless
class is inlined there will be an MNU. It must be that the Cointerpreter and Cogit
have identical semantics. We get away with not hardwiring the other special
selectors either because in the Cointerpreter they are not inlined or because they
are inlined only to instances of classes for which there will always be a method.'.
self generatorTableFrom: #(
(1 0 15 genPushReceiverVariableBytecode needsFrameNever: 1)
(1 16 31 genPushTemporaryVariableBytecode needsFrameIfMod16GENumArgs: 1)
(1 32 63 genPushLiteralConstantBytecode needsFrameNever: 1)
(1 64 95 genPushLiteralVariableBytecode needsFrameNever: 1)
(1 96 103 genStoreAndPopReceiverVariableBytecode needsFrameNever: -1) "N.B. not frameless if immutability"
(1 104 111 genStoreAndPopTemporaryVariableBytecode)
(1 112 112 genPushReceiverBytecode needsFrameNever: 1)
(1 113 113 genPushConstantTrueBytecode needsFrameNever: 1)
(1 114 114 genPushConstantFalseBytecode needsFrameNever: 1)
(1 115 115 genPushConstantNilBytecode needsFrameNever: 1)
(1 116 119 genPushQuickIntegerConstantBytecode needsFrameNever: 1)
"method returns in blocks need a frame because of nonlocalReturn:through:"
(1 120 120 genReturnReceiver return needsFrameIfInBlock: isMappedInBlock 0)
(1 121 121 genReturnTrue return needsFrameIfInBlock: isMappedInBlock 0)
(1 122 122 genReturnFalse return needsFrameIfInBlock: isMappedInBlock 0)
(1 123 123 genReturnNil return needsFrameIfInBlock: isMappedInBlock 0)
(1 124 124 genReturnTopFromMethod return needsFrameIfInBlock: isMappedInBlock -1)
(1 125 125 genReturnTopFromBlock return needsFrameNever: -1)
(1 126 127 unknownBytecode)
+ (2 128 128 extendedPushBytecode)
- (2 128 128 extendedPushBytecode needsFrameNever: 1)
(2 129 129 extendedStoreBytecode)
(2 130 130 extendedStoreAndPopBytecode)
(2 131 131 genExtendedSendBytecode isMapped)
(3 132 132 doubleExtendedDoAnythingBytecode isMapped)
(2 133 133 genExtendedSuperBytecode isMapped)
(2 134 134 genSecondExtendedSendBytecode isMapped)
(1 135 135 genPopStackBytecode needsFrameNever: -1)
(1 136 136 duplicateTopBytecode needsFrameNever: 1)
(1 137 137 genPushActiveContextBytecode)
(2 138 138 genPushNewArrayBytecode)),
((initializationOptions at: #SpurObjectMemory ifAbsent: [false])
+ ifTrue: [#((3 139 139 genCallPrimitiveBytecode))]
- ifTrue: [#((3 139 139 callPrimitiveBytecode))]
ifFalse: [#((1 139 139 unknownBytecode))]),
#(
(3 140 140 genPushRemoteTempLongBytecode)
(3 141 141 genStoreRemoteTempLongBytecode)
(3 142 142 genStoreAndPopRemoteTempLongBytecode)
(4 143 143 genPushClosureCopyCopiedValuesBytecode block v3:Block:Code:Size:)
(1 144 151 genShortUnconditionalJump branch v3:ShortForward:Branch:Distance:)
(1 152 159 genShortJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:ShortForward:Branch:Distance:)
(2 160 163 genLongUnconditionalBackwardJump branch isMapped "because of interrupt check"
v3:Long:Branch:Distance:)
(2 164 167 genLongUnconditionalForwardJump branch v3:Long:Branch:Distance:)
(2 168 171 genLongJumpIfTrue branch isBranchTrue isMapped "because of mustBeBoolean"
v3:LongForward:Branch:Distance:)
(2 172 175 genLongJumpIfFalse branch isBranchFalse isMapped "because of mustBeBoolean"
v3:LongForward:Branch:Distance:)
(1 176 176 genSpecialSelectorArithmetic isMapped AddRR)
(1 177 177 genSpecialSelectorArithmetic isMapped SubRR)
(1 178 178 genSpecialSelectorComparison isMapped JumpLess)
(1 179 179 genSpecialSelectorComparison isMapped JumpGreater)
(1 180 180 genSpecialSelectorComparison isMapped JumpLessOrEqual)
(1 181 181 genSpecialSelectorComparison isMapped JumpGreaterOrEqual)
(1 182 182 genSpecialSelectorComparison isMapped JumpZero)
(1 183 183 genSpecialSelectorComparison isMapped JumpNonZero)
(1 184 189 genSpecialSelectorSend isMapped) " #* #/ #\\ #@ #bitShift: //"
(1 190 190 genSpecialSelectorArithmetic isMapped AndRR)
(1 191 191 genSpecialSelectorArithmetic isMapped OrRR)
(1 192 197 genSpecialSelectorSend isMapped) "#at: #at:put: #size #next #nextPut: #atEnd"
(1 198 198 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
(1 199 199 genSpecialSelectorClass needsFrameIfStackGreaterThanOne: notMapped 0) "not mapped because it is directly inlined (for now)"
(1 200 207 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
(1 208 223 genSendLiteralSelector0ArgsBytecode isMapped)
(1 224 239 genSendLiteralSelector1ArgBytecode isMapped)
(1 240 255 genSendLiteralSelector2ArgsBytecode isMapped))!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genBinaryConstOpVarInlinePrimitive: (in category 'inline primitive generators') -----
genBinaryConstOpVarInlinePrimitive: prim
"Const op var version of binary inline primitives."
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
| ra val untaggedVal adjust |
(ra := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
[self ssAllocateRequiredReg:
(ra := optStatus isReceiverResultRegLive
ifTrue: [Arg0Reg]
ifFalse: [ReceiverResultReg])].
ra = ReceiverResultReg ifTrue:
[optStatus isReceiverResultRegLive: false].
self ssTop popToReg: ra.
self ssPop: 1.
val := self ssTop constant.
self ssPop: 1.
untaggedVal := val - objectMemory smallIntegerTag.
prim caseOf: {
"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
[0] -> [self AddCq: untaggedVal R: ra].
[1] -> [self MoveCq: val R: TempReg.
self SubR: ra R: TempReg.
objectRepresentation genAddSmallIntegerTagsTo: TempReg.
self MoveR: TempReg R: ra].
[2] -> [objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ra.
self MoveCq: (objectMemory integerValueOf: val) R: TempReg.
self MulR: TempReg R: ra.
objectRepresentation genAddSmallIntegerTagsTo: ra].
"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
"2032 through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)"
[32] -> [ self CmpCq: val R: ra.
self genBinaryInlineComparison: JumpGreater opFalse: JumpLess destReg: ra ].
[33] -> [ self CmpCq: val R: ra.
self genBinaryInlineComparison: JumpLess opFalse: JumpGreater destReg: ra ].
[34] -> [ self CmpCq: val R: ra.
self genBinaryInlineComparison: JumpGreaterOrEqual opFalse: JumpLessOrEqual destReg: ra ].
[35] -> [ self CmpCq: val R: ra.
self genBinaryInlineComparison: JumpLessOrEqual opFalse: JumpGreaterOrEqual destReg: ra ].
[36] -> [ self CmpCq: val R: ra.
self genBinaryInlineComparison: JumpZero opFalse: JumpNonZero destReg: ra ].
[37] -> [ self CmpCq: val R: ra.
self genBinaryInlineComparison: JumpNonZero opFalse: JumpZero destReg: ra ].
"2064 through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
+ [64] -> [objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
- [64] -> [self genConvertSmallIntegerToIntegerInReg: ra.
adjust := (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra. ].
+ self annotate: (self MoveCw: val R: TempReg) objRef: val.
- self MoveCq: val R: TempReg.
self MoveXwr: ra R: TempReg R: ra].
+ [65] -> [objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
- [65] -> [self genConvertSmallIntegerToIntegerInReg: ra.
adjust := objectMemory baseHeaderSize - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
self AddCq: adjust R: ra.
+ self annotate: (self MoveCw: val R: TempReg) objRef: val.
- self MoveCq: val R: TempReg.
self MoveXbr: ra R: TempReg R: ra]
}
otherwise: [^EncounteredUnknownBytecode].
self ssPushRegister: ra.
^0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genBinaryVarOpConstInlinePrimitive: (in category 'inline primitive generators') -----
genBinaryVarOpConstInlinePrimitive: prim
"Var op const version of inline binary inline primitives."
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
| rr val untaggedVal |
(rr := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
[self ssAllocateRequiredReg:
(rr := optStatus isReceiverResultRegLive
ifTrue: [Arg0Reg]
ifFalse: [ReceiverResultReg])].
rr = ReceiverResultReg ifTrue:
[optStatus isReceiverResultRegLive: false].
val := self ssTop constant.
self ssPop: 1.
self ssTop popToReg: rr.
self ssPop: 1.
untaggedVal := val - objectMemory smallIntegerTag.
prim caseOf: {
"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
[0] -> [self AddCq: untaggedVal R: rr].
[1] -> [self SubCq: untaggedVal R: rr ].
[2] -> [self flag: 'could use MulCq:R'.
objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: rr.
self MoveCq: (objectMemory integerValueOf: val) R: TempReg.
self MulR: TempReg R: rr.
objectRepresentation genAddSmallIntegerTagsTo: rr].
"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
"2032 through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)
Here the comparison is reversed (cst on the left, reg on the right) so I inverted opTrue and opFalse"
[32] -> [ self CmpCq: val R: rr.
self genBinaryInlineComparison: JumpLess opFalse: JumpGreater destReg: rr ].
[33] -> [ self CmpCq: val R: rr.
self genBinaryInlineComparison: JumpGreater opFalse: JumpLess destReg: rr ].
[34] -> [ self CmpCq: val R: rr.
self genBinaryInlineComparison: JumpLessOrEqual opFalse: JumpGreaterOrEqual destReg: rr ].
[35] -> [ self CmpCq: val R: rr.
self genBinaryInlineComparison: JumpGreaterOrEqual opFalse: JumpLessOrEqual destReg: rr ].
[36] -> [ self CmpCq: val R: rr.
self genBinaryInlineComparison: JumpNonZero opFalse: JumpZero destReg: rr ].
[37] -> [ self CmpCq: val R: rr.
self genBinaryInlineComparison: JumpZero opFalse: JumpNonZero destReg: rr ].
"2064 through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
+ [64] -> [objectRepresentation genLoadSlot: (objectMemory integerValueOf: val) - 1 sourceReg: rr destReg: rr].
+ [65] -> [self MoveCq: (objectMemory integerValueOf: val) + objectMemory baseHeaderSize - 1 R: TempReg.
+ self MoveXbr: TempReg R: rr R: rr.
+ objectRepresentation genConvertIntegerToSmallIntegerInReg: rr]
- [64] -> [self genConvertSmallIntegerToIntegerInReg: rr.
- self MoveCq: (objectMemory integerValueOf: val) + (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1 R: TempReg.
- self MoveXwr: TempReg R: rr R: rr ].
- [65] -> [self genConvertSmallIntegerToIntegerInReg: rr.
- self MoveCq: (objectMemory integerValueOf: val) + objectMemory baseHeaderSize - 1 R: TempReg.
- self MoveXbr: TempReg R: rr R: rr ]
}
otherwise: [^EncounteredUnknownBytecode].
self ssPushRegister: rr.
^0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genBinaryVarOpVarInlinePrimitive: (in category 'inline primitive generators') -----
genBinaryVarOpVarInlinePrimitive: prim
"Var op var version of binary inline primitives."
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
| ra rr adjust |
(rr := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
[self ssAllocateRequiredReg:
(rr := optStatus isReceiverResultRegLive
ifTrue: [Arg0Reg]
ifFalse: [ReceiverResultReg])].
(ra := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: rr))) ifNil:
[self ssAllocateRequiredReg: (ra := Arg1Reg)].
(rr = ReceiverResultReg or: [ra = ReceiverResultReg]) ifTrue:
[optStatus isReceiverResultRegLive: false].
self ssTop popToReg: ra.
self ssPop: 1.
self ssTop popToReg: rr.
self ssPop: 1.
prim caseOf: {
"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
[0] -> [objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ra.
self AddR: ra R: rr].
[1] -> [self SubR: ra R: rr.
objectRepresentation genAddSmallIntegerTagsTo: rr].
[2] -> [objectRepresentation genRemoveSmallIntegerTagsInScratchReg: rr.
objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: ra.
self MulR: ra R: rr.
objectRepresentation genAddSmallIntegerTagsTo: rr].
"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
"2032 through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)"
[32] -> [ self CmpR: rr R: ra.
self genBinaryInlineComparison: JumpGreater opFalse: JumpLess destReg: rr ].
[33] -> [ self CmpR: rr R: ra.
self genBinaryInlineComparison: JumpLess opFalse: JumpGreater destReg: rr ].
[34] -> [ self CmpR: rr R: ra.
self genBinaryInlineComparison: JumpGreaterOrEqual opFalse: JumpLessOrEqual destReg: rr ].
[35] -> [ self CmpR: rr R: ra.
self genBinaryInlineComparison: JumpLessOrEqual opFalse: JumpGreaterOrEqual destReg: rr ].
[36] -> [ self CmpR: rr R: ra.
self genBinaryInlineComparison: JumpZero opFalse: JumpNonZero destReg: rr ].
[37] -> [ self CmpR: rr R: ra.
self genBinaryInlineComparison: JumpNonZero opFalse: JumpZero destReg: rr ].
"2064 through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
+ [64] -> [objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
- [64] -> [self genConvertSmallIntegerToIntegerInReg: ra.
adjust := (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra. ].
self MoveXwr: ra R: rr R: rr ].
+ [65] -> [objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
- [65] -> [self genConvertSmallIntegerToIntegerInReg: ra.
adjust := objectMemory baseHeaderSize - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
self AddCq: adjust R: ra.
+ self MoveXbr: ra R: rr R: rr.
+ objectRepresentation genConvertIntegerToSmallIntegerInReg: rr]
- self MoveXbr: ra R: rr R: rr ]
}
otherwise: [^EncounteredUnknownBytecode].
self ssPushRegister: rr.
^0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genCallPrimitiveBytecode (in category 'bytecode generators') -----
genCallPrimitiveBytecode
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#inlinePrimitiveBytecode:"
| prim |
byte2 < 128 ifTrue:
+ [^bytecodePC = initialPC
+ ifTrue: [0]
+ ifFalse: [EncounteredUnknownBytecode]].
- [^EncounteredUnknownBytecode].
prim := byte2 - 128 << 8 + byte1.
prim < 1000 ifTrue:
[^self genNullaryInlinePrimitive: prim].
prim < 2000 ifTrue:
[^self genUnaryInlinePrimitive: prim - 1000].
prim < 3000 ifTrue:
[self ssTop type = SSConstant ifTrue:
[^self genBinaryVarOpConstInlinePrimitive: prim - 2000].
(self ssValue: 1) type = SSConstant ifTrue:
[^self genBinaryConstOpVarInlinePrimitive: prim - 2000].
^self genBinaryVarOpVarInlinePrimitive: prim - 2000].
prim < 4000 ifTrue:
[^self genTrinaryInlinePrimitive: prim - 3000].
^EncounteredUnknownBytecode!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genTrinaryInlinePrimitive: (in category 'inline primitive generators') -----
genTrinaryInlinePrimitive: prim
"Unary inline primitives."
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#trinaryInlinePrimitive:"
+ | ra1 ra2 rr adjust |
+ (ra2 := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
+ [self ssAllocateRequiredReg: (ra2 := Arg1Reg)].
+ (ra1 := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: ra2))) ifNil:
+ [self ssAllocateRequiredReg: (ra1 := Arg0Reg)].
+ (rr := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: ra1 and: ra2))) ifNil:
+ [self ssAllocateRequiredReg: (rr := ReceiverResultReg)].
+ (rr = ReceiverResultReg or: [ra1 = ReceiverResultReg or: [ra2 = ReceiverResultReg]]) ifTrue:
- | ra rr adjust |
- (rr := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
- [self ssAllocateRequiredReg:
- (rr := optStatus isReceiverResultRegLive
- ifTrue: [Arg0Reg]
- ifFalse: [ReceiverResultReg])].
- (ra := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: rr))) ifNil:
- [self ssAllocateRequiredReg: (ra := Arg1Reg)].
- (rr = ReceiverResultReg or: [ra = ReceiverResultReg]) ifTrue:
[optStatus isReceiverResultRegLive: false].
+ self assert: (rr ~= ra1 and: [rr ~= ra2 and: [ra1 ~= ra2]]).
+ self ssTop popToReg: ra2.
- self ssTop popToReg: TempReg.
self ssPop: 1.
+ self ssTop popToReg: ra1.
- self ssTop popToReg: ra.
self ssPop: 1.
self ssTop popToReg: rr.
self ssPop: 1.
+ objectRepresentation genConvertSmallIntegerToIntegerInReg: ra1.
- self ssPushRegister: TempReg.
- self genConvertSmallIntegerToIntegerInReg: ra.
"Now: ra is the variable object, rr is long, TempReg holds the value to store."
prim caseOf: {
"0 - 1 pointerAt:put: and byteAt:Put:"
[0] -> [ adjust := (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
+ adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra1. ].
+ self MoveR: ra2 Xwr: ra1 R: rr.
+ objectRepresentation genStoreCheckReceiverReg: rr valueReg: ra1 scratchReg: TempReg].
+ [1] -> [ objectRepresentation genConvertSmallIntegerToIntegerInReg: ra2.
- adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra. ].
- self MoveR: TempReg Xwr: ra R: rr ].
- [1] -> [ self genConvertSmallIntegerToIntegerInReg: TempReg.
adjust := objectMemory baseHeaderSize - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
+ self AddCq: adjust R: ra1.
+ self MoveR: ra2 Xbr: ra1 R: rr.
+ objectRepresentation genConvertIntegerToSmallIntegerInReg: ra2. ]
- self AddCq: adjust R: ra.
- self MoveR: TempReg Xbr: ra R: rr ]
}
otherwise: [^EncounteredUnknownBytecode].
+ self ssPushRegister: ra2.
^0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genUnaryInlinePrimitive: (in category 'inline primitive generators') -----
genUnaryInlinePrimitive: prim
"Unary inline primitives."
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#unaryInlinePrimitive:"
| rcvrReg resultReg |
self ssTop type = SSRegister
ifTrue: [rcvrReg := self ssTop register]
ifFalse:
[(rcvrReg := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
[self ssAllocateRequiredReg:
(rcvrReg := optStatus isReceiverResultRegLive
ifTrue: [Arg0Reg]
ifFalse: [ReceiverResultReg])]].
self ssTop popToReg: rcvrReg.
self ssPop: 1.
+ (resultReg := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: rcvrReg))) ifNil:
+ [self ssAllocateRequiredReg: (resultReg := Arg1Reg)].
- (resultReg := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
- [self ssFlushUpThroughRegister: rcvrReg].
prim
caseOf: {
[1] -> "01 unchecked pointer numSlots"
+ [objectRepresentation
- [resultReg ifNil: [resultReg := rcvrReg].
- objectRepresentation
genGetNumSlotsOf: rcvrReg into: resultReg;
+ genConvertIntegerToSmallIntegerInReg: resultReg].
- genConvertIntegerToSmallIntegerInScratchReg: resultReg.
- self ssPushRegister: resultReg].
[3] -> "03 unchecked byte numBytes"
+ [objectRepresentation
- [resultReg ifNil: [resultReg := rcvrReg].
- objectRepresentation
genGetNumBytesOf: rcvrReg into: resultReg;
+ genConvertIntegerToSmallIntegerInReg: resultReg].
- genConvertIntegerToSmallIntegerInScratchReg: resultReg.
- self ssPushRegister: resultReg].
}
otherwise:
+ [^EncounteredUnknownBytecode]..
+ self ssPushRegister: resultReg.
- [^EncounteredUnknownBytecode].
^0!
More information about the Vm-dev
mailing list