[Vm-dev] VM Maker: VMMaker.oscog-djm.682.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Apr 20 01:02:31 UTC 2014


Douglas McPherson uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-djm.682.mcz

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

Name: VMMaker.oscog-djm.682
Author: djm
Time: 19 April 2014, 5:59:52.572 pm
UUID: e7def840-4cc1-464d-a20e-29498ae5a99a
Ancestors: VMMaker.oscog-eem.681

ThreadedARMFFIPlugin
- make progress on passing and returning structs but there are still outstanding bugs
- 22/23 existing FFI tests pass, but there are many new tests yet to include to stress combined register and stack usage for parameter passing

=============== Diff against VMMaker.oscog-eem.681 ===============

Item was changed:
  ----- Method: ThreadedARMFFIPlugin>>dispatchFunctionPointer:with:with:with:with: (in category 'callout support') -----
  dispatchFunctionPointer: aFunctionPointer with: int1 with: int2 with: int3 with: int4
  	"In C aFunctionPointer is void (*aFunctionPointer)(int, int, int, int)"
  	<cmacro: '(aFunctionPointer, int1, int2, int3, int4) (aFunctionPointer)(int1, int2, int3, int4)'>
+ 	^self 
+ 		perform: aFunctionPointer
+ 		with: int1
+ 		with: int2
+ 		with: int3
+ 		with: int4!
- 	^self perform: aFunctionPointer!

Item was changed:
  ----- Method: ThreadedARMFFIPlugin>>ffiCalloutTo:SpecOnStack:in: (in category 'callout support') -----
  ffiCalloutTo: procAddr SpecOnStack: specOnStack in: calloutState
  	<var: #procAddr type: #'void *'>
  	<var: #calloutState type: #'CalloutState *'>
  	"Go out, call this guy and create the return value.  This *must* be inlined because of
  	 the alloca of the outgoing stack frame in ffiCall:WithFlags:NumArgs:Args:AndTypes:"
  	| myThreadIndex atomicType floatRet intRet |
  	<var: #floatRet type: #double>
  	<var: #intRet type: #usqLong>
  	<inline: true>
  	self cppIf: COGMTVM ifTrue:
  	[(calloutState callFlags anyMask: FFICallFlagThreaded) ifTrue:
  		[myThreadIndex := interpreterProxy disownVM: 0]].
  
- 	self msg: 'calling out to C function'.
- 
  	self registerArgsSlop + self cStackAlignment > 0 ifTrue:
  		[self setsp: calloutState argVector].
  
  	calloutState floatRegisterIndex > 0
  		ifTrue:
  			[self 
  				dummyFloatFunction: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 0)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 2)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 4)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 6)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 8)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 10)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 12)) to: 'double *') at: 0)
  				with: ((self cCoerceSimple: (self addressOf: (calloutState floatRegisters at: 14)) to: 'double *') at: 0)
  			].
  
  	atomicType := self atomicTypeOf: calloutState ffiRetHeader.
  	atomicType = FFITypeSingleFloat
  		ifTrue:
  			[floatRet := self 
  				dispatchFunctionPointer: (self cCoerceSimple: procAddr to: 'float (*)(int, int, int, int)') 
  				with: (calloutState integerRegisters at: 0)
  				with: (calloutState integerRegisters at: 1)
  				with: (calloutState integerRegisters at: 2)
  				with: (calloutState integerRegisters at: 3)].
  	 atomicType = FFITypeDoubleFloat
  		ifTrue:
  			[floatRet := self 
  				dispatchFunctionPointer: (self cCoerceSimple: procAddr to: 'double (*)(int, int, int, int)') 
  				with: (calloutState integerRegisters at: 0)
  				with: (calloutState integerRegisters at: 1)
  				with: (calloutState integerRegisters at: 2)
  				with: (calloutState integerRegisters at: 3)]
  		ifFalse:
  			[intRet := self 
  				dispatchFunctionPointer: (self cCoerceSimple: procAddr to: 'usqLong (*)(int, int, int, int)') 
  				with: (calloutState integerRegisters at: 0)
  				with: (calloutState integerRegisters at: 1)
  				with: (calloutState integerRegisters at: 2)
  				with: (calloutState integerRegisters at: 3)].
  	"undo any callee argument pops because it may confuse stack management with the alloca."
  	(self isCalleePopsConvention: calloutState callFlags) ifTrue:
  		[self setsp: calloutState argVector].
  
  	self cppIf: COGMTVM ifTrue:
  	[(calloutState callFlags anyMask: FFICallFlagThreaded) ifTrue:
  		[interpreterProxy ownVM: myThreadIndex]].
  
  	"Note: Order is important here since FFIFlagPointer + FFIFlagStructure is used to represent
  	 'typedef void* VoidPointer' and VoidPointer must be returned as pointer *not* as struct."
  	(calloutState ffiRetHeader anyMask: FFIFlagPointer) ifTrue:
  		[^self ffiReturnPointer: intRet ofType: (self ffiReturnType: specOnStack) in: calloutState].
  
  	(calloutState ffiRetHeader anyMask: FFIFlagStructure) ifTrue:
  		[^self ffiReturnStruct: intRet ofType: (self ffiReturnType: specOnStack) in: calloutState].
  	
  	(atomicType = FFITypeSingleFloat
  	 or: [atomicType = FFITypeDoubleFloat]) ifTrue:
  		[^interpreterProxy methodReturnValue: (interpreterProxy floatObjectOf: floatRet)].
  
  	^interpreterProxy methodReturnValue: (self ffiCreateIntegralResultOop: intRet
  												ofAtomicType: atomicType
  												in: calloutState)!

Item was changed:
  ----- Method: ThreadedARMFFIPlugin>>ffiPushStructure:ofSize:typeSpec:ofLength:in: (in category 'marshalling') -----
  ffiPushStructure: pointer ofSize: structSize typeSpec: argSpec ofLength: argSpecSize in: calloutState
  	<var: #pointer type: #'void *'>
  	<var: #argSpec type: #'sqInt *'>
  	<var: #calloutState type: #'CalloutState *'>
  	<inline: true>
+ 	| availableRegisterSpace stackPartSize roundedSize |
+ 
+ 	availableRegisterSpace := (NumIntRegArgs - calloutState integerRegisterIndex) * 4.
+ 	stackPartSize := structSize.
+ 	availableRegisterSpace > 0
+ 		ifTrue: 
+ 			[structSize <= availableRegisterSpace
+ 				ifTrue:
+ 					["all in registers"
+ 					 stackPartSize = 0.
+ 					 self 
+ 						mem: (self cCoerceSimple: (self addressOf: (calloutState integerRegisters at: calloutState integerRegisterIndex)) to: 'void *') 
+ 						cp: pointer 
+ 						y: structSize.
+ 					 calloutState integerRegisterIndex: calloutState integerRegisterIndex + (structSize + 3 bitShift: -2) ]
+ 				ifFalse:
+ 					["some in registers rest on stack"
+ 					 stackPartSize := structSize - availableRegisterSpace.
+ 					 self 
+ 						mem: (self cCoerceSimple: (self addressOf: (calloutState integerRegisters at: calloutState integerRegisterIndex)) to: 'void *') 
+ 						cp: pointer 
+ 						y: availableRegisterSpace.
+ 					 calloutState integerRegisterIndex: NumIntRegArgs]].
+ 
+ 	stackPartSize > 0
+ 		ifTrue: 
+ 			[roundedSize := stackPartSize + 3 bitClear: 3.
+ 			 calloutState currentArg + roundedSize > calloutState limit ifTrue:
+ 				 [^FFIErrorCallFrameTooBig].
+ 			 self mem: calloutState currentArg cp: (self addressOf: ((self cCoerceSimple: pointer to: 'char *') at: availableRegisterSpace)) y: stackPartSize.
+ 			 calloutState currentArg: calloutState currentArg + roundedSize].
+ 
- 	self shouldBeImplemented.
  	^0!

Item was removed:
- ----- Method: ThreadedARMFFIPlugin>>ffiPushUnsignedLong:in: (in category 'marshalling') -----
- ffiPushUnsignedLong: value in: calloutState
- 	<var: #calloutState type: #'CalloutState *'>
- 	<inline: true>
- 	self shouldBeImplemented.
- 	^0!

Item was changed:
  ----- Method: ThreadedARMFFIPlugin>>returnStructInRegisters: (in category 'marshalling') -----
  returnStructInRegisters: returnStructSize
  	"Answer if a struct result of a given size is returned in memory or not."
+ 	^returnStructSize <= 4!
- 	^false!



More information about the Vm-dev mailing list