[Vm-dev] VM Maker: VMMaker.oscog-nice.1711.mcz
Eliot Miranda
eliot.miranda at gmail.com
Sat Mar 5 01:27:26 UTC 2016
Thanks Nicolas! And great that you found slips. The more eyes the merrier.
On Fri, Mar 4, 2016 at 5:24 PM, <commits at source.squeak.org> wrote:
>
> 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!
>
>
--
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160304/ee808409/attachment-0001.htm
More information about the Vm-dev
mailing list