<div dir="ltr">Hi Nicolas,<br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 11, 2015 at 2:05 PM, Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div dir="ltr"><div><div>If I reformulate:<br><br>1) 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<br></div></div></div></blockquote><div><br></div><div>Right.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>2) this speed-up is already performed in interpreter special bytecode handling and/or in JIT<br></div></div></div></blockquote><div><br></div><div>It wasn't, but it is now.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>3) so checking again in the primitive is a loss of time<br></div></div></blockquote><div><br></div><div>Right.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div></div>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)<br></div></blockquote><div><br></div><div>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.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"></div><div class="gmail_extra"><div class="gmail_quote">2015-02-11 22:20 GMT+01:00 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1054.mcz" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1054.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1054<br>
Author: eem<br>
Time: 11 February 2015, 1:20:01.475 pm<br>
UUID: 3d511797-53fc-4848-b1ec-4b8a1eb0c0ff<br>
Ancestors: VMMaker.oscog-eem.1053<br>
<br>
Broaden primitiveBitAnd and primitiveBitOr for Spur<br>
64-bits. Make the bytecodes handle the common<br>
SmallInteger op SmallInteger case.<br>
<br>
Fix C code for and endianness under simulation of<br>
Spur64BitMemoryManager>>fetchLong32:ofFloatObject:<br>
<br>
=============== Diff against VMMaker.oscog-eem.1053 ===============<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveBitAnd (in category 'arithmetic integer primitives') -----<br>
primitiveBitAnd<br>
+ <inline: false><br>
| integerReceiver integerArgument |<br>
+ integerArgument := self stackTop.<br>
+ integerReceiver := self stackValue: 1.<br>
+ "Comment out the short-cut. Either the inline interpreter bytecode or the JIT primitive will handle this case.<br>
+ ((objectMemory isIntegerObject: integerArgument)<br>
+ and: [objectMemory isIntegerObject: integerReceiver])<br>
+ ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd: integerReceiver)]<br>
+ ifFalse:<br>
+ ["objectMemory wordSize = 8<br>
+ ifTrue:<br>
+ [integerArgument := self positive64BitValueOf: integerArgument.<br>
+ integerReceiver := self positive64BitValueOf: integerReceiver.<br>
+ self successful ifTrue:<br>
+ [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]<br>
+ ifFalse:<br>
+ [integerArgument := self positive32BitValueOf: integerArgument.<br>
+ integerReceiver := self positive32BitValueOf: integerReceiver.<br>
+ self successful ifTrue:<br>
+ [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]"]"!<br>
- integerArgument := self popPos32BitInteger.<br>
- integerReceiver := self popPos32BitInteger.<br>
- self successful<br>
- ifTrue: [self push: (self positive32BitIntegerFor:<br>
- (integerReceiver bitAnd: integerArgument))]<br>
- ifFalse: [self unPop: 2]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveBitOr (in category 'arithmetic integer primitives') -----<br>
primitiveBitOr<br>
+ <inline: false><br>
| integerReceiver integerArgument |<br>
+ integerArgument := self stackTop.<br>
+ integerReceiver := self stackValue: 1.<br>
+ "Comment out the short-cut. Either the inline interpreter bytecode or the JIT primitive will handle this case.<br>
+ ((objectMemory isIntegerObject: integerArgument)<br>
+ and: [objectMemory isIntegerObject: integerReceiver])<br>
+ ifTrue: [self pop: 2 thenPush: (integerArgument bitOr: integerReceiver)]<br>
+ ifFalse:<br>
+ ["objectMemory wordSize = 8<br>
+ ifTrue:<br>
+ [integerArgument := self positive64BitValueOf: integerArgument.<br>
+ integerReceiver := self positive64BitValueOf: integerReceiver.<br>
+ self successful ifTrue:<br>
+ [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]<br>
+ ifFalse:<br>
+ [integerArgument := self positive32BitValueOf: integerArgument.<br>
+ integerReceiver := self positive32BitValueOf: integerReceiver.<br>
+ self successful ifTrue:<br>
+ [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitOr: integerReceiver))]]"]"!<br>
- integerArgument := self popPos32BitInteger.<br>
- integerReceiver := self popPos32BitInteger.<br>
- self successful<br>
- ifTrue: [self push: (self positive32BitIntegerFor:<br>
- (integerReceiver bitOr: integerArgument))]<br>
- ifFalse: [self unPop: 2]!<br>
<br>
Item was changed:<br>
----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') -----<br>
fetchLong32: fieldIndex ofFloatObject: oop<br>
"index by word size, and return a pointer as long as the word size"<br>
<br>
| bits |<br>
(self isImmediateFloat: oop) ifFalse:<br>
[^self fetchLong32: fieldIndex ofObject: oop].<br>
bits := self smallFloatBitsOf: oop.<br>
^self<br>
+ cCode: [(self cCoerceSimple: (self addressOf: bits) to: #'int *') at: fieldIndex]<br>
+ inSmalltalk:<br>
+ [self flag: #endian.<br>
+ fieldIndex = 0<br>
+ ifTrue: [bits bitAnd: 16rFFFFFFFF]<br>
+ ifFalse: [bits >> 32]]!<br>
- cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *')<br>
- + (fieldIndex << self shiftForWord)]<br>
- inSmalltalk: [self flag: #endian.<br>
- fieldIndex = 0<br>
- ifTrue: [bits >> 32]<br>
- ifFalse: [bits bitAnd: 16rFFFFFFFF]]!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>bytecodePrimBitAnd (in category 'common selector sends') -----<br>
bytecodePrimBitAnd<br>
+ | rcvr arg |<br>
+ arg := self internalStackTop.<br>
+ rcvr := self internalStackValue: 1.<br>
+ ((objectMemory isIntegerObject: arg)<br>
+ and: [objectMemory isIntegerObject: rcvr]) ifTrue:<br>
+ [self internalPop: 2 thenPush: (arg bitAnd: rcvr).<br>
+ ^self fetchNextBytecode "success"].<br>
<br>
self initPrimCall.<br>
self externalizeIPandSP.<br>
self primitiveBitAnd.<br>
self internalizeIPandSP.<br>
+ self successful ifTrue:<br>
+ [^self fetchNextBytecode "success"].<br>
- self successful ifTrue: [^ self fetchNextBytecode "success"].<br>
<br>
messageSelector := self specialSelector: 14.<br>
argumentCount := 1.<br>
self normalSend!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>bytecodePrimBitOr (in category 'common selector sends') -----<br>
bytecodePrimBitOr<br>
+ | rcvr arg |<br>
+ arg := self internalStackTop.<br>
+ rcvr := self internalStackValue: 1.<br>
+ ((objectMemory isIntegerObject: arg)<br>
+ and: [objectMemory isIntegerObject: rcvr]) ifTrue:<br>
+ [self internalPop: 2 thenPush: (arg bitOr: rcvr).<br>
+ ^self fetchNextBytecode "success"].<br>
<br>
self initPrimCall.<br>
self externalizeIPandSP.<br>
self primitiveBitOr.<br>
self internalizeIPandSP.<br>
+ self successful ifTrue:<br>
+ [^self fetchNextBytecode "success"].<br>
- self successful ifTrue: [^ self fetchNextBytecode "success"].<br>
<br>
messageSelector := self specialSelector: 15.<br>
argumentCount := 1.<br>
self normalSend!<br>
<br>
</blockquote></div><br></div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">best,<div>Eliot</div></div>
</div></div>