[Vm-dev] VM Maker: VMMaker.oscog-nice.1711.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Mar 5 01:25:56 UTC 2016


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1711.mcz

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

Name: VMMaker.oscog-nice.1711
Author: nice
Time: 5 March 2016, 2:14:57.11 am
UUID: 9e7ba417-b6ed-4263-82f2-27ec641d8f30
Ancestors: VMMaker.oscog-eem.1709

3 minor fixes for type inference:
1) remove unecessary block argument assignment
2) infer type of allMask:
3) infer type of rem: instead of mod: (mod: does not exist)

Don't use cCode: pointer aliasing for storing/fetching float/double in FFI primitives.
Replace with a call to mem:cp:y:
- the first one is dangerous with modern C compilers
- while the second is optimized away (no call to memcpy)

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

Item was changed:
  ----- Method: FFIPlugin>>primitiveFFIDoubleAt (in category 'primitives') -----
  primitiveFFIDoubleAt
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #double>
- 	<var: #floatValue type:'double '>
  	byteOffset := interpreterProxy stackIntegerValue: 0.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 8.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: (self addressOf: floatValue) cp: addr y: (self sizeof: floatValue).
- 	self cCode:'((int*)(&floatValue))[0] = ((int*)addr)[0]'.
- 	self cCode:'((int*)(&floatValue))[1] = ((int*)addr)[1]'.
  	interpreterProxy pop: 2.
  	^interpreterProxy pushFloat: floatValue
  !

Item was changed:
  ----- Method: FFIPlugin>>primitiveFFIDoubleAtPut (in category 'primitives') -----
  primitiveFFIDoubleAtPut
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue floatOop |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #double>
- 	<var: #floatValue type:'double '>
  	floatOop := interpreterProxy stackValue: 0.
  	(interpreterProxy isIntegerObject: floatOop)
  		ifTrue:[floatValue := self cCoerce: (interpreterProxy integerValueOf: floatOop) to:'double']
  		ifFalse:[floatValue := self cCoerce: (interpreterProxy floatValueOf: floatOop) to:'double'].
  	byteOffset := interpreterProxy stackIntegerValue: 1.
  	rcvr := interpreterProxy stackObjectValue: 2.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 8.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: addr cp: (self addressOf: floatValue) y: (self sizeof: floatValue).
- 	self cCode:'((int*)addr)[0] = ((int*)(&floatValue))[0]'.
- 	self cCode:'((int*)addr)[1] = ((int*)(&floatValue))[1]'.
  	interpreterProxy pop: 3.
  	^interpreterProxy push: floatOop!

Item was changed:
  ----- Method: FFIPlugin>>primitiveFFIFloatAt (in category 'primitives') -----
  primitiveFFIFloatAt
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #float>
- 	<var: #floatValue type:'float '>
  	byteOffset := interpreterProxy stackIntegerValue: 0.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 4.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: (self addressOf: floatValue) cp: addr y: (self sizeof: floatValue).
- 	self cCode:'((int*)(&floatValue))[0] = ((int*)addr)[0]'.
  	interpreterProxy pop: 2.
  	^interpreterProxy pushFloat: floatValue!

Item was changed:
  ----- Method: FFIPlugin>>primitiveFFIFloatAtPut (in category 'primitives') -----
  primitiveFFIFloatAtPut
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue floatOop |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #float>
- 	<var: #floatValue type:'float '>
  	floatOop := interpreterProxy stackValue: 0.
  	(interpreterProxy isIntegerObject: floatOop)
  		ifTrue:[floatValue := self cCoerce: (interpreterProxy integerValueOf: floatOop) to:'float']
  		ifFalse:[floatValue := self cCoerce: (interpreterProxy floatValueOf: floatOop) to:'float'].
  	byteOffset := interpreterProxy stackIntegerValue: 1.
  	rcvr := interpreterProxy stackObjectValue: 2.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 4.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: addr cp: (self addressOf: floatValue) y: (self sizeof: floatValue).
- 	self cCode:'((int*)addr)[0] = ((int*)(&floatValue))[0]'.
  	interpreterProxy pop: 3.
  	^interpreterProxy push: floatOop!

Item was changed:
  ----- Method: IA32ABIPlugin>>primDoubleAt (in category 'primitives-accessing') -----
  primDoubleAt
  	"Answer the 64-bit double starting at the given byte offset (little endian)."
  	"<Alien> doubleAt: index <Integer> ^<Float>
  		<primitive: 'primDoubleAt' error: errorCode module: 'IA32ABI'>"
  	| byteOffset rcvr startAddr addr floatValue |
  	<export: true>
+ 	<var: #floatValue type: #double>
- 	<var: #floatValue type:'double '>
  
  	byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	(self index: byteOffset length: 8 inRange: rcvr) ifFalse:
  		[^interpreterProxy primitiveFailFor: PrimErrBadIndex].
  	(startAddr := self startOfData: rcvr) = 0 ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
  	addr := startAddr + byteOffset.
+ 	self mem: (self addressOf: floatValue) cp: addr y: (self sizeof: floatValue).
- 	self cCode:'((long *)(&floatValue))[0] = ((long *)addr)[0]; ((long *)(&floatValue))[1] = ((long *)addr)[1]'
- 		inSmalltalk: [floatValue := rcvr doubleAt: byteOffset].
  	interpreterProxy pop: 2.
  	^interpreterProxy pushFloat: floatValue!

Item was changed:
  ----- Method: IA32ABIPlugin>>primDoubleAtPut (in category 'primitives-accessing') -----
  primDoubleAtPut
  	"Store a double into 64 bits starting at the given byte offset (little endian)."
  	"<Alien> doubleAt: index <Integer> put: value <Float | Integer> ^<Float | Integer>
  		<primitive: 'primDoubleAtPut' error: errorCode module: 'IA32ABI'>"
  	| byteOffset rcvr startAddr addr valueOop floatValue |
  	<export: true>
  	<var: #floatValue type: #double>
  
  	valueOop := interpreterProxy stackValue: 0.
  	(interpreterProxy isIntegerObject: valueOop)
  		ifTrue:[floatValue := self cCoerce: (interpreterProxy integerValueOf: valueOop) to: #double]
  		ifFalse:[floatValue := self cCoerce: (interpreterProxy floatValueOf: valueOop) to: #double].
  	byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1.
  	rcvr := interpreterProxy stackObjectValue: 2.
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	(self index: byteOffset length: 8 inRange: rcvr) ifFalse:
  		[^interpreterProxy primitiveFailFor: PrimErrBadIndex].
  	(interpreterProxy isOopImmutable: rcvr) ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrNoModification].
  	(startAddr := self startOfData: rcvr) = 0 ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
  	addr := startAddr + byteOffset.
+ 	self mem: addr cp: (self addressOf: floatValue) y: (self sizeof: floatValue).
- 	self cCode:'((int*)addr)[0] = ((int*)(&floatValue))[0]'.
- 	self cCode:'((int*)addr)[1] = ((int*)(&floatValue))[1]'.
  	interpreterProxy methodReturnValue: valueOop!

Item was changed:
  ----- Method: IA32ABIPlugin>>primFloatAt (in category 'primitives-accessing') -----
  primFloatAt
  	"Answer the 32-bit float starting at the given byte offset (little endian)."
  	"<Alien> floatAt: index <Integer> ^<Float>
  		<primitive: 'primFloatAt' error: errorCode module: 'IA32ABI'>"
  	| byteOffset rcvr startAddr addr floatValue |
  	<export: true>
+ 	<var: #floatValue type: #float>
- 	<var: #floatValue type: 'float '>
  
  	byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	(self index: byteOffset length: 4 inRange: rcvr) ifFalse:
  		[^interpreterProxy primitiveFailFor: PrimErrBadIndex].
  	(startAddr := self startOfData: rcvr) = 0 ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
  	addr := startAddr + byteOffset.
+ 	self mem: (self addressOf: floatValue) cp: addr y: (self sizeof: floatValue).
- 	self cCode:'((long *)(&floatValue))[0] = ((long *)addr)[0]'
- 		inSmalltalk: [floatValue := rcvr floatAt: byteOffset].
  	interpreterProxy pop: 2.
  	^interpreterProxy pushFloat: floatValue!

Item was changed:
  ----- Method: IA32ABIPlugin>>primFloatAtPut (in category 'primitives-accessing') -----
  primFloatAtPut
  	"Store a float into 32 bits starting at the given byte offset (little endian)."
  	"<Alien> floatAt: index <Integer> put: value <Float | Integer> ^<Float | Integer>
  		<primitive: 'primFloatAtPut' error: errorCode module: 'IA32ABI'>"
  	| byteOffset rcvr startAddr addr valueOop floatValue |
  	<export: true>
  	<var: #floatValue type: #float>
  
  	valueOop := interpreterProxy stackValue: 0.
  	(interpreterProxy isIntegerObject: valueOop)
  		ifTrue:[floatValue := self cCoerce: (interpreterProxy integerValueOf: valueOop) to: #double]
  		ifFalse:[floatValue := self cCoerce: (interpreterProxy floatValueOf: valueOop) to: #double].
  	byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1.
  	rcvr := interpreterProxy stackObjectValue: 2.
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	(self index: byteOffset length: 4 inRange: rcvr) ifFalse:
  		[^interpreterProxy primitiveFailFor: PrimErrBadIndex].
  	(interpreterProxy isOopImmutable: rcvr) ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrNoModification].
  	(startAddr := self startOfData: rcvr) = 0 ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
  	addr := startAddr + byteOffset.
+ 	self mem: addr cp: (self addressOf: floatValue) y: (self sizeof: floatValue).
- 	self cCode:'((long *)addr)[0] = ((long *)(&floatValue))[0]'.
  	interpreterProxy methodReturnValue: valueOop!

Item was changed:
  ----- Method: TMethod>>addTypesFor:to:in: (in category 'type inference') -----
  addTypesFor: node to: typeSet in: aCodeGen
  	"Add the value tupes for the node to typeSet.
  	 Answer if any type was derived from an as-yet-untyped method, which allows us to abort
  	 inferReturnTypeFromReturnsIn: if the return type depends on a yet-to-be-typed method."
  	| expr |
  	expr := node.
  	[expr isAssignment or: [expr isStmtList]] whileTrue:
  		[expr isAssignment ifTrue:
  			[expr := expr variable].
  		 expr isStmtList ifTrue:
  			[expr := expr statements last]].
  	expr isSend ifTrue:
  		[(#(ifTrue: ifFalse: ifTrue:ifFalse: ifFalse:ifTrue:) includes: expr selector) ifTrue:
  			[^expr args
  				inject: false
  				into: [:asYetUntyped :block|
+ 					asYetUntyped | (self addTypesFor: block to: typeSet in: aCodeGen)]].
+ 		 (#(= ~= == ~~ < > <= >= anyMask: allMask: noMask:) includes: expr selector) ifTrue:
- 					asYetUntyped := asYetUntyped | (self addTypesFor: block to: typeSet in: aCodeGen)]].
- 		 (#(= ~= == ~~ < > <= >= anyMask: noMask:) includes: expr selector) ifTrue:
  			[typeSet add: #sqInt. ^false].
+ 		 (#(+ - * / // \\ rem: quo: bitAnd: bitClear: bitOr: bitXor: bitShift:) includes: expr selector) ifTrue:
- 		 (#(+ - * / // \\ mod: quo: bitAnd: bitClear: bitOr: bitXor: bitShift:) includes: expr selector) ifTrue:
  			[| types |
  			 types := Set new.
  			 self addTypesFor: expr receiver to: types in: aCodeGen.
  			 (types size = 1 and: [types anyOne last = $*]) ifTrue: "pointer arithmetic"
  				[typeSet add: types anyOne. ^false].
  			 self addTypesFor: expr args first to: types in: aCodeGen.
  			 types := aCodeGen harmonizeReturnTypesIn: types.
  			 types size = 2 ifTrue:
  				[(types includes: #double) ifTrue:
  					[typeSet add: #double. ^false].
  				 (types includes: #float) ifTrue:
  					[typeSet add: #float. ^false].
  				^false]. "don't know; leave unspecified."
  			types notEmpty ifTrue:
  				[typeSet add: types anyOne].
  			^false].
  		"Abort only for untyped methods that will be typed, but don't be phased by recursion."
  		 ^(aCodeGen returnTypeForSend: expr in: self)
  			ifNotNil: [:type| typeSet add: type. false]
  			ifNil: [(aCodeGen methodNamed: expr selector) notNil and: [expr selector ~~ selector]]].
  	expr isVariable ifTrue:
  		[(aCodeGen typeOfVariable: expr name)
  			ifNotNil: [:type| typeSet add: type]
  			ifNil: [typeSet add: (expr name = 'self'
  										ifTrue: [#void]
  										ifFalse: [#sqInt])]].
  	expr isConstant ifTrue:
  		[| val |
  		 val := expr value.
  		 val isInteger ifTrue:
  			[typeSet add: ((val >= 0 ifTrue: [val] ifFalse: [-1 - val]) highBit <= 32
  									ifTrue: [#sqInt]
  									ifFalse: [#sqLong])].
  		 (#(nil true false) includes: val) ifTrue:
  			[typeSet add: #sqInt].
  		 val isFloat ifTrue:
  			[typeSet add: #float]].
  	^false!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>primitiveFFIDoubleAt (in category 'primitives') -----
  primitiveFFIDoubleAt
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #double>
- 	<var: #floatValue type:'double '>
  	byteOffset := interpreterProxy stackIntegerValue: 0.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 8.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: (self addressOf: floatValue) cp: addr y: (self sizeof: floatValue).
- 	self cCode:'((int*)(&floatValue))[0] = ((int*)addr)[0]'.
- 	self cCode:'((int*)(&floatValue))[1] = ((int*)addr)[1]'.
  	interpreterProxy pop: 2.
  	^interpreterProxy pushFloat: floatValue
  !

Item was changed:
  ----- Method: ThreadedFFIPlugin>>primitiveFFIDoubleAtPut (in category 'primitives') -----
  primitiveFFIDoubleAtPut
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue floatOop |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #double>
- 	<var: #floatValue type:'double '>
  	floatOop := interpreterProxy stackValue: 0.
  	(interpreterProxy isIntegerObject: floatOop)
  		ifTrue:[floatValue := self cCoerce: (interpreterProxy integerValueOf: floatOop) to:'double']
  		ifFalse:[floatValue := self cCoerce: (interpreterProxy floatValueOf: floatOop) to:'double'].
  	byteOffset := interpreterProxy stackIntegerValue: 1.
  	rcvr := interpreterProxy stackObjectValue: 2.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 8.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: addr cp: (self addressOf: floatValue) y: (self sizeof: floatValue).
- 	self cCode:'((int*)addr)[0] = ((int*)(&floatValue))[0]'.
- 	self cCode:'((int*)addr)[1] = ((int*)(&floatValue))[1]'.
  	^interpreterProxy pop: 3 thenPush: floatOop!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>primitiveFFIFloatAt (in category 'primitives') -----
  primitiveFFIFloatAt
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #float>
- 	<var: #floatValue type:'float '>
  	byteOffset := interpreterProxy stackIntegerValue: 0.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 4.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: (self addressOf: floatValue) cp: addr y: (self sizeof: floatValue).
- 	self cCode:'((int*)(&floatValue))[0] = ((int*)addr)[0]'.
  	interpreterProxy pop: 2.
  	^interpreterProxy pushFloat: floatValue!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>primitiveFFIFloatAtPut (in category 'primitives') -----
  primitiveFFIFloatAtPut
  	"Return a (signed or unsigned) n byte integer from the given byte offset."
  	| byteOffset rcvr addr floatValue floatOop |
  	<export: true>
  	<inline: false>
+ 	<var: #floatValue type: #float>
- 	<var: #floatValue type:'float '>
  	floatOop := interpreterProxy stackValue: 0.
  	(interpreterProxy isIntegerObject: floatOop)
  		ifTrue:[floatValue := self cCoerce: (interpreterProxy integerValueOf: floatOop) to:'float']
  		ifFalse:[floatValue := self cCoerce: (interpreterProxy floatValueOf: floatOop) to:'float'].
  	byteOffset := interpreterProxy stackIntegerValue: 1.
  	rcvr := interpreterProxy stackObjectValue: 2.
  	interpreterProxy failed ifTrue:[^0].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: 4.
  	interpreterProxy failed ifTrue:[^0].
+ 	self mem: addr cp: (self addressOf: floatValue) y: (self sizeof: floatValue).
- 	self cCode:'((int*)addr)[0] = ((int*)(&floatValue))[0]'.
  	^interpreterProxy pop: 3 thenPush: floatOop!



More information about the Vm-dev mailing list