Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2904.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2904 Author: eem Time: 30 November 2020, 12:09:05.818551 pm UUID: 8569e47f-67b4-4e80-9af6-303a01f7c2c3 Ancestors: VMMaker.oscog-eem.2903 MTVM: fix preemptDisowningThread; marryFrame:SP: expects top-of-stack to be the Smalltalk top-of-stack, not a pushed instructionPointer. =============== Diff against VMMaker.oscog-eem.2903 =============== Item was changed: ----- Method: CoInterpreterMT>>preemptDisowningThread (in category 'vm scheduling') ----- preemptDisowningThread "Set the relevant state for disowningVMThread so that it can resume after being preempted and set disowningVMThread to nil to indicate preemption. N.B. This should only be sent from checkPreemptionOfDisowningThread. There are essentially four things to do. a) save the VM's notion of the current C stack pointers; these are pointers into a thread's stack and must be saved and restored in thread switch. b) save the VM's notion of the current Smalltalk execution point. This is simply the suspend half of a process switch that saves the current context in the current process. c) add the process to the thread's set of AWOL processes so that the scheduler won't try to run the process while the thread has disowned the VM. d) save the in-primitive VM state, newMethod and argumentCount ownVM: will restore the VM context as of disownVM: from the above when it finds it has been preempted." | activeProc activeContext preemptedThread | <var: #preemptedThread type: #'CogVMThread *'> <inline: false> self assert: disowningVMThread notNil. self assert: (disowningVMThread state = CTMUnavailable or: [disowningVMThread state = CTMWantingOwnership]). self assertCStackPointersBelongToDisowningThread. cogit recordEventTrace ifTrue: [self recordTrace: TracePreemptDisowningThread thing: (objectMemory integerObjectOf: disowningVMThread index) source: 0]. disowningVMThread cStackPointer: CStackPointer. disowningVMThread cFramePointer: CFramePointer. activeProc := self activeProcess. self assert: (objectMemory fetchPointer: MyListIndex ofObject: activeProc) = objectMemory nilObject. objectMemory storePointer: MyListIndex ofObject: activeProc withValue: (objectMemory splObj: ProcessInExternalCodeTag). + activeContext := self ensureFrameIsMarried: framePointer SP: stackPointer. + objectMemory + storePointer: SuspendedContextIndex + ofObject: activeProc + withValue: activeContext. "The instructionPointer must be pushed because the convention for inactive stack pages is that the instructionPointer is top of stack. We need to know if this primitive is called from machine code because the invariant that the return pc of an interpreter callee calling a machine code caller is ceReturnToInterpreterPC must be maintained." self push: instructionPointer. self externalWriteBackHeadFramePointers. - activeContext := self ensureFrameIsMarried: framePointer SP: stackPointer. - objectMemory - storePointer: SuspendedContextIndex - ofObject: activeProc - withValue: activeContext. "Since pushing the awol process may realloc disowningVMThread we need to reassign. But since we're going to nil disowningVMThread anyway we can assign to a local." preemptedThread := cogThreadManager pushAWOLProcess: activeProc on: disowningVMThread. disowningVMThread := nil. preemptedThread priority: (self quickFetchInteger: PriorityIndex ofObject: activeProc). (self ownerIndexOfProcess: activeProc) = 0 ifTrue: [self setOwnerIndexOfProcess: activeProc to: preemptedThread index bind: false] ifFalse: [self assert: (self ownerIndexOfProcess: activeProc) = preemptedThread index]. preemptedThread newMethodOrNull: newMethod; argumentCount: argumentCount; primitiveFunctionPointer: primitiveFunctionPointer; inMachineCode: instructionPointer asUnsignedInteger <= objectMemory startOfMemory! |
Free forum by Nabble | Edit this page |