[Vm-dev] VM Maker: VMMaker.oscog-cb.1653.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue Jan 19 12:29:17 UTC 2016
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1653.mcz
==================== Summary ====================
Name: VMMaker.oscog-cb.1653
Author: cb
Time: 19 January 2016, 1:28:02.308 pm
UUID: c46f2c10-6886-4558-9cc7-ffaae87ba44f
Ancestors: VMMaker.oscog-cb.1652
Simplified the generated code and code generating the machine code to make it easier to understand.
Still I have some bugs (but less).
=============== Diff against VMMaker.oscog-cb.1652 ===============
Item was changed:
----- Method: CogObjectRepresentationForSpur>>genImmutableCheck:slotIndex:sourceReg:scratchReg:popBoolean:needRestoreRcvr: (in category 'compile abstract instructions') -----
genImmutableCheck: regHoldingObjectMutated slotIndex: index sourceReg: regHoldingValueToStore scratchReg: scratchReg popBoolean: popBoolean 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."
- Simulated stack is flushed until simulatedStackPointer - 1, which implies full flush
- if popBoolean is true, else top value may not be flushed.
- We spill the top value (the value to store) for the trampoline if needed."
self assert: regHoldingObjectMutated == ReceiverResultReg.
self assert: scratchReg == TempReg.
self assert: regHoldingValueToStore == ClassReg.
+ mutableJump := self genJumpMutable: ReceiverResultReg scratchReg: TempReg.
- mutableJump := self genJumpMutable: ClassReg scratchReg: TempReg.
"We reach this code if the object mutated is immutable."
- "simulatedStack state altered for the trampoline, spill top value if needed"
- (popBoolean or: [ cogit ssTop spilled ]) ifFalse:
- [ self assert: (cogit ssTop type = SSRegister and: [cogit ssTop register = ClassReg]).
- cogit PushR: ClassReg ].
- "pass the unboxed index using TempReg"
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"
- "Top of stack is consumed by the trampoline. In case of store with non spilled value,
- restore ClassReg to match simulated stack state"
- (popBoolean or: [ cogit ssTop spilled ]) ifFalse:
- [cogit popR: ClassReg].
- "restore ReceiverResultReg state if needed"
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: 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 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
popBoolean: popBoolean
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 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. ]
- ifTrue: [ self ssStoreAndReplacePop: popBoolean toReg: ClassReg. ]
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
popBoolean: popBoolean
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 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.
- self ssStoreAndReplacePop: popBoolean toReg: topReg.
immutabilityFailure := objectRepresentation
genImmutableCheck: ReceiverResultReg
slotIndex: slotIndex
sourceReg: ClassReg
scratchReg: TempReg
popBoolean: popBoolean
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>>ssStoreAndReplacePop:toReg: (in category 'simulation stack') -----
ssStoreAndReplacePop: popBoolean toReg: reg
"In addition to ssStorePop:toReg:, if this is a store and not
+ a popInto I change the simulated stack to use the register
+ for the top value"
- a popInto and the top of the simulated stack is not spilled,
- I change the simulated stack to use the register for the value"
| topSpilled |
topSpilled := self ssTop spilled.
self ssStorePop: (popBoolean or: [topSpilled]) toReg: reg.
popBoolean ifFalse:
[ topSpilled ifFalse: [self ssPop: 1].
self ssPushRegister: reg ].!
More information about the Vm-dev
mailing list