<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">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</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&#39;ing bitOr&#39;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&#39;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">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</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&gt;&gt;fetchLong32:ofFloatObject:<br>
<br>
=============== Diff against VMMaker.oscog-eem.1053 ===============<br>
<br>
Item was changed:<br>
  ----- Method: InterpreterPrimitives&gt;&gt;primitiveBitAnd (in category &#39;arithmetic integer primitives&#39;) -----<br>
  primitiveBitAnd<br>
+       &lt;inline: false&gt;<br>
        | integerReceiver integerArgument |<br>
+       integerArgument := self stackTop.<br>
+       integerReceiver := self stackValue: 1.<br>
+       &quot;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>
+                       [&quot;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))]]&quot;]&quot;!<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&gt;&gt;primitiveBitOr (in category &#39;arithmetic integer primitives&#39;) -----<br>
  primitiveBitOr<br>
+       &lt;inline: false&gt;<br>
        | integerReceiver integerArgument |<br>
+       integerArgument := self stackTop.<br>
+       integerReceiver := self stackValue: 1.<br>
+       &quot;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>
+                       [&quot;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))]]&quot;]&quot;!<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&gt;&gt;fetchLong32:ofFloatObject: (in category &#39;object access&#39;) -----<br>
  fetchLong32: fieldIndex ofFloatObject: oop<br>
        &quot;index by word size, and return a pointer as long as the word size&quot;<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: #&#39;int *&#39;) at: fieldIndex]<br>
+               inSmalltalk:<br>
+                       [self flag: #endian.<br>
+                        fieldIndex = 0<br>
+                               ifTrue: [bits bitAnd: 16rFFFFFFFF]<br>
+                               ifFalse: [bits &gt;&gt; 32]]!<br>
-               cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #&#39;char *&#39;)<br>
-                                                       + (fieldIndex &lt;&lt; self shiftForWord)]<br>
-               inSmalltalk: [self flag: #endian.<br>
-                                       fieldIndex = 0<br>
-                                               ifTrue: [bits &gt;&gt; 32]<br>
-                                               ifFalse: [bits bitAnd: 16rFFFFFFFF]]!<br>
<br>
Item was changed:<br>
  ----- Method: StackInterpreter&gt;&gt;bytecodePrimBitAnd (in category &#39;common selector sends&#39;) -----<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 &quot;success&quot;].<br>
<br>
        self initPrimCall.<br>
        self externalizeIPandSP.<br>
        self primitiveBitAnd.<br>
        self internalizeIPandSP.<br>
+       self successful ifTrue:<br>
+               [^self fetchNextBytecode &quot;success&quot;].<br>
-       self successful ifTrue: [^ self fetchNextBytecode &quot;success&quot;].<br>
<br>
        messageSelector := self specialSelector: 14.<br>
        argumentCount := 1.<br>
        self normalSend!<br>
<br>
Item was changed:<br>
  ----- Method: StackInterpreter&gt;&gt;bytecodePrimBitOr (in category &#39;common selector sends&#39;) -----<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 &quot;success&quot;].<br>
<br>
        self initPrimCall.<br>
        self externalizeIPandSP.<br>
        self primitiveBitOr.<br>
        self internalizeIPandSP.<br>
+       self successful ifTrue:<br>
+               [^self fetchNextBytecode &quot;success&quot;].<br>
-       self successful ifTrue: [^ self fetchNextBytecode &quot;success&quot;].<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>