[squeak-dev] FFI: FFI-Kernel-mt.217.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Aug 19 11:19:48 UTC 2021

Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:

==================== Summary ====================

Name: FFI-Kernel-mt.217
Author: mt
Time: 19 August 2021, 1:19:47.069627 pm
UUID: b50f6f6d-fcf9-9e46-8d36-d8aea7f5b4c3
Ancestors: FFI-Kernel-mt.216

Manage array classes as instVar in external type instead of classVar to further speed up type-based allocation.

Having #useArrayClasses enabled, we are now very close to the direct appraoch, which is infavorable due to exposing implementation details:

[Float32Array new: 10] bench.
GOAL: '55,200,000 per second. 18.1 nanoseconds per run. 8.45662 % GC time.'

[ExternalType float allocate: 10] bench
NOW: '33,200,000 per second. 30.1 nanoseconds per run. 5.33893 % GC time.'

=============== Diff against FFI-Kernel-mt.216 ===============

Item was changed:
  Object subclass: #ExternalType
+ 	instanceVariableNames: 'compiledSpec referentClass referencedType byteAlignment arrayClass'
+ 	classVariableNames: 'ArrayTypes AtomicTypeCodes AtomicTypes ExtraTypeChecks StructTypes UseArrayClasses UseTypePool'
- 	instanceVariableNames: 'compiledSpec referentClass referencedType byteAlignment'
- 	classVariableNames: 'ArrayClasses ArrayTypes AtomicTypeCodes AtomicTypes ExtraTypeChecks StructTypes UseArrayClasses UseTypePool'
  	poolDictionaries: 'ExternalTypePool FFIConstants'
  	category: 'FFI-Kernel'!
  !ExternalType commentStamp: 'mt 6/5/2020 18:25' prior: 0!
  An external type represents the type of external objects.
  Instance variables:
  	compiledSpec	<WordArray>		Compiled specification of the external type
  	referentClass	<Behavior | nil>	Class type of argument required
  	referencedType	<ExternalType>	Associated (non)pointer type with the receiver
  	byteAlignment	<Integer | nil>		The desired alignment for a field of the external type within a structure.  If nil it has yet to be computed.
  Compiled Spec:
  The compiled spec defines the type in terms which are understood by the VM. Each word is defined as:
  	bits 0...15 	- byte size of the entity
  	bit 16		- structure flag (FFIFlagStructure)
  				  This flag is set if the following words define a structure
  	bit 17		- pointer flag (FFIFlagPointer)
  				  This flag is set if the entity represents a pointer to another object
  	bit 18		- atomic flag (FFIFlagAtomic)
  				  This flag is set if the entity represents an atomic type.
  				  If the flag is set the atomic type bits are valid.
  	bits 19...23	- unused
  	bits 24...27	- atomic type (FFITypeVoid ... FFITypeDoubleFloat)
  	bits 28...31	- unused
  Note that all combinations of the flags FFIFlagPointer, FFIFlagAtomic, and FFIFlagStructure are invalid, EXCEPT from the following:
  	FFIFlagPointer + FFIFlagAtomic:
  		This defines a pointer to an atomic type (e.g., 'char*', 'int*').
  		The actual atomic type is represented in the atomic type bits.
  	FFIFlagPointer + FFIFlagStructure:
  		This defines a structure which is a typedef of a pointer type as in
  			typedef void* VoidPointer;
  			typedef Pixmap* PixmapPtr;
  		It requires a byte size of four or eight (e.g. a 32-bit or 64-bit pointer) to work correctly.
  [Note: Other combinations may be allowed in the future]

Item was changed:
  ----- Method: ExternalType class>>initializeArrayClasses (in category 'class initialization') -----
  	ExternalType initializeArrayClasses.
- 	ArrayClasses ifNil: [
- 		ArrayClasses := IdentityDictionary new].
  	RawBitsArray allSubclasses collect: [:arrayClass |
+ 		(arrayClass includesSelector: #contentType) ifTrue: [
+ 		[arrayClass new contentType setArrayClass: arrayClass]
+ 			on: Error do: [ "Ignore." ]]].
- 		[ArrayClasses at: arrayClass new contentType ifAbsentPut: arrayClass]
- 			on: Error do: [ "Ignore." ]].
  	String allSubclasses collect: [:stringClass | | contentType |
  		[ contentType := stringClass new contentType.
+ 		contentType asUnsigned setArrayClass: stringClass.
+ 		contentType asSigned setArrayClass: stringClass ]
- 		ArrayClasses at: contentType asUnsigned ifAbsentPut: stringClass.
- 		ArrayClasses at: contentType asSigned ifAbsentPut: stringClass ]
  			on: Error do: [ "Ignore."]].!

Item was changed:
  ----- Method: ExternalType class>>resetAllTypes (in category 'housekeeping') -----
  	"DANGEROUS!! Only do this if you think that your image is in an inconsistent state. You must not actively use FFI (i.e., have instances of external structures or external data) while calling this."
  	ExternalTypePool nukeAll.
  	AtomicTypeCodes := nil.
  	AtomicTypes := nil.
  	StructTypes := nil.
  	ArrayTypes := nil.
- 	ArrayClasses := nil.
  	self initialize.
  	self recompileAllLibraryFunctions.!

Item was changed:
  ----- Method: ExternalType>>allocateArrayClass: (in category 'external data') -----
  allocateArrayClass: numElements
  	"Allocate space for containing an array of numElements of this dataType. Try to use an array class. Answer 'nil' if there is no such class for the receiver."
+ 	^ arrayClass ifNotNil: [arrayClass new: numElements]!
- 	^ ArrayClasses
- 		at: self
- 		ifPresent: [:arrayClass | arrayClass new: numElements]
- 		ifAbsent: [nil]
- !

Item was added:
+ ----- Method: ExternalType>>arrayClass (in category 'accessing') -----
+ arrayClass
+ 	^ arrayClass!

Item was added:
+ ----- Method: ExternalType>>setArrayClass: (in category 'private') -----
+ setArrayClass: class
+ 	arrayClass := class.!

Item was changed:
+ (PackageInfo named: 'FFI-Kernel') postscript: '"Update for array classes."
+ ExternalType initialize.'!
- (PackageInfo named: 'FFI-Kernel') postscript: '"Update for generated type accessors."
- ExternalType initialize..'!

More information about the Squeak-dev mailing list