Eliot Miranda uploaded a new version of Cog to project VM Maker: http://source.squeak.org/VMMaker/Cog-eem.420.mcz ==================== Summary ==================== Name: Cog-eem.420 Author: eem Time: 28 October 2020, 7:15:44.003408 pm UUID: b03ad887-622e-4bf4-9fe4-7470af59aa6c Ancestors: Cog-eem.419 Fix the stack stitching code. Fix MultiProcessor's desNotUnderstand: handler to return the non-virtual processor to the second trap continuation. ANd no breaks for the wicked... =============== Diff against Cog-eem.419 =============== 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 := 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 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 ifNotNil: + [:resultOfSignal| + resultOfSignal == self + ifTrue: [processor] + ifFalse: [resultOfSignal]]]! - ^trap ifNil: [result] ifNotNil: [trap signal]! Item was changed: ----- 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 simulation trap. This cuts up, and restitches the stack so that when 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 | + "This is the bottom context in the saved continuation, which must be stitched in beneath the doesNotUnderstand: handler." + contextAboveContextInCritical := signalerContext findContextSuchThat: [:ctxt| ctxt sender == contextInCritical]. - | contextAboveSignalerContext | "This is our continuation, which should be changed to continue back into the critical section." contextAboveSignalerContext := thisContext findContextSuchThat: [:ctxt| ctxt sender == signalerContext]. self deny: contextAboveSignalerContext isNil. "signalerContext through the context above contextInCritical is the stack that is the continuation for the trap. This must be inserted between the doesNotUnderstandContext and its sender. N.B. Context>>cut: cuts above the argument!!!!" signalerContext cut: contextInCritical. + contextAboveContextInCritical privSender: doesNotUnderstandContext sender. - contextInCritical privSender: doesNotUnderstandContext sender. doesNotUnderstandContext privSender: signalerContext. "Now arrange that the handler returns to contextInCritical; and we're done." contextAboveSignalerContext privSender: contextInCritical! Item was changed: ----- Method: ProcessorSimulatorPlugin>>singleStepCPU:In:Size:MinAddressRead:Write: (in category 'simulation') ----- singleStepCPU: cpu In: memoryCArray Size: memorySize MinAddressRead: minAddress Write: minWriteMaxExecAddress <doNotGenerate> "*now* we need derived pointers. Ho hum... But all we need is one more level of indirection..." | result | - self break. result := mySimulatorAlien rawPrimitiveSingleStepInMemory: interpreterProxy memory offsetBy: memoryCArray ptrAddress minimumAddress: minAddress readOnlyBelow: minWriteMaxExecAddress. ^result == mySimulatorAlien ifTrue: [0] ifFalse: [result isPrimitiveError ifTrue: [result errorCode] ifFalse: [result]]! |
Free forum by Nabble | Edit this page |