<div dir="ltr">Hi Bert,<div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 11, 2014 at 10:41 AM, Bert Freudenberg <span dir="ltr">&lt;<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><div style="word-wrap:break-word">On 11.08.2014, at 18:16, Clément Bera &lt;<a href="mailto:bera.clement@gmail.com" target="_blank">bera.clement@gmail.com</a>&gt; wrote:<br>
<div><br><blockquote type="cite"><div dir="ltr">2014-08-11 17:37 GMT+02:00 Bert Freudenberg <span dir="ltr">&lt;<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>&gt;</span>:<br><div class="gmail_extra">
<div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br>On 09.08.2014, at 00:46, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt; wrote:<br>



<br>
&gt; Hi All,<br>
&gt;<br>
&gt;     as part of the Newspeak infrastructure we use at Cadence I implemented multiple bytecode set support and a lifting of the limits in a method on the number of literals and the span of branches about two years ago.  This work involved adding a second interpretation to the bits in a method header, providing 16 bits of literal count.  This was done by moving the primitive number out of the method header and into an optional callPrimitive bytecode, being the first bytecode of methods that have primitives.<br>



&gt;<br>
&gt; Now in Spur I have the opportunity to use this expanded format for the exsting bytecode set as well.  The SqueakV3 set does not use bytecode 139, which is convenient to use for its callPrimitiveBytecode.  The advantage is that when and if a new bytecode set is added, as is planned for the Sista VMs, the VM will not have to test method headers to decide which format they&#39;re in, because there will only be one.<br>



<br>
Just curious: how does the VM know which bytecode set to use for a given method?<br>
<br></blockquote><div>A bit is set or not in the compiled method header.</div></div></div></div></blockquote><br></div><div>But Eliot wrote &quot;the VM will not have to test method headers&quot;?</div></div></blockquote>
<div><br></div><div>Right.  For a while the Newspeak VMs have supported two bytecode sets with two different header formats, the old format:</div><div><br></div><div><div>sign bit 0, header &gt;= 0:</div><div><span class="" style="white-space:pre">        </span>(index 0)<span class="" style="white-space:pre">                </span>9 bits:<span class="" style="white-space:pre">        </span>main part of primitive number   (#primitive)</div>
<div><span class="" style="white-space:pre">        </span>(index 9)<span class="" style="white-space:pre">                </span>8 bits:<span class="" style="white-space:pre">        </span>number of literals (#numLiterals)</div><div><span class="" style="white-space:pre">        </span>(index 17)<span class="" style="white-space:pre">                </span>1 bit:<span class="" style="white-space:pre">        </span>whether a large frame size is needed (#frameSize)</div>
<div><span class="" style="white-space:pre">        </span>(index 18)<span class="" style="white-space:pre">                </span>6 bits:<span class="" style="white-space:pre">        </span>number of temporary variables (#numTemps)</div><div><span class="" style="white-space:pre">        </span>(index 24)<span class="" style="white-space:pre">                </span>4 bits:<span class="" style="white-space:pre">        </span>number of arguments to the method (#numArgs)</div>
<div><span class="" style="white-space:pre">        </span>(index 28)<span class="" style="white-space:pre">                </span>1 bit:<span class="" style="white-space:pre">        </span>high-bit of primitive number (#primitive)</div><div><span class="" style="white-space:pre">        </span>(index 29)<span class="" style="white-space:pre">                </span>1 bit:<span class="" style="white-space:pre">        </span>flag bit, ignored by the VM  (#flag)</div>
<div><span class="" style="white-space:pre">        </span>(index 30/63)<span class="" style="white-space:pre">        </span>sign bit: 0 selects the Primary instruction set (#signFlag)</div><div>sign bit 1, header &lt; 0:</div><div><span class="" style="white-space:pre">        </span>(index 0)<span class="" style="white-space:pre">                </span>16 bits:<span class="" style="white-space:pre">        </span>number of literals (#numLiterals)</div>
<div><span class="" style="white-space:pre">        </span>(index 16)<span class="" style="white-space:pre">                </span>  1 bit:<span class="" style="white-space:pre">        </span>has primitive</div><div><span class="" style="white-space:pre">        </span>(index 17)<span class="" style="white-space:pre">                </span>  1 bit:<span class="" style="white-space:pre">        </span>whether a large frame size is needed (#frameSize)</div>
<div><span class="" style="white-space:pre">        </span>(index 18)<span class="" style="white-space:pre">                </span>  6 bits:<span class="" style="white-space:pre">        </span>number of temporary variables (#numTemps)</div><div><span class="" style="white-space:pre">        </span>(index 24)<span class="" style="white-space:pre">                </span>  4 bits:<span class="" style="white-space:pre">        </span>number of arguments to the method (#numArgs)</div>
<div><span class="" style="white-space:pre">        </span>(index 28)<span class="" style="white-space:pre">                </span>  2 bits:<span class="" style="white-space:pre">        </span>reserved for an access modifier (00-unused, 01-private, 10-protected, 11-public)</div>
<div><span class="" style="white-space:pre">        </span>(index 30/63)<span class="" style="white-space:pre">        </span>sign bit: 1 selects the Secondary instruction set (e.g. NewsqueakV4) (#signFlag)</div><div>i.e. the Secondary Bytecode Set expands the number of literals to 65535 by assuming a CallPrimitive bytecode.</div>
<div><br></div></div><div><br></div><div>So whenever the VM needed to know the numLiterals (e.g. the GC in visiting pointer fields in methods) it had to switch-hit:</div><div><br></div><div>StackInterpreter&gt;&gt;literalCountOfHeader: headerPointer</div>
<div><span class="" style="white-space:pre">        </span>&lt;api&gt;</div><div><span class="" style="white-space:pre">        </span>&quot;We support two method header formats, as selected by the sign flag.  Even if the VM only</div>
<div><span class="" style="white-space:pre">        </span> has one bytecode set, supporting teh two formats here allows for instantiating methods in</div><div><span class="" style="white-space:pre">        </span> the other format for testing, etc.&quot;</div>
<div><span class="" style="white-space:pre">        </span>^(self headerIndicatesAlternateBytecodeSet: headerPointer)</div><div><span class="" style="white-space:pre">                </span>ifTrue: [self literalCountOfAlternateHeader: headerPointer]</div>
<div><span class="" style="white-space:pre">                </span>ifFalse: [self literalCountOfOriginalHeader: headerPointer]</div><div><div><br></div><div>StackInterpreter&gt;&gt;headerIndicatesAlternateBytecodeSet: methodHeader</div>
<div><span class="" style="white-space:pre">        </span>&lt;api&gt;</div><div><span class="" style="white-space:pre">        </span>&lt;inline: true&gt;</div><div><span class="" style="white-space:pre">        </span>&quot;A negative header selects the alternate bytecode set.&quot;</div>
<div><span class="" style="white-space:pre">        </span>^methodHeader signedIntFromLong &lt; 0</div></div><div><br></div><div>It;s not a lot of work since the header has to be fetched anyway.  But it&#39;s complexity, and things should be as simple as possible but no simpler ;-)</div>
<div><br></div><div>So since Spur is a chance for a fresh start it seemed like a good time to move to a single method header format, while keepoing the ability to support multiple bytecode sets.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><div>Also, with a single bit, how can there be more than one alternative bytecode set?<br></div></div></blockquote><div><br></div><div>One could I suppose put bits in a bytecode, just like the primitive is encoded in a callPrimitive: bytecode.  But I don&#39;t like that.  Instead, if one needs more juts add another bit.  As described above there&#39;s room for a two bit field in the sign and flag bits combined.  </div>
<div><br></div><div>One might take the view that only one additional set is needed.  One can develop it, test it, then move to it by recompiling everything to it and switching.  e.g. a snapshot operation that flips the sign bit on save could simply move methods from one set to another.</div>
<div><br></div><div>However, if, as the Smalltalk-X folks do, one wants to directly support the bytecode of another language (java, python?) then having, say, 4 sets to choose from might be nice.</div><div><br></div><div>
Right now the pressing need is to support the Sista bytecode set.  Clément is making string progress and I&#39;ve implemented a fair ammount of the VM support.  We have the bytecode set defined, the inline primitives defined.  I&#39;ll leave it to Clément to describe the optimizer status.  In the VM we have the bytecode set implemented, the performance counters on conditional branches that call-back into the image when they trip, and the class trap bytecode, used to check that objects are of the required classes before entering unsafe optimized code.  That leaves the inlined primitives of which I&#39;ve implemented a handful of the simpler ones.  So we&#39;re on course to have a prototype by Christmas ;-)</div>
<div><br></div><div>At a later stage we&#39;ll add an OptimizedContext (which in the VM will have an associated new frame format) that will have a pointer stack (as the current Context does) and a byte stack for handling raw data such as floating-point.  The JIT will map (at least some) memory locations in the byte stack onto the floating-point registers for much improved floating-point performance.</div>
</div>-- <br>best,<div>Eliot</div>
</div></div>