Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3056.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3056 Author: eem Time: 5 September 2021, 6:36:28.446042 pm UUID: b1ccff9a-d6c7-455f-b22c-3dedf3116454 Ancestors: VMMaker.oscog-eem.3055
Oops; VMMaker.oscog-eem.3051 regressed primitiveSetOrHasIdentityHash; remember to convert from SmallInteger to inetger and validate the hash is in range.
FFTPlugin: mark primitives with FastCPrimitiveFlag & FastCPrimitiveAlignForFloatsFlag. Save a few cycles in marshalling.
=============== Diff against VMMaker.oscog-eem.3055 ===============
Item was changed: ----- Method: FFTPlugin>>loadFFTFrom: (in category 'private') ----- loadFFTFrom: fftOop | oop | + "N.B. no need to check for an object here because there is a guard in + slotSizeOf: and slotSizeOf: anImmediate = 0" interpreterProxy success: (interpreterProxy slotSizeOf: fftOop) >= 6. interpreterProxy failed ifTrue:[^false]. nu := interpreterProxy fetchInteger: 0 ofObject: fftOop. fftSize := interpreterProxy fetchInteger: 1 ofObject: fftOop.
oop := interpreterProxy fetchPointer: 2 ofObject: fftOop. sinTableSize := interpreterProxy stSizeOf: oop. sinTable := self checkedFloatPtrOf: oop.
oop := interpreterProxy fetchPointer: 3 ofObject: fftOop. permTableSize := interpreterProxy stSizeOf: oop. permTable := self checkedWordPtrOf: oop.
oop := interpreterProxy fetchPointer: 4 ofObject: fftOop. realDataSize := interpreterProxy stSizeOf: oop. realData := self checkedFloatPtrOf: oop.
oop := interpreterProxy fetchPointer: 5 ofObject: fftOop. imagDataSize := interpreterProxy stSizeOf: oop. imagData := self checkedFloatPtrOf: oop.
"Check assumptions about sizes" interpreterProxy success: (1 << nu = fftSize) & (fftSize // 4 + 1 = sinTableSize) & (fftSize = realDataSize) & (fftSize = imagDataSize) & (realDataSize = imagDataSize).
^interpreterProxy failed == false!
Item was changed: ----- Method: FFTPlugin>>permuteData (in category 'transforming') ----- permuteData | i end a b tmp | + <var: 'tmp' type: #float> - <var: #tmp type: 'float '> i := 0. end := permTableSize. [i < end] whileTrue: [a := (permTable at: i) - 1. b := (permTable at: i+1) - 1.
(a < realDataSize and:[b < realDataSize]) ifFalse:[^interpreterProxy success: false].
tmp := realData at: a. realData at: a put: (realData at: b). realData at: b put: tmp.
tmp := imagData at: a. imagData at: a put: (imagData at: b). imagData at: b put: tmp.
i := i + 2]!
Item was changed: ----- Method: FFTPlugin>>primitiveFFTPermuteData (in category 'primitives') ----- primitiveFFTPermuteData + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> + (self loadFFTFrom: (interpreterProxy stackValue: 0)) ifFalse:[^nil]. - | rcvr | - <export: true> - rcvr := interpreterProxy stackObjectValue: 0. - (self loadFFTFrom: rcvr) ifFalse:[^nil]. self permuteData. + interpreterProxy failed ifTrue: - interpreterProxy failed ifTrue:[ "permuteData went wrong. Do the permutation again -- this will restore the original order" + [self permuteData].! - self permuteData].!
Item was changed: ----- Method: FFTPlugin>>primitiveFFTScaleData (in category 'primitives') ----- primitiveFFTScaleData + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> + (self loadFFTFrom: (interpreterProxy stackValue: 0)) ifFalse:[^nil]. + self scaleData! - | rcvr | - <export: true> - rcvr := interpreterProxy stackObjectValue: 0. - (self loadFFTFrom: rcvr) ifFalse:[^nil]. - self scaleData.!
Item was changed: ----- Method: FFTPlugin>>primitiveFFTTransformData (in category 'primitives') ----- primitiveFFTTransformData + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> + | forward | - | rcvr forward | - <export: true> forward := interpreterProxy booleanValueOf: (interpreterProxy stackValue: 0). + (self loadFFTFrom: (interpreterProxy stackValue: 1)) ifFalse:[^nil]. - rcvr := interpreterProxy stackObjectValue: 1. - (self loadFFTFrom: rcvr) ifFalse:[^nil]. self transformData: forward. + interpreterProxy failed ifFalse: + [interpreterProxy pop: 1] "Leave rcvr on stack"! - interpreterProxy failed ifFalse:[ - interpreterProxy pop: 1. "Leave rcvr on stack" - ].!
Item was changed: ----- Method: FFTPlugin>>scaleData (in category 'transforming') ----- scaleData "Scale all elements by 1/n when doing inverse" | realN | + <var: 'realN' type: #float> - <var: #realN type: 'float '> fftSize <= 1 ifTrue:[^nil]. + realN := self cCoerce: (1.0 / (self cCoerce: fftSize to: #double)) to: #float. - realN := self cCoerce: (1.0 / (self cCoerce: fftSize to: 'double')) to: 'float'. 0 to: fftSize-1 do: [:i | realData at: i put: (realData at: i) * realN. imagData at: i put: (imagData at: i) * realN]!
Item was changed: ----- Method: FFTPlugin>>transformForward: (in category 'transforming') ----- transformForward: forward | lev lev1 ip theta realU imagU realT imagT i fftSize2 fftSize4 fftScale ii | + <var: 'realU' type: #float> + <var: 'realT' type: #float> + <var: 'imagU' type: #float> + <var: 'imagT' type: #float> - <var: #realU type:'float '> - <var: #realT type:'float '> - <var: #imagU type:'float '> - <var: #imagT type:'float '> fftSize2 := fftSize // 2. fftSize4 := fftSize // 4. 1 to: nu do: [:level | lev := 1 << level. lev1 := lev // 2. fftScale := fftSize // lev. 1 to: lev1 do: [:j | theta := j-1 * fftScale. "pi * (j-1) / lev1 mapped onto 0..n/2" theta < fftSize4 "Compute U, the complex multiplier for each level" ifTrue: [realU := sinTable at: sinTableSize - theta - 1. imagU := sinTable at: theta] ifFalse: [realU := 0.0 - (sinTable at: theta - fftSize4). imagU := sinTable at: fftSize2 - theta]. forward ifFalse: [imagU := 0.0 - imagU]. " Here is the inner loop... j to: n by: lev do: [:i | hand-transformed to whileTrue... " i := j. [i <= fftSize] whileTrue: [ip := i + lev1 - 1. ii := i-1. realT := ((realData at: ip) * realU) - ((imagData at: ip) * imagU). imagT := ((realData at: ip) * imagU) + ((imagData at: ip) * realU). realData at: ip put: (realData at: ii) - realT. imagData at: ip put: (imagData at: ii) - imagT. realData at: ii put: (realData at: ii) + realT. imagData at: ii put: (imagData at: ii) + imagT. i := i + lev]]].!
Item was changed: ----- Method: InterpreterPrimitives>>primitiveSetOrHasIdentityHash (in category 'object access primitives') ----- primitiveSetOrHasIdentityHash | hash oldHash thisReceiver isReceiverAClass | argumentCount = 0 ifTrue: [| hasHash | hasHash := (objectMemory isNonImmediate: self stackTop) and: [objectMemory hasIdentityHash: self stackTop]. ^self methodReturnBool: hasHash]. isReceiverAClass := false. argumentCount = 2 ifTrue: [| lastArg | lastArg := self stackTop. (objectMemory isIntegerObject: lastArg) ifTrue: "e.g. Symbol primitiveSetIdentityHashOf: aSymbol to: hash" [hash := lastArg. thisReceiver := self stackValue: 1] ifFalse: "anObject primitiveSetIdentityHash: hashValue isBehavior: boolean" [thisReceiver := self stackValue: 2. hash := self stackValue: 1. lastArg = objectMemory trueObject ifTrue: [isReceiverAClass := true] ifFalse: [lastArg = objectMemory falseObject ifFalse: [^self primitiveFailFor: PrimErrBadArgument]]]] ifFalse: "anObject primitiveSetIdentityHashTo: hash" [thisReceiver := self stackValue: 1. hash := self stackTop]. + ((objectMemory isIntegerObject: hash) + and: [((hash := objectMemory integerValueOf: hash) bitAnd: objectMemory maxIdentityHash) = hash]) ifFalse: - (objectMemory isIntegerObject: hash) ifFalse: [^self primitiveFailFor: PrimErrBadArgument]. (objectMemory isNonImmediate: thisReceiver) ifFalse: [^self primitiveFailFor: (thisReceiver = (self stackValue: argumentCount) ifTrue: [PrimErrBadReceiver] ifFalse: [PrimErrBadArgument])]. oldHash := objectMemory hashBitsOf: thisReceiver. objectMemory setHashBitsOf: thisReceiver to: hash. (isReceiverAClass and: [objectMemory hasSpurMemoryManagerAPI]) ifTrue: [objectMemory classAtIndex: hash put: thisReceiver. "this figures out if the index is ambiguous and fixes all the instances if needed" objectMemory allInstancesOf: thisReceiver]. self methodReturnInteger: oldHash!
vm-dev@lists.squeakfoundation.org