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

commits at source.squeak.org commits at source.squeak.org
Wed Aug 18 10:03:07 UTC 2021


Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.212.mcz

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

Name: FFI-Kernel-mt.212
Author: mt
Time: 18 August 2021, 12:03:05.687133 pm
UUID: 5bf6ded7-5f9b-de41-8c03-aeacd2620940
Ancestors: FFI-Kernel-mt.211

Fixes issue with updating alias-to-atomic types through #noticeModificationOf:.

Speeds up image startUp on platform changes.

Complements FFI-Tests-mt.62.

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

Item was added:
+ ----- Method: ExternalAtomicType>>newReferentClass: (in category 'private') -----
+ newReferentClass: classOrNil
+ 	"If I am an alias-to-atomic type, fetch the current spec from my referentClass."
+ 	
+ 	(referentClass := classOrNil)
+ 		ifNotNil: [ "my class has been changed - update my compiledSpec"
+ 			compiledSpec := referentClass compiledSpec.
+ 			byteAlignment := referentClass byteAlignment].!

Item was removed:
- ----- Method: ExternalStructure class>>platformChangedFrom:to: (in category 'system startup') -----
- platformChangedFrom: lastPlatform to: currentPlatform
- 	"The system is coming up on a new platform. Compile all field specs and install them in the respective struct types. Also re-generate all struct-field accessors if necessary."
- 	
- 	self defineAllFields.!

Item was removed:
- ----- Method: ExternalType class>>checkTypeIntegrity (in category 'housekeeping') -----
- checkTypeIntegrity
- 	"
- 	self initialize.
- 	self checkTypeIntegrity.
- 	"
- 	#(atomicTypesDo: atomic structTypesDo: struct pointerTypesDo: pointer arrayTypesDo: array typeAliasTypesDo: alias)
- 		groupsDo: [:enumerator :label |
- 			Transcript showln: ('Checking integrity of {1} types ...' format: { label }).
- 			self perform: enumerator with: [:type |
- 				type compiledSpec ifNil: [Transcript showln: '...', type typeName, ' has invalid compiledSpec!!'].
- 				type byteAlignment ifNil: [Transcript showln: '...', type typeName, ' has invalid byteAlignment!!']]].!

Item was added:
+ ----- Method: ExternalType class>>initializeArrayTypes (in category 'class initialization') -----
+ initializeArrayTypes
+ 	"Private. Initialize all array types that have an atomic-or-pointer type as their content type. Other array types will be updated through #initializeStructureTypes because of how #defineAllFields work with its callback to ExternalType class >> #noticeModificationOf:."
+ 
+ 	self allArrayTypesDo: [:arrayType |
+ 		(arrayType contentType isAtomic or: [arrayType contentType isPointerType]) ifTrue: [
+ 			arrayType newContentType: arrayType contentType]].!

Item was changed:
  ----- Method: ExternalType class>>initializeAtomicTypeCodes (in category 'class initialization') -----
  initializeAtomicTypeCodes
  	"ExternalType initializeAtomicTypeCodes"
  
+ 	FFIConstants initialize. "Init appropriate type codes for current plugin version."
+ 
  	AtomicTypeCodes := OrderedDictionary newFrom: {
  		#'void' -> FFITypeVoid.
  		#'bool' -> FFITypeBool.
  		
  		#'uint8_t' -> FFITypeUnsignedInt8.
  		#'int8_t' -> FFITypeSignedInt8.
  		#'uint16_t' -> FFITypeUnsignedInt16.
  		#'int16_t' -> FFITypeSignedInt16.
  		#'uint32_t' -> FFITypeUnsignedInt32.
  		#'int32_t' -> FFITypeSignedInt32.
  		#'uint64_t' -> FFITypeUnsignedInt64.
  		#'int64_t' -> FFITypeSignedInt64.
  		
  		#'uchar8_t' -> FFITypeUnsignedChar8.
  		#'char8_t' -> FFITypeSignedChar8.
  		#'uchar16_t' -> FFITypeUnsignedChar16.
  		#'char16_t' -> FFITypeSignedChar16.
  		#'uchar32_t' -> FFITypeUnsignedChar32.
  		#'char32_t' -> FFITypeSignedChar32.
  		
  		#'float' -> FFITypeSingleFloat.
  		#'double' -> FFITypeDoubleFloat}.
  	
  	"We must now update the names of all known atomic types."
  	AtomicTypes ifNotNil: [
  		AtomicTypes keys do: [:oldName |
  			| type newName |
  			type := AtomicTypes at: oldName.
  			newName := AtomicTypeCodes keyAtValue: type atomicType.
  			(AtomicTypes includesKey: newName) ifFalse: [
  				"Only store new names. Do not support name swap."
  				AtomicTypes removeKey: oldName.
  				AtomicTypes at: newName put: type.
  				type setAtomicTypeName: newName]]].!

Item was changed:
  ----- Method: ExternalType class>>initializeAtomicTypes (in category 'class initialization') -----
  initializeAtomicTypes
+ 	"Private. (Re-)initialize all atomic types. Preserves object identity of all involved types. If the amount of types changed, use #resetAllAtomicTypes instead. Needs atomic-type codes to be initialized already."
- 	"(Re-)initialize all atomic types. Preserves object identity of all involved types. If the amount of types changed, use #resetAllAtomicTypes instead. Needs atomic-type codes to be initialized already."
  
  	self assert: [AtomicTypeCodes notNil].
  	self assert: [AtomicTypeCodes notEmpty].
  		
  	self basicInitializeAtomicTypes.
  	self invalidateAtomicTypes.
  	
  	ExternalAtomicType initializeAtomicTypes.
  	ExternalAtomicType initializeAtomicTypeCompanions.	
  	
  	self initializeAtomicSends.!

Item was added:
+ ----- Method: ExternalType class>>initializeFast (in category 'class initialization') -----
+ initializeFast
+ 	"Faster than #initialize. Update all atomic types for platform-specifc byte size and alignment. Also update struct and array types when they change due to changed atomics. NOTE THAT this cannot be used when atomic-type codes have changed!!"
+ 
+ 	ExternalAtomicType initializeAtomicTypes.
+ 	self initializeArrayTypes.
+ 	ExternalStructure defineAllChangedFields.!

Item was changed:
  ----- Method: ExternalType class>>initializeStructureTypes (in category 'class initialization') -----
  initializeStructureTypes
  	"(Re-)initialize all structure types and all array types. Preserves object identity of all involved types. If the amount of types changed, use #resetAllStructureTypes instead."
  
  	self basicInitializeStructureTypes.
  	self invalidateStructureTypes.
  	
  	"1) Initialize all array types that have an atomic-or-pointer type as their content type."
+ 	self initializeArrayTypes.
- 	self allArrayTypesDo: [:arrayType |
- 		(arrayType contentType isAtomic or: [arrayType contentType isPointerType]) ifTrue: [
- 			arrayType newContentType: arrayType contentType]].
  	
+ 	"2) Trigger #noticeModificationOf: callback to actually initialize all structure types. Since we invalidated all types, we cannot use #defineAllChangedFields. We rely on the #noticeModificationOf: callback."
- 	"2) Trigger #noticeModificationOf: callback to actually initialize all structure types."
  	ExternalStructure defineAllFields.
  
  	"Finally do some garbage collection."
  	self cleanupUnusedTypes.!

Item was changed:
  ----- Method: ExternalType class>>invalidateAtomicTypes (in category 'class initialization') -----
  invalidateAtomicTypes
+ 	"Invalidate all pure atomic types. Do not invalidate alias-to-atomic types here. See #invalidateStructureTypes."
  	
  	self atomicTypesDo: [:atomicType |
  		atomicType "asNonPointerType" invalidate.
  		atomicType asPointerType invalidate].!

Item was changed:
  ----- Method: ExternalType class>>invalidateStructureTypes (in category 'class initialization') -----
  invalidateStructureTypes
  
+ 	self typeAliasTypesDo: [:type | type isAtomic ifTrue: [
+ 		type "asNonPointerType" invalidate.
+ 		type asPointerType invalidate]].
+ 
  	self allStructTypesDo:[:structType |
  		structType "asNonPointerType" invalidate.
  		structType asPointerType invalidate].
  	
  	self allArrayTypesDo: [:arrayType |
  		arrayType "asNonPointerType" invalidate.
  		arrayType asPointerType invalidate].!

Item was changed:
  ----- Method: ExternalType class>>platformChangedFrom:to: (in category 'system startup') -----
  platformChangedFrom: lastPlatform to: currentPlatform
  	"Byte size or byte alignment for atomic types might be different on the new platform."
  	
+ 	lastPlatform pluginVersion = currentPlatform pluginVersion
+ 		ifTrue: [self initializeFast]
+ 		ifFalse: [self initialize "Slower but necessary for new type codes"].
- 	"0) For a different FFI plugin version, type-codes might have changed."
- 	lastPlatform pluginVersion ~= currentPlatform pluginVersion ifTrue: [
- 		FFIConstants initialize.
- 		self initializeAtomicTypeCodes].
- 
- 	"1) Update all atomic types for platform-specifc byte size and alignment."
- 	self initializeAtomicTypes.
  	
+ 	self flag: #todo. "mt: Update all critical aliases for atomic types, i.e., intptr_t, uintptr_t. But what about 'c_long' between 64-bit platforms?!!"
+ 	"lastPlatform wordSize ~= currentPlatform wordSize
+ 		ifTrue: [self recompileAllLibraryFunctions]."!
- 	"2) Discard all compiled specs for all structure types."
- 	self initializeStructureTypes.
- 	
- 	"3) Update all critical aliases for atomic types, i.e., intptr_t, uintptr_t. But what about 'c_long' between 64-bit platforms?!!"
- 	lastPlatform wordSize ~= currentPlatform wordSize
- 		ifTrue: [self recompileAllLibraryFunctions].!

Item was changed:
  ----- Method: FFIPlatformDescription class>>startUp: (in category 'system startup') -----
  startUp: resuming
  	"Notify all FFI classes about platform changes."
  
  	resuming ifTrue: [
  		LastPlatform in: [:lastPlatform | self newCurrent in: [:currentPlatform |
  			lastPlatform = currentPlatform
  				ifTrue: [
  					self flag: #discuss. "mt: Maybe add #platformResuming?"
+ 					ExternalAddress allBeNull ]
- 					ExternalAddress allBeNull.
- 					ExternalType cleanupUnusedTypes ]
  				ifFalse: [
  					LastPlatform := currentPlatform. "Update now. See #current."
+ 					{ ExternalAddress. ExternalType. ExternalPool. ExternalLibrary }
- 					{ ExternalAddress. ExternalType. ExternalStructure. ExternalPool. ExternalLibrary }
  						do: [:cls | cls
  							platformChangedFrom: lastPlatform
  							to: currentPlatform] ]]].
  		self checkFFIOnStartUp ifTrue: [self checkFFI]].!



More information about the Squeak-dev mailing list