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 ].! |
Free forum by Nabble | Edit this page |