Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI: http://source.squeak.org/FFI/FFI-Kernel-mt.198.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.198 Author: mt Time: 12 August 2021, 10:40:33.706222 am UUID: 59e4fc64-3f4f-4241-ba22-5178c5cf7028 Ancestors: FFI-Kernel-eem.197
Adds preference to opt-out from specific integer primitives, which yields better performance when the FFI plugin does not yet have those new primitives. :-) And it allows for simpler benchmarking.
=============== Diff against FFI-Kernel-eem.197 ===============
Item was changed: ----- Method: ByteArray>>integerAt:put:size:signed: (in category '*FFI-Kernel-accessing - integer') ----- integerAt: byteOffset put: value size: nBytes signed: aBoolean "Primitive. Store the given value as integer of nBytes size in the receiver. - BYTE ORDER is platform native order. - FAILS IF the value is out of range. - NOTE that this primitive will access memory in the outer space if invoked from ExternalAddress." <primitive: #primitiveFFIIntegerAtPut module: #SqueakFFIPrims> + <ffiAtomicWrite: #( int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t ) > - "<ffiAtomicWrite: #( int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t ) >" "Examples: ExternalType int32_t allocate value: -1; explore. ExternalType uint32_t allocate value: 1; explore. " ^ self primitiveFailed!
Item was changed: ----- Method: ByteArray>>integerAt:size:signed: (in category '*FFI-Kernel-accessing - integer') ----- integerAt: byteOffset size: nBytes signed: aBoolean "Primitive. Return an integer of nBytes size from the receiver. - BYTE ORDER is platform native order. - FAILS IF the receiver has not enough bytes. - NOTE that this primitive will access memory in the outer space if invoked from ExternalAddress." <primitive: #primitiveFFIIntegerAt module: #SqueakFFIPrims> + <ffiAtomicRead: #( int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t ) > - "<ffiAtomicRead: #( int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t ) >" "Examples: ExternalType int32_t handle: #[ 255 0 0 255 ] at: 1. ExternalType uint32_t handle: #[ 255 0 0 255 ] at: 1. " ^ self primitiveFailed!
Item was added: + ----- Method: ByteArray>>testInt32At: (in category '*FFI-Kernel-accessing - integer') ----- + testInt32At: byteOffset + "Use this to check whether your FFI plugin supports the specific integer primitives." + <primitive: #primitiveSignedInt32At module: #SqueakFFIPrims error: ec> + ^ nil "To make check faster than via #primitiveFailed exception handler."!
Item was changed: FFIAtomicReadWriteSend subclass: #GenericIntegerReadWriteSend instanceVariableNames: '' + classVariableNames: 'UseSpecificIntegerPrimitives' - classVariableNames: '' poolDictionaries: '' category: 'FFI-Kernel-Support'!
!GenericIntegerReadWriteSend commentStamp: 'mt 8/6/2021 16:11' prior: 0! I am a message send for reading and writing atomic integer values from and to byte arrays or external addresses. My instances memoize type-specific #byteSize and #isSigned. See #isIntegerType and #initializeAtomicSends.
I am generic in the sense that my target primitive covers several atomic types.!
Item was added: + ----- Method: GenericIntegerReadWriteSend class>>canUseSpecificIntegerPrimitives (in category 'preferences') ----- + canUseSpecificIntegerPrimitives + + ^ ((ByteArray new: 4) testInt32At: 1) notNil!
Item was added: + ----- Method: GenericIntegerReadWriteSend class>>pragma:selectsAtomicType: (in category 'instance creation') ----- + pragma: pragma selectsAtomicType: atomicType + "Overwritten to filter between generic and specific integer primitives according to the preference. Note that #isArray is an indicator for a generic primitive." + + "self assert: [atomicType isIntegerType]." + ^ self useSpecificIntegerPrimitives "want specific?" = (pragma argumentAt: 1) isArray "found generic?" + ifTrue: [false] + ifFalse: [super pragma: pragma selectsAtomicType: atomicType]!
Item was added: + ----- Method: GenericIntegerReadWriteSend class>>useSpecificIntegerPrimitives (in category 'preferences') ----- + useSpecificIntegerPrimitives + <preference: 'Use specific integer primitives' + categoryList: #('FFI Kernel') + description: 'When true, use specific primitives when reading/writing int32_t, uint32_t etc. from/to ByteArray or ExternalAddress. Note that your FFI plugin might not support those newer primitives.' + type: #Boolean> + ^ UseSpecificIntegerPrimitives ifNil: [true "Cannot use #canUseSpecificIntegerPrimitives because struct-field generation is affected. Need to keep this preference in sync with how the struct-field accessors actually look like."]!
Item was added: + ----- Method: GenericIntegerReadWriteSend class>>useSpecificIntegerPrimitives: (in category 'preferences') ----- + useSpecificIntegerPrimitives: aBoolean + + UseSpecificIntegerPrimitives = aBoolean ifTrue: [^ self]. + + aBoolean ~= self canUseSpecificIntegerPrimitives + ifTrue: [self notify: 'FFI plugin does not support specific integer primitives. Proceed to update atomic sends anyway. Fallback code will redirect to generic integer primitive. Performance might be affected.']. + + UseSpecificIntegerPrimitives := aBoolean. + + Cursor wait showWhile: [ + ExternalType initializeAtomicSends. + MessageTally spyOn: [ExternalStructure defineAllFields]].!
packages@lists.squeakfoundation.org