<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 >></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'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"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></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>>genStorePop:LiteralVariable: (in category 'bytecode generator support') -----<br>
genStorePop: popBoolean LiteralVariable: litVarIndex<br>
<inline: false><br>
| association |<br>
+ "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."<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 > 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>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----<br>
genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex<br>
<inline: false><br>
| jmpSingle jmpDone |<br>
<var: #jmpSingle type: #'AbstractInstruction *'><br>
<var: #jmpDone type: #'AbstractInstruction *'><br>
+ "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."<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 > 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>>genStorePop:RemoteTemp:At: (in category 'bytecode generator support') -----<br>
genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex<br>
<inline: false><br>
+ "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."<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 > 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>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----<br>
genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex<br>
<inline: false><br>
| jmpSingle jmpDone valueReg |<br>
<var: #jmpSingle type: #'AbstractInstruction *'><br>
<var: #jmpDone type: #'AbstractInstruction *'><br>
+ "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."<br>
self assert: needsFrame.<br>
self ssFlushUpThroughReceiverVariable: slotIndex.<br>
"Note that ReceiverResultReg remains live after both<br>
ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."<br>
self ensureReceiverResultRegContainsSelf.<br>
self ssPop: 1.<br>
self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for the ceStoreCheck call in genStoreSourceReg:... below"<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 > 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>>genStorePop:RemoteTemp:At: (in category 'bytecode generator support') -----<br>
genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex<br>
<inline: false><br>
| topReg topSpilled tempVectReg |<br>
+ "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."<br>
self assert: needsFrame.<br>
optStatus isReceiverResultRegLive: false.<br>
"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."<br>
"Avoid store check for immediate values"<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 > 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>
"for the ceStoreCheck call in genStoreSourceReg:... below"<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 > 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>