<div dir="ltr">About <div><i><span style="font-size:12.8000001907349px">The only reason we assert needsFrame here is that in a frameless method</span><span style="font-size:12.8000001907349px"> ReceiverResultReg </span><span style="font-size:12.8000001907349px">must and does contain only self</span></i><div><br></div><div>What if in frameless method we swap temporarily the ReceiverResultReg ?</div></div><div><br></div><div>I mean a work around like that for frameless methods :</div><div> </div><div><span style="font-size:12.8000001907349px">SimpleStackBasedCogit &gt;&gt;</span><span style="font-size:12.8000001907349px">genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px"><b>| tempReg |</b></span></div><div><span style="font-size:12.8000001907349px"><b>needsFrame ifFalse: </b></span></div><div><span style="font-size:12.8000001907349px"><b>    [ </b></span><b style="font-size:12.8000001907349px">tempReg</b><b><span style="font-size:12.8000001907349px"> := self allocateRegNotConflictingWith: (self registerMaskFor: </span><span style="font-size:12.8000001907349px">ClassReg and: ReceiverResultReg).</span></b></div><div><b><span style="font-size:12.8000001907349px">self MoveR: ReceiverResultReg R: tempReg ].</span></b></div><div><span style="font-size:12.8000001907349px"> popBoolean</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                ifTrue: [self PopR: ClassReg]</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">        self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: ReceiverResultReg.</span></div><div><span style="font-size:12.8000001907349px">        objectRepresentation</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                genStoreSourceReg: ClassReg</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                slotIndex: slotIndex</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                destReg: ReceiverResultReg</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                scratchReg: TempReg</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">                inFrame: needsFrame.</span><span style="font-size:12.8000001907349px"><br></span></div><div><div><span style="font-size:12.8000001907349px"><b>needsFrame ifFalse: </b></span></div><div><span style="font-size:12.8000001907349px"><b>    [ </b></span><b><span style="font-size:12.8000001907349px">self MoveR: </span></b><b><span style="font-size:12.8000001907349px">tempReg</span></b><b><span style="font-size:12.8000001907349px"> R:</span></b><b><span style="font-size:12.8000001907349px"> ReceiverResultReg ].</span></b></div></div><div><b><span style="font-size:12.8000001907349px"><br></span></b></div><div><span style="font-size:12.8000001907349px">That&#39;s two extra instructions but compared to a stack frame creation it may make sense.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">Anyway it does not really matter I guess there are few frameless methods on the SistaCogit.</span></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-04-23 20:08 GMT+02:00  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1249.mcz" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1249.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1249<br>
Author: eem<br>
Time: 23 April 2015, 11:07:28.905 am<br>
UUID: 41e8dbc2-ed01-42d2-9155-eaf604510aaa<br>
Ancestors: VMMaker.oscog-eem.1248<br>
<br>
More commentary.<br>
<br>
=============== Diff against VMMaker.oscog-eem.1248 ===============<br>
<br>
Item was changed:<br>
  ----- Method: SimpleStackBasedCogit&gt;&gt;genStorePop:LiteralVariable: (in category &#39;bytecode generator support&#39;) -----<br>
  genStorePop: popBoolean LiteralVariable: litVarIndex<br>
        &lt;inline: false&gt;<br>
        | association |<br>
+       &quot;The only reason we assert needsFrame here is that in a frameless method<br>
+        ReceiverResultReg must and does contain only self, but the ceStoreCheck<br>
+        trampoline expects the target of the store to be in ReceiverResultReg.  So<br>
+        in a frameless method we would have a conflict between the receiver and<br>
+        the literal store, unless we we smart enough to realise that ReceiverResultReg<br>
+        was unused after the literal variable store, unlikely given that methods<br>
+        return self by default.&quot;<br>
        self assert: needsFrame.<br>
        association := self getLiteral: litVarIndex.<br>
        self annotate: (self MoveCw: association R: ReceiverResultReg) objRef: association.<br>
        objectRepresentation<br>
                genEnsureObjInRegNotForwarded: ReceiverResultReg<br>
                scratchReg: TempReg.<br>
        popBoolean<br>
                ifTrue: [self PopR: ClassReg]<br>
                ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].<br>
        traceStores &gt; 0 ifTrue:<br>
                [self CallRT: ceTraceStoreTrampoline].<br>
        ^objectRepresentation<br>
                genStoreSourceReg: ClassReg<br>
                slotIndex: ValueIndex<br>
                destReg: ReceiverResultReg<br>
                scratchReg: TempReg<br>
                inFrame: needsFrame!<br>
<br>
Item was changed:<br>
  ----- Method: SimpleStackBasedCogit&gt;&gt;genStorePop:MaybeContextReceiverVariable: (in category &#39;bytecode generator support&#39;) -----<br>
  genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex<br>
        &lt;inline: false&gt;<br>
        | jmpSingle jmpDone |<br>
        &lt;var: #jmpSingle type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpDone type: #&#39;AbstractInstruction *&#39;&gt;<br>
+       &quot;The reason we need a frame here is that assigning to an inst var of a context may<br>
+        involve wholesale reorganization of stack pages, and the only way to preserve the<br>
+        execution state of an activation in that case is if it has a frame.&quot;<br>
        self assert: needsFrame.<br>
        self MoveMw: FoxMFReceiver r: FPReg R: ReceiverResultReg.<br>
        objectRepresentation<br>
                genLoadSlot: SenderIndex<br>
                sourceReg: ReceiverResultReg<br>
                destReg: TempReg.<br>
        self MoveMw: 0 r: SPReg R: ClassReg.<br>
        jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.<br>
        self MoveCq: slotIndex R: SendNumArgsReg.<br>
        self CallRT: ceStoreContextInstVarTrampoline.<br>
        jmpDone := self Jump: 0.<br>
        jmpSingle jmpTarget: self Label.<br>
        traceStores &gt; 0 ifTrue:<br>
                [self CallRT: ceTraceStoreTrampoline].<br>
        objectRepresentation<br>
                genStoreSourceReg: ClassReg<br>
                slotIndex: slotIndex<br>
                destReg: ReceiverResultReg<br>
                scratchReg: TempReg<br>
                inFrame: true.<br>
        jmpDone jmpTarget: self Label.<br>
        popBoolean ifTrue:<br>
                [self AddCq: objectMemory wordSize R: SPReg].<br>
        ^0!<br>
<br>
Item was changed:<br>
  ----- Method: SimpleStackBasedCogit&gt;&gt;genStorePop:RemoteTemp:At: (in category &#39;bytecode generator support&#39;) -----<br>
  genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex<br>
        &lt;inline: false&gt;<br>
+       &quot;The only reason we assert needsFrame here is that in a frameless method<br>
+        ReceiverResultReg must and does contain only self, but the ceStoreCheck<br>
+        trampoline expects the target of the store to be in ReceiverResultReg.  So<br>
+        in a frameless method we would have a conflict between the receiver and<br>
+        the temote temp store, unless we we smart enough to realise that<br>
+        ReceiverResultReg was unused after the literal variable store, unlikely given<br>
+        that methods return self by default.&quot;<br>
        self assert: needsFrame.<br>
        popBoolean<br>
                ifTrue: [self PopR: ClassReg]<br>
                ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].<br>
        self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: ReceiverResultReg.<br>
        traceStores &gt; 0 ifTrue:<br>
                [self CallRT: ceTraceStoreTrampoline].<br>
        ^objectRepresentation<br>
                genStoreSourceReg: ClassReg<br>
                slotIndex: slotIndex<br>
                destReg: ReceiverResultReg<br>
                scratchReg: TempReg<br>
                inFrame: needsFrame!<br>
<br>
Item was changed:<br>
  ----- Method: StackToRegisterMappingCogit&gt;&gt;genStorePop:MaybeContextReceiverVariable: (in category &#39;bytecode generator support&#39;) -----<br>
  genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex<br>
        &lt;inline: false&gt;<br>
        | jmpSingle jmpDone valueReg |<br>
        &lt;var: #jmpSingle type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpDone type: #&#39;AbstractInstruction *&#39;&gt;<br>
+       &quot;The reason we need a frame here is that assigning to an inst var of a context may<br>
+        involve wholesale reorganization of stack pages, and the only way to preserve the<br>
+        execution state of an activation in that case is if it has a frame.&quot;<br>
        self assert: needsFrame.<br>
        self ssFlushUpThroughReceiverVariable: slotIndex.<br>
        &quot;Note that ReceiverResultReg remains live after both<br>
         ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline.&quot;<br>
        self ensureReceiverResultRegContainsSelf.<br>
        self ssPop: 1.<br>
        self ssAllocateCallReg: ClassReg and: SendNumArgsReg. &quot;for the ceStoreCheck call in genStoreSourceReg:... below&quot;<br>
        self ssPush: 1.<br>
        objectRepresentation<br>
                genLoadSlot: SenderIndex<br>
                sourceReg: ReceiverResultReg<br>
                destReg: TempReg.<br>
        valueReg := self ssStorePop: popBoolean toPreferredReg: ClassReg.<br>
        valueReg ~= ClassReg ifTrue:<br>
                [self MoveR: valueReg R: ClassReg].<br>
        jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.<br>
        self MoveCq: slotIndex R: SendNumArgsReg.<br>
        self CallRT: ceStoreContextInstVarTrampoline.<br>
        jmpDone := self Jump: 0.<br>
        jmpSingle jmpTarget: self Label.<br>
        traceStores &gt; 0 ifTrue:<br>
                [self MoveR: ClassReg R: TempReg.<br>
                 self CallRT: ceTraceStoreTrampoline].<br>
        objectRepresentation<br>
                genStoreSourceReg: ClassReg<br>
                slotIndex: slotIndex<br>
                destReg: ReceiverResultReg<br>
                scratchReg: TempReg<br>
                inFrame: true.<br>
        jmpDone jmpTarget: self Label.<br>
        ^0!<br>
<br>
Item was changed:<br>
  ----- Method: StackToRegisterMappingCogit&gt;&gt;genStorePop:RemoteTemp:At: (in category &#39;bytecode generator support&#39;) -----<br>
  genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex<br>
        &lt;inline: false&gt;<br>
        | topReg topSpilled tempVectReg |<br>
+       &quot;The only reason we assert needsFrame here is that in a frameless method<br>
+        ReceiverResultReg must and does contain only self, but the ceStoreCheck<br>
+        trampoline expects the target of the store to be in ReceiverResultReg.  So<br>
+        in a frameless method we would have a conflict between the receiver and<br>
+        the temote temp store, unless we we smart enough to realise that<br>
+        ReceiverResultReg was unused after the literal variable store, unlikely given<br>
+        that methods return self by default.&quot;<br>
        self assert: needsFrame.<br>
        optStatus isReceiverResultRegLive: false.<br>
        &quot;N.B.  No need to check the stack for references because we generate code for<br>
         remote temp loads that stores the result in a register, deferring only the register push.&quot;<br>
        &quot;Avoid store check for immediate values&quot;<br>
        (objectRepresentation isUnannotatableConstant: self ssTop) ifTrue:<br>
                [ tempVectReg := self allocateAnyReg.<br>
                 self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: tempVectReg.<br>
                 self ssStorePop: popBoolean toReg: TempReg.<br>
                 traceStores &gt; 0 ifTrue:<br>
                        [ tempVectReg = ReceiverResultReg ifFalse:<br>
                                        [ self ssAllocateRequiredReg: ReceiverResultReg.<br>
                                        optStatus isReceiverResultRegLive: false.<br>
                                        self MoveR: tempVectReg R: ReceiverResultReg ].<br>
                        self CallRT: ceTraceStoreTrampoline].<br>
                 ^objectRepresentation<br>
                        genStoreImmediateInSourceReg: TempReg<br>
                        slotIndex: slotIndex<br>
                        destReg: tempVectReg].<br>
        topReg := self allocateRegForStackTopEntryNotConflictingWith: (self registerMaskFor: ReceiverResultReg).<br>
        self ssPop: 1.<br>
        &quot;for the ceStoreCheck call in genStoreSourceReg:... below&quot;<br>
        self ssAllocateCallReg: topReg and: ReceiverResultReg.<br>
        self ssPush: 1.<br>
        topSpilled := self ssTop spilled.<br>
        self ssStorePop: (popBoolean or: [topSpilled]) toReg: topReg.<br>
        popBoolean ifFalse:<br>
                [topSpilled ifFalse: [self ssPop: 1].<br>
                 self ssPushRegister: topReg].<br>
        self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: ReceiverResultReg.<br>
         traceStores &gt; 0 ifTrue:<br>
                [self MoveR: topReg R: TempReg.<br>
                 self CallRT: ceTraceStoreTrampoline].<br>
        ^objectRepresentation<br>
                genStoreSourceReg: topReg<br>
                slotIndex: slotIndex<br>
                destReg: ReceiverResultReg<br>
                scratchReg: TempReg<br>
                inFrame: needsFrame!<br>
<br>
</blockquote></div><br></div>