Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1054.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.1054 Author: eem Time: 11 February 2015, 1:20:01.475 pm UUID: 3d511797-53fc-4848-b1ec-4b8a1eb0c0ff Ancestors: VMMaker.oscog-eem.1053 Broaden primitiveBitAnd and primitiveBitOr for Spur 64-bits. Make the bytecodes handle the common SmallInteger op SmallInteger case. Fix C code for and endianness under simulation of Spur64BitMemoryManager>>fetchLong32:ofFloatObject: =============== Diff against VMMaker.oscog-eem.1053 =============== Item was changed: ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category 'arithmetic integer primitives') ----- primitiveBitAnd + <inline: false> | integerReceiver integerArgument | + integerArgument := self stackTop. + integerReceiver := self stackValue: 1. + "Comment out the short-cut. Either the inline interpreter bytecode or the JIT primitive will handle this case. + ((objectMemory isIntegerObject: integerArgument) + and: [objectMemory isIntegerObject: integerReceiver]) + ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd: integerReceiver)] + ifFalse: + ["objectMemory wordSize = 8 + ifTrue: + [integerArgument := self positive64BitValueOf: integerArgument. + integerReceiver := self positive64BitValueOf: integerReceiver. + self successful ifTrue: + [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]] + ifFalse: + [integerArgument := self positive32BitValueOf: integerArgument. + integerReceiver := self positive32BitValueOf: integerReceiver. + self successful ifTrue: + [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]"]"! - integerArgument := self popPos32BitInteger. - integerReceiver := self popPos32BitInteger. - self successful - ifTrue: [self push: (self positive32BitIntegerFor: - (integerReceiver bitAnd: integerArgument))] - ifFalse: [self unPop: 2]! Item was changed: ----- Method: InterpreterPrimitives>>primitiveBitOr (in category 'arithmetic integer primitives') ----- primitiveBitOr + <inline: false> | integerReceiver integerArgument | + integerArgument := self stackTop. + integerReceiver := self stackValue: 1. + "Comment out the short-cut. Either the inline interpreter bytecode or the JIT primitive will handle this case. + ((objectMemory isIntegerObject: integerArgument) + and: [objectMemory isIntegerObject: integerReceiver]) + ifTrue: [self pop: 2 thenPush: (integerArgument bitOr: integerReceiver)] + ifFalse: + ["objectMemory wordSize = 8 + ifTrue: + [integerArgument := self positive64BitValueOf: integerArgument. + integerReceiver := self positive64BitValueOf: integerReceiver. + self successful ifTrue: + [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]] + ifFalse: + [integerArgument := self positive32BitValueOf: integerArgument. + integerReceiver := self positive32BitValueOf: integerReceiver. + self successful ifTrue: + [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitOr: integerReceiver))]]"]"! - integerArgument := self popPos32BitInteger. - integerReceiver := self popPos32BitInteger. - self successful - ifTrue: [self push: (self positive32BitIntegerFor: - (integerReceiver bitOr: integerArgument))] - ifFalse: [self unPop: 2]! Item was changed: ----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') ----- fetchLong32: fieldIndex ofFloatObject: oop "index by word size, and return a pointer as long as the word size" | bits | (self isImmediateFloat: oop) ifFalse: [^self fetchLong32: fieldIndex ofObject: oop]. bits := self smallFloatBitsOf: oop. ^self + cCode: [(self cCoerceSimple: (self addressOf: bits) to: #'int *') at: fieldIndex] + inSmalltalk: + [self flag: #endian. + fieldIndex = 0 + ifTrue: [bits bitAnd: 16rFFFFFFFF] + ifFalse: [bits >> 32]]! - cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *') - + (fieldIndex << self shiftForWord)] - inSmalltalk: [self flag: #endian. - fieldIndex = 0 - ifTrue: [bits >> 32] - ifFalse: [bits bitAnd: 16rFFFFFFFF]]! Item was changed: ----- Method: StackInterpreter>>bytecodePrimBitAnd (in category 'common selector sends') ----- bytecodePrimBitAnd + | rcvr arg | + arg := self internalStackTop. + rcvr := self internalStackValue: 1. + ((objectMemory isIntegerObject: arg) + and: [objectMemory isIntegerObject: rcvr]) ifTrue: + [self internalPop: 2 thenPush: (arg bitAnd: rcvr). + ^self fetchNextBytecode "success"]. self initPrimCall. self externalizeIPandSP. self primitiveBitAnd. self internalizeIPandSP. + self successful ifTrue: + [^self fetchNextBytecode "success"]. - self successful ifTrue: [^ self fetchNextBytecode "success"]. messageSelector := self specialSelector: 14. argumentCount := 1. self normalSend! Item was changed: ----- Method: StackInterpreter>>bytecodePrimBitOr (in category 'common selector sends') ----- bytecodePrimBitOr + | rcvr arg | + arg := self internalStackTop. + rcvr := self internalStackValue: 1. + ((objectMemory isIntegerObject: arg) + and: [objectMemory isIntegerObject: rcvr]) ifTrue: + [self internalPop: 2 thenPush: (arg bitOr: rcvr). + ^self fetchNextBytecode "success"]. self initPrimCall. self externalizeIPandSP. self primitiveBitOr. self internalizeIPandSP. + self successful ifTrue: + [^self fetchNextBytecode "success"]. - self successful ifTrue: [^ self fetchNextBytecode "success"]. messageSelector := self specialSelector: 15. argumentCount := 1. self normalSend! |
If I reformulate: 2) this speed-up is already performed in interpreter special bytecode handling and/or in JIT1) there is a speed-up consisting in bitAnd'ing bitOr'ing the Oop (shifted integer value+tag) directly without need to decode anything when both are immediate SmallInteger 4) the primitive is there just in case the receiver and/or argument is a LargePositiveInteger outside immediate range, but still fitting in an unsigned long (32 or 64 bits) 2015-02-11 22:20 GMT+01:00 <[hidden email]>:
|
Hi Nicolas,
On Wed, Feb 11, 2015 at 2:05 PM, Nicolas Cellier <[hidden email]> wrote:
Right.
It wasn't, but it is now.
Right.
Not quite. While in normal execution the primitive will only be called if one or other of the receiver and argument is not a SmallInteger, the primitive will be called whenever the debugger executes bitAnd: or bitXor: since the simulation machinery invokes the primitive, rather than simulating the inlining of the special selectors.
best,
Eliot |
2015-02-11 23:14 GMT+01:00 Eliot Miranda <[hidden email]>:
OK, it's good to keep this case in mind... When debugging, I presume we can afford to be a tiny bit slower and allways decode/encode the SmallIntegers. Note that bitAnd'ing a positive SmallInteger with any LargeInteger (positive or not) will allways answer a SmallInteger... So we might create another optimization in the primitive for this case... Or
maybe it's too crooked ;)Similarly, bitAnd'ing a negative SmallInteger with any LargeInteger will never answer a SmallInteger.
|
In reply to this post by Eliot Miranda-2
On 11.02.2015, at 23:14, Eliot Miranda <[hidden email]> wrote:
Also, if those selectors are #performed (think proxies etc.), right? - Bert - smime.p7s (5K) Download Attachment |
Hi Bert,
|
Free forum by Nabble | Edit this page |