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

Clément Bera bera.clement at gmail.com
Thu Apr 23 19:04:53 UTC 2015


About
*The only reason we assert needsFrame here is that in a frameless
method ReceiverResultReg must and does contain only self*

What if in frameless method we swap temporarily the ReceiverResultReg ?

I mean a work around like that for frameless methods :

SimpleStackBasedCogit >>genStorePop: popBoolean RemoteTemp: slotIndex At:
remoteTempIndex

*| tempReg |*
*needsFrame ifFalse: *
*    [ **tempReg** := self allocateRegNotConflictingWith: (self
registerMaskFor: ClassReg and: ReceiverResultReg).*
*self MoveR: ReceiverResultReg R: tempReg ].*
 popBoolean
                ifTrue: [self PopR: ClassReg]
                ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
        self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r:
FPReg R: ReceiverResultReg.
        objectRepresentation
                genStoreSourceReg: ClassReg
                slotIndex: slotIndex
                destReg: ReceiverResultReg
                scratchReg: TempReg
                inFrame: needsFrame.
*needsFrame ifFalse: *
*    [ **self MoveR: **tempReg** R:** ReceiverResultReg ].*

That's two extra instructions but compared to a stack frame creation it may
make sense.

Anyway it does not really matter I guess there are few frameless methods on
the SistaCogit.



2015-04-23 20:08 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-eem.1249.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-eem.1249
> Author: eem
> Time: 23 April 2015, 11:07:28.905 am
> UUID: 41e8dbc2-ed01-42d2-9155-eaf604510aaa
> Ancestors: VMMaker.oscog-eem.1248
>
> More commentary.
>
> =============== Diff against VMMaker.oscog-eem.1248 ===============
>
> Item was changed:
>   ----- Method: SimpleStackBasedCogit>>genStorePop:LiteralVariable: (in
> category 'bytecode generator support') -----
>   genStorePop: popBoolean LiteralVariable: litVarIndex
>         <inline: false>
>         | association |
> +       "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 annotate: (self MoveCw: association R: ReceiverResultReg)
> objRef: association.
>         objectRepresentation
>                 genEnsureObjInRegNotForwarded: ReceiverResultReg
>                 scratchReg: TempReg.
>         popBoolean
>                 ifTrue: [self PopR: ClassReg]
>                 ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
>         traceStores > 0 ifTrue:
>                 [self CallRT: ceTraceStoreTrampoline].
>         ^objectRepresentation
>                 genStoreSourceReg: ClassReg
>                 slotIndex: ValueIndex
>                 destReg: ReceiverResultReg
>                 scratchReg: TempReg
>                 inFrame: needsFrame!
>
> Item was changed:
>   ----- Method:
> SimpleStackBasedCogit>>genStorePop:MaybeContextReceiverVariable: (in
> category 'bytecode generator support') -----
>   genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
>         <inline: false>
>         | jmpSingle jmpDone |
>         <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 MoveMw: FoxMFReceiver r: FPReg R: ReceiverResultReg.
>         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].
>         objectRepresentation
>                 genStoreSourceReg: ClassReg
>                 slotIndex: slotIndex
>                 destReg: ReceiverResultReg
>                 scratchReg: TempReg
>                 inFrame: true.
>         jmpDone jmpTarget: self Label.
>         popBoolean ifTrue:
>                 [self AddCq: objectMemory wordSize R: SPReg].
>         ^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 changed:
>   ----- Method:
> StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in
> category 'bytecode generator support') -----
>   genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
>         <inline: false>
>         | jmpSingle jmpDone valueReg |
>         <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.
>         "Note that ReceiverResultReg remains live after both
>          ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
>         self ensureReceiverResultRegContainsSelf.
>         self ssPop: 1.
>         self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for the
> ceStoreCheck call in genStoreSourceReg:... below"
>         self ssPush: 1.
>         objectRepresentation
>                 genLoadSlot: SenderIndex
>                 sourceReg: ReceiverResultReg
>                 destReg: TempReg.
>         valueReg := self ssStorePop: popBoolean toPreferredReg: ClassReg.
>         valueReg ~= ClassReg ifTrue:
>                 [self MoveR: valueReg 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 MoveR: ClassReg R: TempReg.
>                  self CallRT: ceTraceStoreTrampoline].
>         objectRepresentation
>                 genStoreSourceReg: ClassReg
>                 slotIndex: slotIndex
>                 destReg: ReceiverResultReg
>                 scratchReg: TempReg
>                 inFrame: true.
>         jmpDone 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 topSpilled tempVectReg |
> +       "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.
>         optStatus isReceiverResultRegLive: false.
>         "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."
>         "Avoid store check for immediate values"
>         (objectRepresentation isUnannotatableConstant: self ssTop) ifTrue:
>                 [ tempVectReg := self allocateAnyReg.
>                  self MoveMw: (self frameOffsetOfTemporary:
> remoteTempIndex) r: FPReg R: tempVectReg.
>                  self ssStorePop: popBoolean toReg: TempReg.
>                  traceStores > 0 ifTrue:
>                         [ tempVectReg = ReceiverResultReg ifFalse:
>                                         [ self ssAllocateRequiredReg:
> ReceiverResultReg.
>                                         optStatus isReceiverResultRegLive:
> false.
>                                         self MoveR: tempVectReg R:
> ReceiverResultReg ].
>                         self CallRT: ceTraceStoreTrampoline].
>                  ^objectRepresentation
>                         genStoreImmediateInSourceReg: TempReg
>                         slotIndex: slotIndex
>                         destReg: tempVectReg].
>         topReg := self allocateRegForStackTopEntryNotConflictingWith:
> (self registerMaskFor: ReceiverResultReg).
>         self ssPop: 1.
>         "for the ceStoreCheck call in genStoreSourceReg:... below"
>         self ssAllocateCallReg: topReg and: ReceiverResultReg.
>         self ssPush: 1.
>         topSpilled := self ssTop spilled.
>         self ssStorePop: (popBoolean or: [topSpilled]) toReg: topReg.
>         popBoolean ifFalse:
>                 [topSpilled ifFalse: [self ssPop: 1].
>                  self ssPushRegister: 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!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150423/15ca8619/attachment-0001.htm


More information about the Vm-dev mailing list