[Vm-dev] VM Maker: VMMaker.oscog-cb.1748.mcz
Clément Bera
bera.clement at gmail.com
Wed Mar 30 14:32:29 UTC 2016
It saves 2 bytes for inst var 0 and 5 bytes for inst var between 1 and 255
in x86. There is one less branch to take on the common path too. Not sure
if this matters a lot. The difference should be better on x64 as in x86
MoveCq:R: calls MoveCw:R: if the quick constant is not 0, and we have many
little constants more than 0.
Isn't there a better way to move quick constant to register on x86 than the
full word constant ? Maybe we should change MoveCq:R: on x86 to do a xor
reg,reg, movq r8 as suggested in the comment.
2016-03-30 15:52 GMT+02:00 <commits at source.squeak.org>:
>
> Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1748.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-cb.1748
> Author: cb
> Time: 30 March 2016, 3:52:01.732 pm
> UUID: db420bcd-e4aa-4cad-9543-047274e49915
> Ancestors: VMMaker.oscog-nice.1747
>
> Reworked machine code generation of immutability so for common stores it
> uses a single trampoline for both store checks and immutability checks.
>
> I have simulation bug due to large integers, so I am not entirely sure
> everything is working, but generated code looks good.
>
> =============== Diff against VMMaker.oscog-nice.1747 ===============
>
> Item was changed:
> ----- Method:
> CogObjectRepresentation>>genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:
> (in category 'compile abstract instructions') -----
> genStoreSourceReg: sourceReg slotIndex: index destReg: destReg
> scratchReg: scratchReg inFrame: inFrame
> + <inline: true>
> + self
> + cppIf: IMMUTABILITY
> + ifTrue:
> + [ ^ self
> + genStoreWithImmutabilityCheckSourceReg:
> sourceReg
> + slotIndex: index
> + destReg: destReg
> + scratchReg: scratchReg
> + needsStoreCheck: true
> + needRestoreRcvr: false "RcvrResultReg
> doesn't need to be live across the instructions" ]
> + ifFalse:
> + [ ^ self
> + genStoreSourceReg: sourceReg
> + slotIndex: index
> + destReg: destReg
> + scratchReg: scratchReg
> + inFrame: inFrame
> + needsStoreCheck: true ]!
> - ^ self
> - genStoreSourceReg: sourceReg
> - slotIndex: index
> - destReg: destReg
> - scratchReg: scratchReg
> - inFrame: inFrame
> - needsStoreCheck: true!
>
> Item was changed:
> CogObjectRepresentation subclass: #CogObjectRepresentationForSpur
> + instanceVariableNames: 'ceScheduleScavengeTrampoline
> ceSmallActiveContextInMethodTrampoline
> ceSmallActiveContextInBlockTrampoline
> ceLargeActiveContextInMethodTrampoline
> ceLargeActiveContextInBlockTrampoline ceStoreCheckContextReceiverTrampoline
> ceStoreTrampoline'
> - instanceVariableNames: 'ceScheduleScavengeTrampoline
> ceSmallActiveContextInMethodTrampoline
> ceSmallActiveContextInBlockTrampoline
> ceLargeActiveContextInMethodTrampoline
> ceLargeActiveContextInBlockTrampoline ceStoreCheckContextReceiverTrampoline
> ceCannotAssignToWithIndexTrampoline'
> classVariableNames: ''
> poolDictionaries: 'VMBytecodeConstants VMSqueakClassIndices'
> category: 'VMMaker-JIT'!
>
> Item was removed:
> - ----- Method:
> CogObjectRepresentationForSpur>>genImmutableCheck:slotIndex:sourceReg:scratchReg:needRestoreRcvr:
> (in category 'compile abstract instructions') -----
> - genImmutableCheck: regHoldingObjectMutated slotIndex: index sourceReg:
> regHoldingValueToStore scratchReg: scratchReg needRestoreRcvr:
> needRestoreRcvr
> - | mutableJump fail |
> - <var: #mutableJump type: #'AbstractInstruction *'>
> - <var: #fail type: #'AbstractInstruction *'>
> - <inline: true>
> - <option: #IMMUTABILITY>
> - "Trampoline convention:
> - - objectMutated passed in ReceiverResultReg
> - - index (unboxed) passed in TempReg
> - - valueToStore passed in ClassReg.
> - Simulated stack is flushed, but if needRestoreRcvr is true
> - the receiver has to be live after this operation."
> - self assert: regHoldingObjectMutated == ReceiverResultReg.
> - self assert: scratchReg == TempReg.
> - self assert: regHoldingValueToStore == ClassReg.
> - mutableJump := self genJumpMutable: ReceiverResultReg scratchReg:
> TempReg.
> -
> - "We reach this code if the object mutated is immutable."
> - cogit MoveCq: index R: TempReg.
> - "trampoline call and mcpc to bcpc annotation."
> - cogit CallRT: ceCannotAssignToWithIndexTrampoline.
> - cogit annotateBytecode: cogit Label.
> - "restore ReceiverResultReg state if needed, the rest of the state
> is spilled"
> - needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].
> - fail := cogit Jump: 0.
> -
> - "We reach this code is the object mutated is mutable"
> - mutableJump jmpTarget: cogit Label.
> -
> - ^ fail!
>
> Item was changed:
> ----- Method:
> CogObjectRepresentationForSpur>>genJumpBaseHeaderImmutable: (in category
> 'compile abstract instructions') -----
> genJumpBaseHeaderImmutable: baseHeaderReg
> "baseHeader holds at least the least significant 32 bits of the
> object"
> <returnTypeC: #'AbstractInstruction *'>
> <option: #IMMUTABILITY>
> + <inline: true>
> cogit TstCq: objectMemory immutableBitMask R: baseHeaderReg.
> ^ cogit JumpNonZero: 0!
>
> Item was changed:
> ----- Method: CogObjectRepresentationForSpur>>genJumpBaseHeaderMutable:
> (in category 'compile abstract instructions') -----
> genJumpBaseHeaderMutable: baseHeaderReg
> "baseHeader holds at least the least significant 32 bits of the
> object"
> <returnTypeC: #'AbstractInstruction *'>
> <option: #IMMUTABILITY>
> + <inline: true>
> cogit TstCq: objectMemory immutableBitMask R: baseHeaderReg.
> ^ cogit JumpZero: 0!
>
> Item was added:
> + ----- Method:
> CogObjectRepresentationForSpur>>genJumpImmutable:scratchReg: (in category
> 'compile abstract instructions') -----
> + genJumpImmutable: sourceReg scratchReg: scratchReg
> + <returnTypeC: #'AbstractInstruction *'>
> + <option: #IMMUTABILITY>
> + cogit MoveMw: 0 r: sourceReg R: scratchReg.
> + ^ self genJumpBaseHeaderImmutable: scratchReg!
>
> Item was changed:
> ----- Method:
> CogObjectRepresentationForSpur>>genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck:
> (in category 'compile abstract instructions') -----
> genStoreSourceReg: sourceReg slotIndex: index destReg: destReg
> scratchReg: scratchReg inFrame: inFrame needsStoreCheck: needsStoreCheck
> +
> + cogit genTraceStores.
> "do the store"
> cogit MoveR: sourceReg
> Mw: index * objectMemory wordSize + objectMemory
> baseHeaderSize
> r: destReg.
> "now the check. needStoreCheck is false if the JIT has figured out
> that the value stored does not need the check (immediate, nil, true, false)"
> needsStoreCheck ifTrue:
> [ ^ self
> genStoreCheckReceiverReg: destReg
> valueReg: sourceReg
> scratchReg: scratchReg
> inFrame: inFrame ].
> ^ 0!
>
> Item was added:
> + ----- Method: CogObjectRepresentationForSpur>>genStoreTrampolineCalled:
> (in category 'initialization') -----
> + genStoreTrampolineCalled: trampolineName
> + "This can be entered in one of two states, depending on TempReg.
> + TempReg = 0 => store check
> + TempReg > 0 => immutability failure
> + TempReg holds index + 1 in this case as the value 0 is reserved
> for store checks.
> + In addition the 0 value is convenient to save one instruction for
> store checks."
> + | jumpSC |
> + <var: #trampolineName type: #'char *'>
> + <var: #jumpSC type: #'AbstractInstruction *'>
> + <inline: false>
> + cogit zeroOpcodeIndex.
> + cogit CmpCq: 0 R: TempReg.
> + jumpSC := cogit JumpZero: 0.
> +
> + "CannotAssignTo:, we restore the index."
> + cogit SubCq: 1 R: TempReg.
> + cogit
> + compileTrampolineFor:
> #ceCannotAssignTo:withIndex:valueToAssign:
> + numArgs: 3
> + arg: ReceiverResultReg
> + arg: TempReg
> + arg: ClassReg
> + arg: nil
> + regsToSave: cogit emptyRegisterMask
> + pushLinkReg: true
> + resultReg: NoReg.
> +
> + "Store check"
> + jumpSC jmpTarget: cogit Label.
> + ^ cogit genTrampolineFor: #remember:
> + called: trampolineName
> + numArgs: 1
> + arg: ReceiverResultReg
> + arg: nil
> + arg: nil
> + arg: nil
> + regsToSave: cogit emptyRegisterMask
> + pushLinkReg: true
> + resultReg: NoReg
> + appendOpcodes: true!
>
> Item was added:
> + ----- Method:
> CogObjectRepresentationForSpur>>genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr:
> (in category 'compile abstract instructions') -----
> + genStoreWithImmutabilityAndStoreCheckSourceReg: sourceReg slotIndex:
> index destReg: destReg scratchReg: scratchReg needRestoreRcvr:
> needRestoreRcvr
> + "Store check code is duplicated to use a single trampoline"
> + <var: #immutableJump type: #'AbstractInstruction *'>
> + <var: #trampJump type: #'AbstractInstruction *'>
> + <var: #jmpImmediate type: #'AbstractInstruction *'>
> + <var: #jmpDestYoung type: #'AbstractInstruction *'>
> + <var: #jmpSourceOld type: #'AbstractInstruction *'>
> + <var: #jmpAlreadyRemembered type: #'AbstractInstruction *'>
> + | immutableJump trampJump jmpImmediate jmpDestYoung jmpSourceOld
> rememberedBitByteOffset jmpAlreadyRemembered mask |
> +
> + immutableJump := self genJumpImmutable: destReg scratchReg:
> scratchReg.
> +
> + cogit genTraceStores.
> +
> + "do the store"
> + cogit MoveR: sourceReg
> + Mw: index * objectMemory wordSize + objectMemory
> baseHeaderSize
> + r: destReg.
> +
> + "store check"
> + jmpImmediate := self genJumpImmediate: sourceReg.
> + "Get the old/new boundary in scratchReg"
> + cogit MoveCw: objectMemory storeCheckBoundary R: scratchReg.
> + "Is target young? If so we're done"
> + cogit CmpR: scratchReg R: destReg. "N.B. FLAGS := destReg -
> scratchReg"
> + jmpDestYoung := cogit JumpBelow: 0.
> + "Is value stored old? If so we're done."
> + cogit CmpR: scratchReg R: sourceReg. "N.B. FLAGS := valueReg -
> scratchReg"
> + jmpSourceOld := cogit JumpAboveOrEqual: 0.
> + "value is young and target is old.
> + Need to remember this only if the remembered bit is not already
> set.
> + Test the remembered bit. Only need to fetch the byte containing
> it,
> + which reduces the size of the mask constant."
> + rememberedBitByteOffset := jmpSourceOld isBigEndian
> +
> ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory
> rememberedBitShift // 8)]
> +
> ifFalse:[objectMemory rememberedBitShift // 8].
> + mask := 1 << (objectMemory rememberedBitShift \\ 8).
> + cogit MoveMb: rememberedBitByteOffset r: destReg R: scratchReg.
> + cogit AndCq: mask R: scratchReg.
> + jmpAlreadyRemembered := cogit JumpNonZero: 0.
> + "We know scratchReg now holds 0, this is convenient because the
> trampoline
> + convention expects 0 for store check in scratchReg. What a
> coincidence ;-)"
> + "Remembered bit is not set. Call store check to insert dest into
> remembered table."
> + trampJump := cogit Jump: 0.
> + "Here we reach the trampoline for Immutability failure"
> + immutableJump jmpTarget: (cogit MoveCq: index + 1 R: scratchReg).
> "index + 1 as 0 is reserved for store checks"
> + trampJump jmpTarget: (cogit CallRT: ceStoreTrampoline).
> + cogit annotateBytecode: cogit Label.
> + needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].
> +
> + jmpImmediate jmpTarget:
> + (jmpDestYoung jmpTarget:
> + (jmpSourceOld jmpTarget:
> + (jmpAlreadyRemembered jmpTarget:
> + cogit Label))).
> +
> + ^ 0!
>
> Item was added:
> + ----- Method:
> CogObjectRepresentationForSpur>>genStoreWithImmutabilityButNoStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr:
> (in category 'compile abstract instructions') -----
> + genStoreWithImmutabilityButNoStoreCheckSourceReg: sourceReg slotIndex:
> index destReg: destReg scratchReg: scratchReg needRestoreRcvr:
> needRestoreRcvr
> +
> + <var: #immutableJump type: #'AbstractInstruction *'>
> + <var: #immutabilityFailure type: #'AbstractInstruction *'>
> + | immutabilityFailure mutableJump |
> +
> + "imm check has its own trampoline"
> + mutableJump := self genJumpMutable: destReg scratchReg: scratchReg.
> + cogit MoveCq: index + 1 R: TempReg. "index + 1 as 0 is reserved
> for store checks"
> + cogit CallRT: ceStoreTrampoline.
> + cogit annotateBytecode: cogit Label.
> + needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].
> + immutabilityFailure := cogit Jump: 0.
> + mutableJump jmpTarget: cogit Label.
> +
> + cogit genTraceStores.
> +
> + "do the store"
> + cogit MoveR: sourceReg
> + Mw: index * objectMemory wordSize + objectMemory
> baseHeaderSize
> + r: destReg.
> +
> + immutabilityFailure jmpTarget: cogit Label.
> +
> + ^ 0!
>
> Item was added:
> + ----- Method:
> CogObjectRepresentationForSpur>>genStoreWithImmutabilityCheckSourceReg:slotIndex:destReg:scratchReg:needsStoreCheck:needRestoreRcvr:
> (in category 'compile abstract instructions') -----
> + genStoreWithImmutabilityCheckSourceReg: sourceReg slotIndex: index
> destReg: destReg scratchReg: scratchReg needsStoreCheck: needsStoreCheck
> needRestoreRcvr: needRestoreRcvr
> + "We know there is a frame as immutability check requires a frame"
> + "needRestoreRcvr has to be true to keep RcvrResultReg live with
> the receiver in it across the trampoline"
> +
> + "Trampoline convention..."
> + self assert: destReg == ReceiverResultReg.
> + self assert: scratchReg == TempReg.
> + self assert: sourceReg == ClassReg.
> +
> + needsStoreCheck
> + ifTrue:
> + [ self
> +
> genStoreWithImmutabilityAndStoreCheckSourceReg: sourceReg
> + slotIndex: index
> + destReg: destReg
> + scratchReg: scratchReg
> + needRestoreRcvr: needRestoreRcvr ]
> + ifFalse:
> + [ self
> +
> genStoreWithImmutabilityButNoStoreCheckSourceReg: sourceReg
> + slotIndex: index
> + destReg: destReg
> + scratchReg: scratchReg
> + needRestoreRcvr: needRestoreRcvr ].
> + ^ 0!
>
> Item was changed:
> ----- Method:
> CogObjectRepresentationForSpur>>generateObjectRepresentationTrampolines (in
> category 'initialization') -----
> generateObjectRepresentationTrampolines
> "Do the store check. Answer the argument for the benefit of the
> code generator;
> ReceiverResultReg may be caller-saved and hence smashed by this
> call. Answering
> it allows the code generator to reload ReceiverResultReg cheaply.
> In Spur the only thing we leave to the run-time is adding the
> receiver to the
> remembered set and setting its isRemembered bit."
> self
> cppIf: IMMUTABILITY
> + ifTrue: [ceStoreTrampoline := self
> genStoreTrampolineCalled: 'ceStoreTrampoline'].
> - ifTrue: "c.f.
> genImmutableCheck:slotIndex:sourceReg:scratchReg:popBoolean:needRestoreRcvr:"
> - [ceCannotAssignToWithIndexTrampoline := cogit
> -
> genTrampolineFor:
> #ceCannotAssignTo:withIndex:valueToAssign:
> -
> called:
> 'ceCannotAssignToWithIndexTrampoline'
> -
> arg: ReceiverResultReg
> -
> arg: TempReg
> -
> arg: ClassReg].
> ceStoreCheckTrampoline := cogit
>
> genTrampolineFor: #remember:
>
> called: 'ceStoreCheckTrampoline'
>
> arg: ReceiverResultReg
>
> regsToSave: (cogit callerSavedRegMask bitClear: (cogit registerMaskFor:
> ReceiverResultReg))
>
> result: cogit returnRegForStoreCheck.
> ceStoreCheckContextReceiverTrampoline := self
> genStoreCheckContextReceiverTrampoline.
> ceScheduleScavengeTrampoline := cogit
>
> genTrampolineFor: #ceScheduleScavenge
>
> called: 'ceScheduleScavengeTrampoline'
>
> regsToSave: cogit callerSavedRegMask.
> ceSmallActiveContextInMethodTrampoline := self
> genActiveContextTrampolineLarge: false inBlock: false called:
> 'ceSmallMethodContext'.
> ceSmallActiveContextInBlockTrampoline := self
> genActiveContextTrampolineLarge: false inBlock: true called:
> 'ceSmallBlockContext'.
> ceLargeActiveContextInMethodTrampoline := self
> genActiveContextTrampolineLarge: true inBlock: false called:
> 'ceLargeMethodContext'.
> ceLargeActiveContextInBlockTrampoline := self
> genActiveContextTrampolineLarge: true inBlock: true called:
> 'ceLargeBlockContext'!
>
> Item was changed:
> ----- Method:
> CogObjectRepresentationForSqueakV3>>genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck:
> (in category 'compile abstract instructions') -----
> genStoreSourceReg: sourceReg slotIndex: index destReg: destReg
> scratchReg: scratchReg inFrame: inFrame needsStoreCheck: needsStoreCheck
> | jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRoot mask
> rootBitByteOffset |
> <var: #jmpImmediate type: #'AbstractInstruction *'>
> <var: #jmpDestYoung type: #'AbstractInstruction *'>
> <var: #jmpSourceOld type: #'AbstractInstruction *'>
> <var: #jmpAlreadyRoot type: #'AbstractInstruction *'>
> +
> + cogit genTraceStores.
> "do the store"
> cogit MoveR: sourceReg Mw: index * objectMemory wordSize +
> objectMemory baseHeaderSize r: destReg.
> "if no need for the store check then returns"
> needsStoreCheck ifFalse: [ ^ 0 ].
> "now the check. Is value stored an integer? If so we're done"
> jmpImmediate := self genJumpImmediate: sourceReg.
> "Get the old/new boundary in scratchReg"
> cogit MoveAw: objectMemory youngStartAddress R: scratchReg.
> "Is target young? If so we're done"
> cogit CmpR: scratchReg R: destReg. "N.B. FLAGS := destReg -
> scratchReg"
> jmpDestYoung := cogit JumpAboveOrEqual: 0.
> "Is value stored old? If so we're done."
> cogit CmpR: scratchReg R: sourceReg. "N.B. FLAGS := sourceReg -
> scratchReg"
> jmpSourceOld := cogit JumpBelow: 0.
> "value is young and target is old.
> Need to make this a root if the root bit is not already set.
> Test the root bit. Only need to fetch the byte containing it,
> which reduces the size of the mask constant."
> rootBitByteOffset := jmpSourceOld isBigEndian
> ifTrue:
> [objectMemory wordSize - RootBitDigitLength]
>
> ifFalse:[RootBitDigitLength - 1].
> mask := RootBitDigitLength > 1
> ifTrue: [RootBit >> (RootBitDigitLength -
> 1 * 8)]
> ifFalse: [RootBit].
> cogit MoveMb: rootBitByteOffset r: destReg R: scratchReg.
> cogit AndCq: mask R: scratchReg.
> jmpAlreadyRoot := cogit JumpNonZero: 0.
> "Root bit is not set. Call store check to insert dest into root
> table."
> self assert: destReg == ReceiverResultReg.
> cogit
> evaluateTrampolineCallBlock: [cogit CallRT:
> ceStoreCheckTrampoline]
> protectLinkRegIfNot: inFrame.
> jmpImmediate jmpTarget:
> (jmpDestYoung jmpTarget:
> (jmpSourceOld jmpTarget:
> (jmpAlreadyRoot jmpTarget:
> cogit Label))).
> ^0!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genStorePop:LiteralVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean LiteralVariable: litVarIndex
> <inline: false>
> + | association |
> - | association immutabilityFailure |
> - <var: #immutabilityFailure type: #'AbstractInstruction *'>
> "The only reason we assert needsFrame here is that in a frameless
> method
> ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> trampoline expects the target of the store to be in
> ReceiverResultReg. So
> in a frameless method we would have a conflict between the
> receiver and
> the literal store, unless we we smart enough to realise that
> ReceiverResultReg
> was unused after the literal variable store, unlikely given that
> methods
> return self by default."
> self assert: needsFrame.
> association := self getLiteral: litVarIndex.
> self genMoveConstant: association R: ReceiverResultReg.
> objectRepresentation
> genEnsureObjInRegNotForwarded: ReceiverResultReg
> scratchReg: TempReg.
> popBoolean
> ifTrue: [self PopR: ClassReg]
> ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
> + self
> + genStoreSourceReg: ClassReg
> + slotIndex: ValueIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> - traceStores > 0 ifTrue:
> - [self CallRT: ceTraceStoreTrampoline].
> - self cppIf: IMMUTABILITY ifTrue:
> - [immutabilityFailure := objectRepresentation
> -
> genImmutableCheck: ReceiverResultReg
> -
> slotIndex: ValueIndex
> -
> sourceReg: ClassReg
> -
> scratchReg: TempReg
> -
> needRestoreRcvr: true].
> - objectRepresentation
> - genStoreSourceReg: ClassReg
> - slotIndex: ValueIndex
> - destReg: ReceiverResultReg
> - scratchReg: TempReg
> inFrame: needsFrame.
> -
> - self cppIf: IMMUTABILITY ifTrue:
> - [immutabilityFailure jmpTarget: self Label].
> -
> ^0!
>
> Item was changed:
> ----- Method:
> SimpleStackBasedCogit>>genStorePop:MaybeContextReceiverVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
> <inline: false>
> + | jmpSingle jmpDone |
> - | jmpSingle jmpDone immutabilityFailure |
> - <var: #immutabilityFailure type: #'AbstractInstruction *'>
> <var: #jmpSingle type: #'AbstractInstruction *'>
> <var: #jmpDone type: #'AbstractInstruction *'>
> "The reason we need a frame here is that assigning to an inst var
> of a context may
> involve wholesale reorganization of stack pages, and the only way
> to preserve the
> execution state of an activation in that case is if it has a
> frame."
> self assert: needsFrame.
> self putSelfInReceiverResultReg.
> objectRepresentation
> genLoadSlot: SenderIndex
> sourceReg: ReceiverResultReg
> destReg: TempReg.
> self MoveMw: 0 r: SPReg R: ClassReg.
> jmpSingle := objectRepresentation
> genJumpNotSmallIntegerInScratchReg: TempReg.
> self MoveCq: slotIndex R: SendNumArgsReg.
> self CallRT: ceStoreContextInstVarTrampoline.
> jmpDone := self Jump: 0.
> jmpSingle jmpTarget: self Label.
> - traceStores > 0 ifTrue:
> - [self CallRT: ceTraceStoreTrampoline].
> - self cppIf: IMMUTABILITY ifTrue:
> - [immutabilityFailure := objectRepresentation
> -
> genImmutableCheck: ReceiverResultReg
> -
> slotIndex: slotIndex
> -
> sourceReg: ClassReg
> -
> scratchReg: TempReg
> -
> needRestoreRcvr: true].
> - objectRepresentation
> - genStoreSourceReg: ClassReg
> - slotIndex: slotIndex
> - destReg: ReceiverResultReg
> - scratchReg: TempReg
> - inFrame: true.
> - jmpDone jmpTarget: self Label.
> popBoolean ifTrue:
> [self AddCq: objectMemory wordSize R: SPReg].
> + self
> + genStoreSourceReg: ClassReg
> + slotIndex: slotIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + inFrame: needsFrame.
> + jmpDone jmpTarget: self Label.
> - self cppIf: IMMUTABILITY ifTrue:
> - [immutabilityFailure jmpTarget: self Label].
> ^0!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genStorePop:ReceiverVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean ReceiverVariable: slotIndex
> <inline: false>
> - | immutabilityFailure |
> - <var: #immutabilityFailure type: #'AbstractInstruction *'>
> needsFrame ifTrue:
> [self putSelfInReceiverResultReg].
> popBoolean
> ifTrue: [self PopR: ClassReg]
> ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
> + self
> + genStoreSourceReg: ClassReg
> + slotIndex: slotIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> - traceStores > 0 ifTrue:
> - [self CallRT: ceTraceStoreTrampoline].
> - self cppIf: IMMUTABILITY ifTrue:
> - [immutabilityFailure := objectRepresentation
> -
> genImmutableCheck: ReceiverResultReg
> -
> slotIndex: slotIndex
> -
> sourceReg: ClassReg
> -
> scratchReg: TempReg
> -
> needRestoreRcvr: true].
> - objectRepresentation
> - genStoreSourceReg: ClassReg
> - slotIndex: slotIndex
> - destReg: ReceiverResultReg
> - scratchReg: TempReg
> inFrame: needsFrame.
> -
> - self cppIf: IMMUTABILITY ifTrue:
> - [immutabilityFailure jmpTarget: self Label].
> -
> ^0!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genStorePop:RemoteTemp:At: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
> <inline: false>
> "The only reason we assert needsFrame here is that in a frameless
> method
> ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> trampoline expects the target of the store to be in
> ReceiverResultReg. So
> in a frameless method we would have a conflict between the
> receiver and
> the temote temp store, unless we we smart enough to realise that
> ReceiverResultReg was unused after the literal variable store,
> unlikely given
> that methods return self by default."
> self assert: needsFrame.
> popBoolean
> ifTrue: [self PopR: ClassReg]
> ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
> self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r:
> FPReg R: ReceiverResultReg.
> - traceStores > 0 ifTrue:
> - [self CallRT: ceTraceStoreTrampoline].
> ^objectRepresentation
> genStoreSourceReg: ClassReg
> slotIndex: slotIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: needsFrame!
>
> Item was added:
> + ----- Method: SimpleStackBasedCogit>>genTraceStores (in category
> 'bytecode generator support') -----
> + genTraceStores
> + <inline: true>
> + traceStores > 0 ifTrue: [ self CallRT: ceTraceStoreTrampoline ].!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:LiteralVariable:
> (in category 'bytecode generator support') -----
> + genImmutabilityCheckStorePop: popBoolean LiteralVariable: litVarIndex
> + <inline: true>
> + | association needStoreCheck |
> + "The only reason we assert needsFrame here is that in a frameless
> method
> + ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> + trampoline expects the target of the store to be in
> ReceiverResultReg. So
> + in a frameless method we would have a conflict between the
> receiver and
> + the literal store, unless we we smart enough to realise that
> ReceiverResultReg
> + was unused after the literal variable store, unlikely given that
> methods
> + return self by default."
> + self assert: needsFrame.
> + "N.B. No need to check the stack for references because we
> generate code for
> + literal variable loads that stores the result in a register,
> deferring only the register push."
> + needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> + association := self getLiteral: litVarIndex.
> + optStatus isReceiverResultRegLive: false.
> + self ssAllocateRequiredReg: ReceiverResultReg. "for store
> trampoline call in genStoreSourceReg: has to be ReceiverResultReg"
> + self genMoveConstant: association R: ReceiverResultReg.
> + objectRepresentation genEnsureObjInRegNotForwarded:
> ReceiverResultReg scratchReg: TempReg.
> + self ssAllocateRequiredReg: ClassReg.
> + self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
> + self ssFlushTo: simStackPtr.
> + objectRepresentation
> + genStoreWithImmutabilityCheckSourceReg: ClassReg
> + slotIndex: ValueIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + needsStoreCheck: needStoreCheck
> + needRestoreRcvr: false.
> + ^ 0!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:MaybeContextReceiverVariable:
> (in category 'bytecode generator support') -----
> + genImmutabilityCheckStorePop: popBoolean MaybeContextReceiverVariable:
> slotIndex
> + <inline: true>
> + | jmpSingle jmpDone needStoreCheck |
> + <var: #jmpSingle type: #'AbstractInstruction *'>
> + <var: #jmpDone type: #'AbstractInstruction *'>
> + "The reason we need a frame here is that assigning to an inst var
> of a context may
> + involve wholesale reorganization of stack pages, and the only way
> to preserve the
> + execution state of an activation in that case is if it has a
> frame."
> + self assert: needsFrame.
> + needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> + "Note that ReceiverResultReg remains live after both
> + ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
> + self ensureReceiverResultRegContainsSelf.
> + self ssPop: 1.
> + self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for
> ceStoreContextInstVarTrampoline"
> + self ssPush: 1.
> + objectRepresentation
> + genLoadSlot: SenderIndex
> + sourceReg: ReceiverResultReg
> + destReg: TempReg.
> + self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
> + "stack is flushed except maybe ssTop if popBoolean is false.
> + ssTop is a SSregister in this case due to #ssStoreAndReplacePop:
> + to avoid a second indirect read / annotation in case of
> SSConstant
> + or SSBaseRegister"
> + self ssFlushTo: simStackPtr.
> + jmpSingle := objectRepresentation
> genJumpNotSmallIntegerInScratchReg: TempReg.
> + self MoveCq: slotIndex R: SendNumArgsReg.
> + self CallRT: ceStoreContextInstVarTrampoline.
> + jmpDone := self Jump: 0.
> + jmpSingle jmpTarget: self Label.
> + objectRepresentation
> + genStoreWithImmutabilityCheckSourceReg: ClassReg
> + slotIndex: slotIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + needsStoreCheck: needStoreCheck
> + needRestoreRcvr: true.
> + jmpDone jmpTarget: self Label.
> + ^0!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:ReceiverVariable:
> (in category 'bytecode generator support') -----
> + genImmutabilityCheckStorePop: popBoolean ReceiverVariable: slotIndex
> + <inline: true>
> + | needStoreCheck |
> + self assert: needsFrame.
> + needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> + "Note that ReceiverResultReg remains live after the trampoline."
> + self ensureReceiverResultRegContainsSelf.
> + self ssAllocateRequiredReg: ClassReg.
> + self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
> + self ssFlushTo: simStackPtr.
> + objectRepresentation
> + genStoreWithImmutabilityCheckSourceReg: ClassReg
> + slotIndex: slotIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + needsStoreCheck: needStoreCheck
> + needRestoreRcvr: true.
> +
> + ^ 0!
>
> Item was changed:
> ----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable:
> (in category 'bytecode generator support') -----
> genStorePop: popBoolean LiteralVariable: litVarIndex
> <inline: false>
> - | topReg association needStoreCheck immutabilityFailure |
> - "The only reason we assert needsFrame here is that in a frameless
> method
> - ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> - trampoline expects the target of the store to be in
> ReceiverResultReg. So
> - in a frameless method we would have a conflict between the
> receiver and
> - the literal store, unless we we smart enough to realise that
> ReceiverResultReg
> - was unused after the literal variable store, unlikely given that
> methods
> - return self by default."
> - self assert: needsFrame.
> - self cppIf: IMMUTABILITY ifTrue: [ self ssFlushTo: simStackPtr - 1
> ].
> - "N.B. No need to check the stack for references because we
> generate code for
> - literal variable loads that stores the result in a register,
> deferring only the register push."
> - needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> - association := self getLiteral: litVarIndex.
> - optStatus isReceiverResultRegLive: false.
> - self ssAllocateRequiredReg: ReceiverResultReg. "for ceStoreCheck
> call in genStoreSourceReg: has to be ReceiverResultReg"
> - self genMoveConstant: association R: ReceiverResultReg.
> - objectRepresentation genEnsureObjInRegNotForwarded:
> ReceiverResultReg scratchReg: TempReg.
> self
> cppIf: IMMUTABILITY
> + ifTrue: [ ^ self genImmutabilityCheckStorePop: popBoolean
> LiteralVariable: litVarIndex ]
> + ifFalse: [ ^ self genVanillaStorePop: popBoolean
> LiteralVariable: litVarIndex ]
> + !
> - ifTrue:
> - [ self ssAllocateRequiredReg: ClassReg.
> - topReg := ClassReg.
> - self ssStoreAndReplacePop: popBoolean toReg:
> ClassReg.
> - "stack is flushed except maybe ssTop if
> popBoolean is false.
> - ssTop is a SSregister in this case due to
> #ssStoreAndReplacePop:
> - to avoid a second indirect read / annotation in
> case of SSConstant
> - or SSBaseRegister"
> - self ssFlushTo: simStackPtr.
> - immutabilityFailure := objectRepresentation
> -
> genImmutableCheck: ReceiverResultReg
> -
> slotIndex: ValueIndex
> -
> sourceReg: ClassReg
> -
> scratchReg: TempReg
> -
> needRestoreRcvr: false ]
> - ifFalse:
> - [ topReg := self allocateRegForStackEntryAt: 0
> notConflictingWith: (self registerMaskFor: ReceiverResultReg).
> - self ssStorePop: popBoolean toReg: topReg ].
> - traceStores > 0 ifTrue:
> - [self MoveR: topReg R: TempReg.
> - self CallRT: ceTraceStoreTrampoline].
> - objectRepresentation
> - genStoreSourceReg: topReg
> - slotIndex: ValueIndex
> - destReg: ReceiverResultReg
> - scratchReg: TempReg
> - inFrame: needsFrame
> - needsStoreCheck: needStoreCheck.
> - self cppIf: IMMUTABILITY ifTrue: [ immutabilityFailure jmpTarget:
> self Label ].
> - ^ 0!
>
> Item was changed:
> ----- Method:
> StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
> <inline: false>
> - | jmpSingle jmpDone needStoreCheck immutabilityFailure |
> - <var: #jmpSingle type: #'AbstractInstruction *'>
> - <var: #jmpDone type: #'AbstractInstruction *'>
> - "The reason we need a frame here is that assigning to an inst var
> of a context may
> - involve wholesale reorganization of stack pages, and the only way
> to preserve the
> - execution state of an activation in that case is if it has a
> frame."
> - self assert: needsFrame.
> - self cppIf: IMMUTABILITY ifTrue: [ self ssFlushTo: simStackPtr - 1
> ].
> - self ssFlushUpThroughReceiverVariable: slotIndex.
> - needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> - "Note that ReceiverResultReg remains live after both
> - ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
> - self ensureReceiverResultRegContainsSelf.
> - self ssPop: 1.
> - self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for
> ceStoreContextInstVarTrampoline"
> - self ssPush: 1.
> - objectRepresentation
> - genLoadSlot: SenderIndex
> - sourceReg: ReceiverResultReg
> - destReg: TempReg.
> self
> cppIf: IMMUTABILITY
> + ifTrue: [ ^ self genImmutabilityCheckStorePop: popBoolean
> MaybeContextReceiverVariable: slotIndex ]
> + ifFalse: [ ^ self genVanillaStorePop: popBoolean
> MaybeContextReceiverVariable: slotIndex ]!
> - ifTrue:
> - [ self ssStoreAndReplacePop: popBoolean toReg:
> ClassReg.
> - "stack is flushed except maybe ssTop if
> popBoolean is false.
> - ssTop is a SSregister in this case due to
> #ssStoreAndReplacePop:
> - to avoid a second indirect read / annotation in
> case of SSConstant
> - or SSBaseRegister"
> - self ssFlushTo: simStackPtr. ]
> - ifFalse: [ self ssStorePop: popBoolean toReg: ClassReg ].
> - jmpSingle := objectRepresentation
> genJumpNotSmallIntegerInScratchReg: TempReg.
> - self MoveCq: slotIndex R: SendNumArgsReg.
> - self CallRT: ceStoreContextInstVarTrampoline.
> - jmpDone := self Jump: 0.
> - jmpSingle jmpTarget: self Label.
> - traceStores > 0 ifTrue:
> - [self MoveR: ClassReg R: TempReg.
> - self CallRT: ceTraceStoreTrampoline].
> - self
> - cppIf: IMMUTABILITY
> - ifTrue:
> - [ immutabilityFailure := objectRepresentation
> -
> genImmutableCheck: ReceiverResultReg
> -
> slotIndex: ValueIndex
> -
> sourceReg: ClassReg
> -
> scratchReg: TempReg
> -
> needRestoreRcvr: true ].
> - objectRepresentation
> - genStoreSourceReg: ClassReg
> - slotIndex: slotIndex
> - destReg: ReceiverResultReg
> - scratchReg: TempReg
> - inFrame: true
> - needsStoreCheck: needStoreCheck.
> - jmpDone jmpTarget: self Label.
> - self cppIf: IMMUTABILITY ifTrue: [ immutabilityFailure jmpTarget:
> self Label ].
> - ^0!
>
> Item was changed:
> ----- Method: StackToRegisterMappingCogit>>genStorePop:ReceiverVariable:
> (in category 'bytecode generator support') -----
> genStorePop: popBoolean ReceiverVariable: slotIndex
> <inline: false>
> - | topReg needStoreCheck immutabilityFailure |
> - self cppIf: IMMUTABILITY ifTrue: [ self assert: needsFrame. self
> ssFlushTo: simStackPtr - 1 ].
> - self ssFlushUpThroughReceiverVariable: slotIndex.
> - needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> - "Note that ReceiverResultReg remains live after
> ceStoreCheckTrampoline."
> - self ensureReceiverResultRegContainsSelf.
> self
> cppIf: IMMUTABILITY
> + ifTrue: [ ^ self genImmutabilityCheckStorePop: popBoolean
> ReceiverVariable: slotIndex ]
> + ifFalse: [ ^ self genVanillaStorePop: popBoolean
> ReceiverVariable: slotIndex ]
> + !
> - ifTrue:
> - [ self ssAllocateRequiredReg: ClassReg.
> - topReg := ClassReg.
> - self ssStoreAndReplacePop: popBoolean toReg:
> ClassReg.
> - "stack is flushed except maybe ssTop if
> popBoolean is false.
> - ssTop is a SSregister in this case due to
> #ssStoreAndReplacePop:
> - to avoid a second indirect read / annotation in
> case of SSConstant
> - or SSBaseRegister"
> - self ssFlushTo: simStackPtr.
> - immutabilityFailure := objectRepresentation
> -
> genImmutableCheck: ReceiverResultReg
> -
> slotIndex: slotIndex
> -
> sourceReg: ClassReg
> -
> scratchReg: TempReg
> -
> needRestoreRcvr: true ]
> - ifFalse:
> - [ topReg := self allocateRegForStackEntryAt: 0
> notConflictingWith: (self registerMaskFor: ReceiverResultReg).
> - self ssStorePop: popBoolean toReg: topReg ].
> - traceStores > 0 ifTrue:
> - [ self MoveR: topReg R: TempReg.
> - self evaluateTrampolineCallBlock: [ self CallRT:
> ceTraceStoreTrampoline ] protectLinkRegIfNot: needsFrame ].
> - objectRepresentation
> - genStoreSourceReg: topReg
> - slotIndex: slotIndex
> - destReg: ReceiverResultReg
> - scratchReg: TempReg
> - inFrame: needsFrame
> - needsStoreCheck: needStoreCheck.
> - self cppIf: IMMUTABILITY ifTrue: [ immutabilityFailure jmpTarget:
> self Label ].
> - ^ 0!
>
> Item was changed:
> ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At:
> (in category 'bytecode generator support') -----
> genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
> <inline: false>
> | topReg needStoreCheck |
> "The only reason we assert needsFrame here is that in a frameless
> method
> ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> trampoline expects the target of the store to be in
> ReceiverResultReg. So
> in a frameless method we would have a conflict between the
> receiver and
> the temote temp store, unless we we smart enough to realise that
> ReceiverResultReg was unused after the literal variable store,
> unlikely given
> that methods return self by default."
> self assert: needsFrame.
> "N.B. No need to check the stack for references because we
> generate code for
> remote temp loads that stores the result in a register, deferring
> only the register push."
> needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> topReg := self allocateRegForStackEntryAt: 0 notConflictingWith:
> (self registerMaskFor: ReceiverResultReg).
> self ssAllocateRequiredReg: ReceiverResultReg.
> optStatus isReceiverResultRegLive: false.
> self ssStoreAndReplacePop: popBoolean toReg: topReg.
> self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r:
> FPReg R: ReceiverResultReg.
> - traceStores > 0 ifTrue:
> - [ self MoveR: topReg R: TempReg.
> - self CallRT: ceTraceStoreTrampoline. ].
> ^objectRepresentation
> genStoreSourceReg: topReg
> slotIndex: slotIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: needsFrame
> needsStoreCheck: needStoreCheck!
>
> Item was added:
> + ----- Method: StackToRegisterMappingCogit>>genTraceStores (in category
> 'bytecode generator support') -----
> + genTraceStores
> + <inline: true>
> + traceStores > 0 ifTrue:
> + [ self MoveR: ClassReg R: TempReg.
> + self CallRT: ceTraceStoreTrampoline ].!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genVanillaStorePop:LiteralVariable: (in
> category 'bytecode generator support') -----
> + genVanillaStorePop: popBoolean LiteralVariable: litVarIndex
> + <inline: true>
> + | topReg association needStoreCheck |
> + "The only reason we assert needsFrame here is that in a frameless
> method
> + ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> + trampoline expects the target of the store to be in
> ReceiverResultReg. So
> + in a frameless method we would have a conflict between the
> receiver and
> + the literal store, unless we we smart enough to realise that
> ReceiverResultReg
> + was unused after the literal variable store, unlikely given that
> methods
> + return self by default."
> + self assert: needsFrame.
> + "N.B. No need to check the stack for references because we
> generate code for
> + literal variable loads that stores the result in a register,
> deferring only the register push."
> + needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> + association := self getLiteral: litVarIndex.
> + optStatus isReceiverResultRegLive: false.
> + self ssAllocateRequiredReg: ReceiverResultReg. "for ceStoreCheck
> call in genStoreSourceReg: has to be ReceiverResultReg"
> + self genMoveConstant: association R: ReceiverResultReg.
> + objectRepresentation genEnsureObjInRegNotForwarded:
> ReceiverResultReg scratchReg: TempReg.
> + topReg := self allocateRegForStackEntryAt: 0 notConflictingWith:
> (self registerMaskFor: ReceiverResultReg).
> + self ssStorePop: popBoolean toReg: topReg.
> + objectRepresentation
> + genStoreSourceReg: topReg
> + slotIndex: ValueIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + inFrame: needsFrame
> + needsStoreCheck: needStoreCheck.
> + ^ 0!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genVanillaStorePop:MaybeContextReceiverVariable:
> (in category 'bytecode generator support') -----
> + genVanillaStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
> + <inline: true>
> + | jmpSingle jmpDone needStoreCheck |
> + <var: #jmpSingle type: #'AbstractInstruction *'>
> + <var: #jmpDone type: #'AbstractInstruction *'>
> + "The reason we need a frame here is that assigning to an inst var
> of a context may
> + involve wholesale reorganization of stack pages, and the only way
> to preserve the
> + execution state of an activation in that case is if it has a
> frame."
> + self assert: needsFrame.
> + self ssFlushUpThroughReceiverVariable: slotIndex.
> + needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> + "Note that ReceiverResultReg remains live after both
> + ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
> + self ensureReceiverResultRegContainsSelf.
> + self ssPop: 1.
> + self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for
> ceStoreContextInstVarTrampoline"
> + self ssPush: 1.
> + objectRepresentation
> + genLoadSlot: SenderIndex
> + sourceReg: ReceiverResultReg
> + destReg: TempReg.
> + self ssStorePop: popBoolean toReg: ClassReg.
> + jmpSingle := objectRepresentation
> genJumpNotSmallIntegerInScratchReg: TempReg.
> + self MoveCq: slotIndex R: SendNumArgsReg.
> + self CallRT: ceStoreContextInstVarTrampoline.
> + jmpDone := self Jump: 0.
> + jmpSingle jmpTarget: self Label.
> + objectRepresentation
> + genStoreSourceReg: ClassReg
> + slotIndex: slotIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + inFrame: true
> + needsStoreCheck: needStoreCheck.
> + jmpDone jmpTarget: self Label.
> +
> + ^0!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genVanillaStorePop:ReceiverVariable: (in
> category 'bytecode generator support') -----
> + genVanillaStorePop: popBoolean ReceiverVariable: slotIndex
> + <inline: true>
> + | topReg needStoreCheck |
> + self ssFlushUpThroughReceiverVariable: slotIndex.
> + needStoreCheck := (objectRepresentation isUnannotatableConstant:
> self ssTop) not.
> + "Note that ReceiverResultReg remains live after
> ceStoreCheckTrampoline."
> + self ensureReceiverResultRegContainsSelf.
> + topReg := self allocateRegForStackEntryAt: 0 notConflictingWith:
> (self registerMaskFor: ReceiverResultReg).
> + self ssStorePop: popBoolean toReg: topReg.
> + objectRepresentation
> + genStoreSourceReg: topReg
> + slotIndex: slotIndex
> + destReg: ReceiverResultReg
> + scratchReg: TempReg
> + inFrame: needsFrame
> + needsStoreCheck: needStoreCheck.
> + ^ 0!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160330/d9b2731e/attachment-0001.htm
More information about the Vm-dev
mailing list