Eliot Miranda uploaded a new version of Cog to project VM Maker: http://source.squeak.org/VMMaker/Cog-eem.414.mcz ==================== Summary ==================== Name: Cog-eem.414 Author: eem Time: 28 October 2020, 1:22:52.353271 am UUID: 12531e8d-e09b-4057-a626-60006375a14a Ancestors: Cog-eem.413 Write code to stitch the stack together to preserve the continuation when raising the first of a pair of ProcessorSimulationTraps (from ARMv8 load/store pair) outside of the critical section inside MultiProcessor's doesNotUnderstand:. But even though this code looks correct it appears not to work properly. Boris has complained of a simular bug. Hence, let's try and simulate the simulator and see what is happening with this bug. Go some way to making the ProcessorSimulatorPlugins simulate :-) So far implement primitiveNewCPU and primitiveIntegerRegisterState. =============== Diff against Cog-eem.413 =============== Item was added: + ----- Method: BochsIA32Plugin>>alienClass (in category 'simulation support') ----- + alienClass + ^BochsIA32Alien! Item was added: + ----- Method: BochsX64Plugin>>alienClass (in category 'simulation support') ----- + alienClass + ^BochsX64Alien! Item was added: + ----- Method: CogProcessorAlien>>nonVirtualProcessor (in category 'accessing-abstract') ----- + nonVirtualProcessor + ^self! Item was added: + ----- Method: GdbARMv6Plugin>>alienClass (in category 'simulation support') ----- + alienClass + ^GdbARMAlien! Item was added: + ----- Method: GdbARMv8Plugin>>alienClass (in category 'simulation support') ----- + alienClass + ^GdbARMv8Alien! Item was added: + ----- Method: MIPSSimulator>>nonVirtualProcessor (in category 'accessing-abstract') ----- + nonVirtualProcessor + ^self! Item was changed: ----- Method: MultiProcessor>>doesNotUnderstand: (in category 'message forwarding') ----- doesNotUnderstand: aMessage "Forward a message to the actual processor, managing a thread-switch if necessary. Catch ProcessorSimulationTraps and raise them outside of the critical section to avoid deadlock when reentering the VM from a trap and switching threads in the run-time." + | selector result trap contextInCritical | - | selector result trap | selector := aMessage selector. (guardedProcessorProtocol includes: selector) ifFalse: [^(unguardedProcessorProtocol includes: selector) ifTrue: [processor perform: selector withArguments: aMessage arguments] ifFalse: [super doesNotUnderstand: aMessage]]. result := [mutex critical: + [contextInCritical := thisContext. + owner ~~ mutex owningProcess ifTrue: - [owner ~~ mutex owningProcess ifTrue: [owner ifNotNil: [registerState at: owner put: processor registerState]. (registerState at: (owner := mutex owningProcess) ifAbsent: nil) ifNil: [coInterpreter initializeProcessorForThreadIndex: (threadIndex := threadIndex + 1)] ifNotNil: [:newState| processor setRegisterState: newState]]. processor perform: selector withArguments: aMessage arguments]] on: ProcessorSimulationTrap, Error, AssertionFailure do: [:ex| ex class == ProcessorSimulationTrap ifFalse: [ex pass]. + "Alas things are not so simple with ARMv8 ldp/stp... + The comments in these two methods explain..." + (self isAboutToReturn: ex signalerContext) ifFalse: + [self saveStackFor: ex signalerContext + above: contextInCritical + homeContext: thisContext home]. trap := ex]. ^trap ifNil: [result] ifNotNil: [trap signal]! Item was added: + ----- Method: MultiProcessor>>isAboutToReturn: (in category 'private-deep hackery') ----- + isAboutToReturn: aContextRaisingProcessorSimulationTrap + "Answer if aContextRaisingProcessorSimulationTrap is about to return the result of raising + a ProcessorSimulationTrap. Such traps don't need special handling when continuing." + ^aContextRaisingProcessorSimulationTrap willReturn + or: [aContextRaisingProcessorSimulationTrap willJump + and: [aContextRaisingProcessorSimulationTrap copy interpretJump; willReturn]]! Item was added: + ----- Method: MultiProcessor>>nonVirtualProcessor (in category 'accessing-abstract') ----- + nonVirtualProcessor + ^processor! Item was added: + ----- Method: MultiProcessor>>saveStackFor:above:homeContext: (in category 'private-deep hackery') ----- + saveStackFor: signalerContext above: contextInCritical homeContext: doesNotUnderstandContext + "Some processors, notably ARMv8, support load/store pair instructions which may raise two + ProcessorSimulationTraps. To handle this we must preserve the continuation following the + raising of the first simulaiton trap. This cuts up, and restitches the stack so that when the + first ProcessorSimulationTrap is raised outside the critical: block in our doesNotUnderstand: + method, control continues to the second trap." + | contextAboveContextInCritical contextAboveSignalerContext | + contextAboveContextInCritical := signalerContext findContextSuchThat: [:ctxt| ctxt sender == contextInCritical]. + "This is our continuation, which should be changed to continue back into the critical section." + contextAboveSignalerContext := thisContext findContextSuchThat: [:ctxt| ctxt sender == signalerContext]. + self deny: contextAboveContextInCritical isNil. + self deny: contextAboveSignalerContext isNil. + + "signalerContext through contextAboveContextInCritical is the stack that is the continuation + for the trap. This must be inserted between the doesNotUnderstandContext and its sender." + signalerContext cut: contextAboveContextInCritical. + contextAboveContextInCritical privSender: doesNotUnderstandContext sender. + doesNotUnderstandContext privSender: signalerContext. + + "Now arrange that the handler returns to contextInCritical; and we're done." + contextAboveSignalerContext privSender: contextInCritical. + self deny: (thisContext findContextSuchThat: [:ctxt| ctxt == signalerContext]) isNil. + self deny: (thisContext findContextSuchThat: [:ctxt| ctxt == contextInCritical]) isNil. + self deny: (thisContext findContextSuchThat: [:ctxt| ctxt == doesNotUnderstandContext]) isNil! Item was changed: SmartSyntaxInterpreterPlugin subclass: #ProcessorSimulatorPlugin + instanceVariableNames: 'prevInterruptCheckChain mySimulatorAlien' - instanceVariableNames: 'prevInterruptCheckChain' classVariableNames: 'NumIntegerRegisterStateFields' poolDictionaries: 'VMBasicConstants' category: 'Cog-ProcessorPlugins'! !ProcessorSimulatorPlugin commentStamp: 'eem 11/19/2019 09:32' prior: 0! ProcessorSimulatorPlugin is the abstract superclass for plugins that interface to a processor simulator that executes the machine code for some processor the Cog JIT generates code for. These include the Bochs C++ IA32/x64 processor emulator, and the GDB simulator for the ARMv6 and ARMv8 architectures. Instance Variables prevInterruptCheckChain: <Symbol/function pointer> prevInterruptCheckChain - the previous value of the interruptCheckChain function pointer ! Item was changed: ----- Method: ProcessorSimulatorPlugin class>>declareCVarsIn: (in category 'translation') ----- declareCVarsIn: aCCodeGenerator self ~~ ProcessorSimulatorPlugin ifTrue: [super declareCVarsIn: aCCodeGenerator. aCCodeGenerator removeVariable: 'prevInterruptCheckChain'; "lives in the platform support code." + removeConstant: #NumIntegerRegisterStateFields]. "defined by the header file" + aCCodeGenerator removeVariable: 'mySimulatorAlien' ifAbsent: nil! - removeConstant: #NumIntegerRegisterStateFields] "defined by the header file"! Item was added: + ----- Method: ProcessorSimulatorPlugin>>newCPU (in category 'simulation') ----- + newCPU + "Isn't this deliciously recursive??" + <doNotGenerate> + ((interpreterProxy coInterpreter isKindOf: CoInterpreter) + and: [self alienClass = interpreterProxy coInterpreter cogit processor nonVirtualProcessor class]) ifTrue: + [self error: 'this isn''t going to work; choose a different simulator class to run the simulation...']. + mySimulatorAlien := self alienClass createNewCPU. + NumIntegerRegisterStateFields := mySimulatorAlien integerRegisterState size. + ^mySimulatorAlien address! Item was added: + ----- Method: ProcessorSimulatorPlugin>>storeIntegerRegisterStateOf:into: (in category 'simulation support') ----- + storeIntegerRegisterStateOf: objOop into: aCArray + | state | + state := mySimulatorAlien integerRegisterState. + 1 to: state size do: + [:i| aCArray at: i - 1 put: (objOop at: i)]! |
Free forum by Nabble | Edit this page |