[squeak-dev] FFI: FFI-Kernel-mt.218.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu Aug 19 13:22:30 UTC 2021
Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.218.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.218
Author: mt
Time: 19 August 2021, 3:22:28.986186 pm
UUID: 214b5564-8fa9-5c47-9334-07e3fd038f60
Ancestors: FFI-Kernel-mt.217
Speed up mem-copy (i.e., #structAt:length: in ByteArray) by factor 10.
Speed up read/write pointers (i.e., ExternalAddress) by factor 20, given that you have primitives for #asInteger and #fromInteger in your plugin.
Use the same algorithm as in #zeroMemory:, which reduces the amount of primitive sends as much as possible.
=============== Diff against FFI-Kernel-mt.217 ===============
Item was added:
+ ----- Method: ByteArray>>memoryAt:length: (in category '*FFI-Kernel-accessing') -----
+ memoryAt: byteOffset length: numBytes
+
+ | index size handle startByteOffset |
+ handle := ByteArray new: numBytes.
+ startByteOffset := byteOffset - 1.
+ index := 1.
+ size := numBytes - 7.
+ [index <= size] whileTrue:
+ [handle uint64At: index put: (self uint64At: startByteOffset + index).
+ index := index + 8].
+ size := size + 4. "7 - 3, i.e. numBytes - 3"
+ index <= size ifTrue:
+ [handle uint32At: index put: (self uint32At: startByteOffset + index).
+ index := index + 4].
+ size := size + 2. "3 - 1, i.e. numBytes - 1"
+ index <= size ifTrue:
+ [handle uint16At: index put: (self uint16At: startByteOffset + index).
+ index := index + 2].
+ size := size + 1.
+ index <= size ifTrue:
+ [handle uint8At: index put: (self uint8At: startByteOffset + index)].
+ ^ handle!
Item was added:
+ ----- Method: ByteArray>>memoryAt:put:length: (in category '*FFI-Kernel-accessing') -----
+ memoryAt: byteOffset put: handle length: numBytes
+
+ | index size startByteOffset |
+ startByteOffset := byteOffset - 1.
+ index := 1.
+ size := numBytes - 7.
+ [index <= size] whileTrue:
+ [self uint64At: startByteOffset + index put: (handle uint64At: index).
+ index := index + 8].
+ size := size + 4. "7 - 3, i.e. numBytes - 3"
+ index <= size ifTrue:
+ [self uint32At: startByteOffset + index put: (handle uint32At: index).
+ index := index + 4].
+ size := size + 2. "3 - 1, i.e. numBytes - 1"
+ index <= size ifTrue:
+ [self uint16At: startByteOffset + index put: (handle uint16At: index).
+ index := index + 2].
+ size := size + 1.
+ index <= size ifTrue:
+ [self uint8At: startByteOffset + index put: (handle uint8At: index)].
+ ^ handle!
Item was changed:
----- Method: ByteArray>>pointerAt:length: (in category '*FFI-Kernel-accessing') -----
pointerAt: byteOffset length: length
"Return a pointer of the given length starting at the indicated byte offset."
+ ^ ExternalAddress fromInteger: (self integerAt: byteOffset size: length signed: false)!
- | pointer startByteOffset |
- pointer := ExternalAddress basicNew: length.
- startByteOffset := byteOffset - 1.
- 1 to: length do: [:pointerByteOffset |
- pointer
- basicAt: pointerByteOffset
- put: (self unsignedByteAt: startByteOffset + pointerByteOffset)].
- ^ pointer!
Item was changed:
----- Method: ByteArray>>pointerAt:put:length: (in category '*FFI-Kernel-accessing') -----
+ pointerAt: byteOffset put: externalAddress length: length
- pointerAt: byteOffset put: pointer length: length
"Store a pointer of the given length starting at the indicated byte offset."
+ self integerAt: byteOffset put: externalAddress asInteger size: length signed: false.
+ ^ externalAddress!
- | startByteOffset |
- self assert: [pointer isExternalAddress].
- startByteOffset := byteOffset - 1.
- 1 to: length do: [:pointerByteOffset |
- self
- unsignedByteAt: startByteOffset + pointerByteOffset
- put: (pointer basicAt: pointerByteOffset)].
- ^ pointer!
Item was changed:
----- Method: ByteArray>>structAt:length: (in category '*FFI-Kernel-accessing') -----
structAt: byteOffset length: length
"Return a structure of the given length starting at the indicated byte offset."
+
+ ^ self memoryAt: byteOffset length: length!
-
- | value startByteOffset |
- self flag: #todo. "mt: Better name #unsignedBytesAt:length:?"
- value := ByteArray new: length.
- startByteOffset := byteOffset - 1.
- 1 to: length do: [:valueByteOffset |
- value
- unsignedByteAt: valueByteOffset
- put: (self unsignedByteAt: startByteOffset + valueByteOffset)].
- ^ value!
Item was changed:
----- Method: ByteArray>>structAt:put:length: (in category '*FFI-Kernel-accessing') -----
structAt: byteOffset put: value length: length
"Store a structure of the given length starting at the indicated byte offset."
+ ^ self memoryAt: byteOffset put: value length: length!
- | startByteOffset |
- self flag: #todo. "mt: Better name #unsignedBytesAt:put:length:?"
- startByteOffset := byteOffset - 1.
- 1 to: length do: [:valueByteOffset |
- self
- unsignedByteAt: startByteOffset + valueByteOffset
- put: (value unsignedByteAt:valueByteOffset)].
- ^ value!
Item was added:
+ ----- Method: ByteArrayReadWriter>>memoryAt:length: (in category 'read/write structs') -----
+ memoryAt: newByteOffset length: newLength
+
+ self checkAt: newByteOffset length: newLength.
+ ^ ByteArrayReadWriter new
+ setArray: byteArray
+ offset: byteOffset + newByteOffset - 1
+ size: newLength!
Item was added:
+ ----- Method: ByteArrayReadWriter>>memoryAt:put:length: (in category 'read/write structs') -----
+ memoryAt: newByteOffset put: value length: newLength
+
+ self checkAt: newByteOffset length: newLength.
+ ^ byteArray
+ structAt: byteOffset + newByteOffset - 1
+ put: value
+ length: newLength!
Item was changed:
----- Method: ByteArrayReadWriter>>structAt:length: (in category 'read/write structs') -----
structAt: newByteOffset length: newLength
+ ^ self memoryAt: newByteOffset length: newLength!
- self checkAt: newByteOffset length: newLength.
- ^ ByteArrayReadWriter new
- setArray: byteArray
- offset: byteOffset + newByteOffset - 1
- size: newLength!
Item was changed:
----- Method: ByteArrayReadWriter>>structAt:put:length: (in category 'read/write structs') -----
structAt: newByteOffset put: value length: newLength
+ ^ self memoryAt: newByteOffset put: value length: newLength!
- self checkAt: newByteOffset length: newLength.
- ^ byteArray
- structAt: byteOffset + newByteOffset - 1
- put: value
- length: newLength!
Item was added:
+ ----- Method: ExternalAddress>>memoryAt:length: (in category 'accessing') -----
+ memoryAt: byteOffset length: length
+ "Overwritten to not read bytes but just move the pointer. Ignore the length."
+
+ ^ ExternalAddress fromAddress: self movedBy: byteOffset - 1!
Item was removed:
- ----- Method: ExternalAddress>>structAt:length: (in category 'accessing') -----
- structAt: byteOffset length: length
- "Overwritten to not read bytes but just move the pointer. Ignore the length."
-
- ^ ExternalAddress fromAddress: self movedBy: byteOffset - 1!
Item was changed:
----- Method: ExternalData>>from: (in category 'accessing') -----
from: firstIndex
"Move the start of this array. Size not needed."
| byteOffset numElements byteSize |
byteOffset := ((firstIndex-1) * self contentType byteSize)+1.
numElements := (self size ifNotNil: [:sz | sz - firstIndex + 1 max: 0]).
byteSize := numElements
ifNil: [self contentType byteSize]
ifNotNil: [numElements * self contentType byteSize].
^ ExternalData
+ fromHandle: (handle memoryAt: byteOffset length: (byteSize ifNil: [1]))
- fromHandle: (handle structAt: byteOffset length: (byteSize ifNil: [1]))
type: self contentType
size: numElements!
Item was changed:
----- Method: ExternalData>>from:to: (in category 'accessing') -----
from: firstIndex to: lastIndex
"Only copy data if already in object memory, that is, as byte array. Only check size if configured."
| byteOffset numElements byteSize |
ExtraSizeChecks == true ifTrue: [
self sizeCheck: firstIndex.
self sizeCheck: lastIndex].
byteOffset := ((firstIndex-1) * self contentType byteSize)+1.
numElements := lastIndex - firstIndex + 1 max: 0.
byteSize := numElements * self contentType byteSize.
^ ExternalData
+ fromHandle: (handle memoryAt: byteOffset length: byteSize)
- fromHandle: (handle structAt: byteOffset length: byteSize)
type: self contentType
size: numElements!
Item was changed:
----- Method: ExternalData>>postCopy (in category 'copying') -----
postCopy
"Reads all bytes from external into object memory or duplicate the array within object memory. Note that this does not flatten all bytes into a single array by repeatedly calling it."
+ | newHandle numBytes |
- | bytes |
self sizeCheck.
+ numBytes := self byteSize.
+ newHandle := ByteArray new: numBytes.
+ newHandle memoryAt: 1 put: handle length: numBytes.
- bytes := ByteArray new: self byteSize.
- 1 to: bytes size do: [:index |
- bytes basicAt: index put: (handle unsignedByteAt: index)].
+ handle := newHandle.
- handle := bytes.
self setType: type. "Change container type from pointer to non-pointer type."!
Item was changed:
----- Method: GenericIntegerReadWriteSend class>>useSpecificIntegerPrimitives: (in category 'preferences') -----
useSpecificIntegerPrimitives: aBoolean
UseSpecificIntegerPrimitives = aBoolean ifTrue: [^ self].
+ aBoolean ==> [self canUseSpecificIntegerPrimitives]
+ ifFalse: [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.'].
- 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.
ExternalStructure defineAllFields].!
More information about the Squeak-dev
mailing list
|