Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3351.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3351 Author: eem Time: 15 February 2024, 2:08:43.718855 pm UUID: ee0e1c44-4495-48cb-aa70-ca668d8bd20d Ancestors: VMMaker.oscog-eem.3350
Oops; not so fast! The fallback disown/own code needs to be a little more careful to avoid failing the sender.
=============== Diff against VMMaker.oscog-eem.3350 ===============
Item was changed: ----- Method: StackInterpreter>>disownVM: (in category 'vm scheduling') ----- disownVM: flags <public> <inline: false> "Release the VM to other threads and answer the current thread's index. Currently valid flags for the non-threaded VM are: DisownVMForThreading - allow the VM to thread-switch; this is ignored DisownVMLockOutFullGC - prevent fullGCs while this thread disowns the VM DisownVMForFFICall - informs the VM that it is entering an FFI call
This is the entry-point for plugins and primitives that wish to release the VM while performing some operation that may potentially block, and for callbacks returning back to some blocking operation. While this exists for the threaded FFI VM we use it to reset newMethod and the argumentCount after a callback." self assert: primFailCode = 0.
flags = DisownVMForThreading ifTrue: + [^flags]. - [^0].
"Hack encodings of client state. We use non-immediates (bottom three bits clear) for FFI/Plugin doing save := self disownVM: FLAGS. ... callout ... self ownVM: save. We use immediate integer (bottom bit 1) for callbacks doing save := self ownVM: 0. ... callback ... self disownVM: save. return to C" self assert: ((objectMemory isImmediate: flags) ifFalse: [flags = (flags bitAnd: DisownVMForFFICall+DisownVMForThreading) and: [flags anyMask: DisownVMForFFICall]] ifTrue: [(objectMemory isIntegerObject: flags) and: [(objectMemory integerValueOf: flags) between: 0 and: (self argumentCountOfMethodHeader: -1)]]).
"If DisownVMForFFICall this is from the FFI plugin and we're making a callout; remember the fact." (((objectMemory isImmediate: flags)) not and: [flags anyMask: DisownVMForFFICall]) ifTrue: [self assert: ((objectMemory isOopCompiledMethod: newMethod) and: [(self argumentCountOf: newMethod) = argumentCount]). inFFIFlags := DisownVMForFFICall. ^flags].
self assert: ((objectMemory isIntegerObject: flags) and: [(objectMemory integerValueOf: flags) between: 0 and: (self argumentCountOfMethodHeader: -1)]).
"Otherwise this is a callback return; restore argumentCount and newMethod as per the ownVM: on callback." argumentCount := objectMemory integerValueOf: flags. newMethod := self popStack. self assert: ((objectMemory isOopCompiledMethod: newMethod) and: [(self argumentCountOf: newMethod) = argumentCount]). ^0!
Item was changed: ----- Method: StackInterpreter>>ownVM: (in category 'vm scheduling') ----- ownVM: threadIndexAndFlags <public> <inline: false> "This is the entry-point for plugins and primitives that wish to reacquire the VM after having released it via disownVM or callbacks that want to acquire it without knowing their ownership status. While this exists for the threaded FFI VM we use it to reset newMethod and the argumentCount after a callback.
Answer -1 if the current thread is unknown to the VM and fails to take ownership." <var: 'amInVMThread' declareC: 'extern sqInt amInVMThread(void)'> self cppIf: COGMTVM ifTrue: [self amInVMThread ifFalse: [^-1]].
self assert: ((objectMemory isOopCompiledMethod: newMethod) and: [(self argumentCountOf: newMethod) = argumentCount]).
+ threadIndexAndFlags = DisownVMForThreading ifTrue: + [^threadIndexAndFlags]. + "Hack encodings of client state. We use non-immediates (bottom three bits clear) for FFI/Plugin doing save := self disownVM: FLAGS. ... callout ... self ownVM: save. We use immediate integer (bottom bit 1) for callbacks doing save := self ownVM: 0. ... callback ... self disownVM: save. return to C"
"If DisownVMForFFICall this is from the FFI plugin and we're returning from a callout." (threadIndexAndFlags anyMask: DisownVMForFFICall) ifTrue: [inFFIFlags := 0. ^threadIndexAndFlags].
"Otherwise this is a callback; stash newMethod on the stack and encode argumentCount in the flags retrieved when the calback calls disownVM:." self assert: primFailCode = 0. self push: newMethod. ^objectMemory integerObjectOf: argumentCount!
vm-dev@lists.squeakfoundation.org