<div dir="ltr"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jul 1, 2020 at 10:05 AM <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Eliot Miranda uploaded a new version of Compiler to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Compiler-eem.440.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Compiler-eem.440.mcz</a></blockquote><div><br></div><div>It's in tune ;-)  Vanessa, Clément, your proof-reading and/or editing is appreciated.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">==================== Summary ====================<br>
<br>
Name: Compiler-eem.440<br>
Author: eem<br>
Time: 1 July 2020, 10:05:10.178038 am<br>
UUID: a39848b4-1bc8-4b31-93f8-e4f343d1400b<br>
Ancestors: Compiler-mt.439<br>
<br>
Improve slightly the EncoderForSistaV1 class comment specifying the SistaV1 bytecode set in the light of recent discussion.<br>
<br>
=============== Diff against Compiler-mt.439 ===============<br>
<br>
Item was changed:<br>
  BytecodeEncoder subclass: #EncoderForSistaV1<br>
(excessive size, no diff calculated)<br></blockquote><div><br></div><div>EncoderForSistaV1 encodes a bytecode set for Smalltalk that lifts limits on the number of literals, branch distances, the number of temporary variables, and provides extended push integer and push character bytecodes.  The bytecode set also supports creating FullBlockClosures, closures whose method is separate from their home method's.  Bytecodes are ordered by length to make decoding easier.  Bytecodes marked with an * are extensible via a prefix extension bytecode.</div><div><br></div><div>N.B.  Extension bytecodes can only come before extensible bytecodes, and only if valid (one cannot extend a bytecode extensible by Ext A with an Ext B).  An extensible bytecode consumes (and zeros) its extension(s).  Hence the hidden implicit variables holding extensions are always zero except after a valid sequence of extension bytecodes.  The implication is that a bytecode interpreter should maintain the extension values in static variables initialized to zero at start-up, and live only from the start of a sequence of extension bytecodes to the end of the extended bytecode immediately following.</div><div><br></div><div>While the bytecode set lifts limits, it still assumes there are no more than 65535 literals (as of 2020 the CompiledCode header word imposes a 32,767 limit on number of literals), and no more than 256 stack slots (used for arguments, temporaries, and stack contents) in a Context.</div><div><br></div><div>EncoderForSistaV1 also includes an extended set of bytecodes for Sista, the Speculative Inlining Smalltalk Architecture, a project by Clément Bera and Eliot Miranda.  Scorch is an optimizer that exists in the Smalltalk image, /not/ in the VM,  and optimizes by substituting normal bytecoded methods by optimized bytecoded methods that may use special bytecodes for which the Cogit can generate faster code.  These bytecodes eliminate overheads such as bounds checks or polymorphic code (indexing Array, ByteArray, String etc).  But the bulk of the optimization performed is in inlining blocks and sends for the common path.  This bytecode set therefore differs from a normal Smalltalk set in providing a set of inlined primitives that do not validate their arguments that the compiler generates only when it can prove that the primitives' arguments are valid.</div><div><br></div><div>The basic scheme is that the Cogit generates code containing performance counters.  When these counters trip, a callback into the image is performed, at which point Scorch analyses some portion of the stack, looking at performance data for the methods on the stack, and optimises based on the stack and performance data.  Execution then resumes in the optimized code.</div><div><br></div><div>The Sista Cogit (e.g. SistaStackToRegisterMappingCogit) adds counters to conditional branches.  Each branch has an executed and a taken count.  On execution the executed count is decremented and if the count goes below zero the VM sends a message at a special index in the specialObjectsArray (as of writing, conditionalCounterTrippedOn:).  Then if the branch is taken the taken count is decremented.  The two counter values allow the Sista optimizer to collect basic block execution paths and to know what are the "hot" paths through execution that are worth agressively optimizing.  Since conditional branches are about 1/6 as frequent as sends, and since they can be used to determine the hot path through code, they are a better choice to count than, for example, method or block entry.</div><div><br></div><div>The VM provides a primitive that fills an Array with the state of the counters, and the state of each linked send in a method.  The optimizer obtains the branch and send data for a method via this primitive.</div><div><br></div><div>Instance Variables (inherited)</div><div><br></div><div>Here is the list of bytecodes.  An asterisk implies the bytecode takes either extA or extB extensions. Two asterisks imply it takes both extA and extB extensions.  A number in parentheses is a note.  See the notes at the end of the table.</div><div><br></div><div>1 Byte Bytecodes</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>code<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>(note)<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>binary<span class="gmail-Apple-tab-span" style="white-space:pre">                        </span>name</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>0-15<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>0000 iiii <span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>Push Receiver Variable #iiii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>16-31<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>0001 iiii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Push Literal Variable #iiii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>32-63<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>001 iiiii<span class="gmail-Apple-tab-span" style="white-space:pre">                             </span>Push Literal #iiiii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>64-71<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>01000 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Push Temp #iii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>72-75<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>010010 ii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Push Temp #ii + 8</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>76<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01001100<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push Receiver</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>77<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01001101<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push true</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>78<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01001110<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push false</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>79<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01001111<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push nil</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>80<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01010000<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push 0</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>81<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01010001<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push 1</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>82<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01010010<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Push thisContext, (then Extend B = 1 => push thisProcess)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>83<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01010011<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Duplicate Stack Top</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>84-87<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>010101 ii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>UNASSIGNED</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>88-91<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>010110 ii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Return Receiver/true/false/nil</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>92<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01011100<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Return top</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>93<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01011101<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>BlockReturn nil</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>94<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01011110<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>BlockReturn Top [* return from enclosing block N, N = Extend A, then jump by Ext B ]</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>95<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>01011111<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Nop</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>96-111<span class="gmail-Apple-tab-span" style="white-space:pre">                </span>0110 iiii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Send Arithmetic Message #iiii (+ - < > <= >= = ~= * / \\ @ bitShift: // bitAnd: bitOr:)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>112-119<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>01110 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Send Special Message #iii + 0 (at: at:put: size next nextPut: atEnd == class)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>120-127<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>01111 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Send Special Message #iii + 8 (~~ value value: do: new new: x y)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>128-143<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>1000 iiii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Send Literal Selector #iiii With 0 Argument</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>144-159<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>1001 iiii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Send Literal Selector #iiii With 1 Arguments</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>160-175<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>1010 iiii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Send Literal Selector #iiii With 2 Arguments</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>176-183<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>10110 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Jump iii + 1 (i.e., 1 through 8)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>184-191<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>10111 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Pop and Jump 0n True iii +1 (i.e., 1 through 8)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>192-199<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>11000 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Pop and Jump 0n False iii +1 (i.e., 1 through 8)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>200-207<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>11001 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Pop and Store Receiver Variable #iii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>208-215<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>11010 iii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>Pop and Store Temporary Variable #iii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>216<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11011000<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Pop Stack Top</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>217<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(5)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11011001<span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>Unconditional trap</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>218-219<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>1101101 i<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>UNASSIGNED</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>220-223<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>110111 ii<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>UNASSIGNED</div><div><br></div><div>2 Byte Bytecodes</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>224<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100000<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>aaaaaaaa<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Extend A (Ext A = Ext A prev * 256 + Ext A) A is an unsigned extension.</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>225<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100001<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>bbbbbbbb<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Extend B (Ext B = Ext B prev * 256 + Ext B) B is a signed extension.</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>226<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100010<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Receiver Variable #iiiiiiii (+ Extend A * 256)</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>227<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100011<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Literal Variable #iiiiiiii (+ Extend A * 256)</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>228<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100100<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Literal #iiiiiiii (+ Extend A * 256)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>229<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100101<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Temporary Variable #iiiiiiii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>230<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100110<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>UNASSIGNED (was pushNClosureTemps)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>231<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11100111<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>jkkkkkkk<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Push (Array new: kkkkkkk) (j = 0)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                                      </span>&<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>Pop kkkkkkk elements into: (Array new: kkkkkkk) (j = 1)</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>232<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11101000<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Integer #iiiiiiii (+ Extend B * 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, d=0, s=1)</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>233<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11101001<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Character #iiiiiiii (+ Extend B * 256)</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>234<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11101010<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiijjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Send Literal Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>235<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(1)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11101011<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiijjj<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>ExtendB < 64</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                                                </span>ifTrue: [Send To Superclass Literal Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments]</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                                             </span>ifFalse: [Send To Superclass of Stacked Class Literal Selector #iiiii (+ Extend A * 32) with jjj (+ (Extend B bitAnd: 63) * 8) Arguments]</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>236<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11101100<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>UNASSIGNED</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>237<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11101101<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Jump #iiiiiiii (+ Extend B * 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, d=0, s=1)</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>238<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(4)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11101110<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Pop and Jump 0n True #iiiiiiii (+ Extend B * 256, where Extend B >= 0)</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>239<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(4)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11101111<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Pop and Jump 0n False #iiiiiiii (+ Extend B * 256, where Extend B >= 0)</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>240<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(3)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11110000<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Pop and Store Receiver Variable #iiiiiii (+ Extend A * 256) </div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>241<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(3)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11110001<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Pop and Store Literal Variable #iiiiiiii (+ Extend A * 256) </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>242<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11110010<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Pop and Store Temporary Variable #iiiiiiii</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>243<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(3)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11110011<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Store Receiver Variable #iiiiiii (+ Extend A * 256) </div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>244<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(3)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11110100<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Store Literal Variable #iiiiiiii (+ Extend A * 256) </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>245<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11110110<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Store Temporary Variable #iiiiiiii</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>246-247<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>1111011 i<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>xxxxxxxx<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>UNASSIGNED</div><div><br></div><div>3 Byte Bytecodes</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>248<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(2)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11111000 <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>iiiiiiii<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>mssjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Call Primitive #iiiiiiii + (jjjjj * 256) </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                             </span>m=1 means inlined primitive, no hard return after execution. </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                         </span>ss defines the unsafe operation set used to encode the operations. </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                           </span>(ss = 0 means sista unsafe operations, ss = 01 means lowcode operations, other numbers are as yet used)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                                </span>Lowcode inlined primitives may have extensions.</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>249<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11111001 <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>xxxxxxxx<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>siyyyyyy<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Push Closure Compiled block literal index xxxxxxxx (+ Extend A * 256) numCopied yyyyyy receiverOnStack: s = 1 ignoreOuterContext: i = 1</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>250<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11111010 <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>eeiiikkk<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>jjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Closure Num Copied iii (+ExtA//16*8) Num Args kkk (+ ExtA\\16*8) BlockSize jjjjjjjj (+ExtB*256). ee = num extensions</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>251<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11111011 <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>kkkkkkkk<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>sjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Push Temp At kkkkkkkk In Temp Vector At: jjjjjjj, s = 1 implies remote inst var access instead of remote temp vector access </div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>252<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(3)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11111100 <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>kkkkkkkk<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>sjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Store Temp At kkkkkkkk In Temp Vector At: jjjjjjj s = 1 implies remote inst var access instead of remote temp vector access </div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>253<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(3)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11111101 <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>kkkkkkkk<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>sjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Pop and Store Temp At kkkkkkkk In Temp Vector At: jjjjjjj s = 1 implies remote inst var access instead of remote temp vector access</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>254<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(5)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11111110<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>kkkkkkkk<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>jjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>branch If Not Instance Of Behavior/Array Of Behavior literal kkkkkkkk (+ Extend A * 256, where Extend A >= 0) distance jjjjjjjj (+ Extend B * 256, where Extend B >= 0 and <= 127)</div><div>**<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>254<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>(5)<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>11111110<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>kkkkkkkk<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>jjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>branch If Instance Of Behavior/Array Of Behavior literal kkkkkkkk (+ Extend A * 256, where Extend A >= 0) distance jjjjjjjj (+ (Extend B bitAnd: 127) * 256, where Extend B >= 128 and <= 255)</div><div>*<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>255<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>11111111<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>xxxxxxxx<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>jjjjjjjj<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>UNASSIGNED</div><div><br></div><div>(1) Bytecode 235 is a super send bytecode that starts the lookup in the superclass of some class.  It has two forms, "normal" and "directed". In the normal form, the class is the value of the method's methodClassAssociation which must be the last literal.  In the directed form the class is the class on top of stack.</div><div><br></div><div>(2) The Call Primitive Bytecode (see below) specifies either a primitive in the primitive table (m=0) or an inlined primitive (m=1). Non-inlined primitives from the primitive table have index (jjjjjjj * 256) + iiiiiiii and return from the method if they succeed.  This bytecode is only valid as the first bytecode of a method.  Inline primitives have index (jjjjjjj * 256) + iiiiiiii, cannot fail, and do not return when they succeed, yielding a result (typically on top of stack after popping their arguments, but possibly in a byte data stack, for example for unboxed floating-point primitives).</div><div><br></div><div>(3) ExtB lowest bit implies no store check is needed, ExtB second bit implies the object may be a context, ExtB third bit implies no immutability/read-only check is needed, other bits in the extension are unused.</div><div><br></div><div>(4) ExtA = 1 implies no mustBeBoolean trampoline is needed, other bits in the extension are unused</div><div><br></div><div>(5) these are Scorch/Sista bytecodes generated by an optimizing compiler and not used in normal Smalltalk code.</div><div><br></div><div><br></div><div>The CallPrimitive bytecode is divided into two halves, those for normal primtiives, occurring at the beginning of a method, and those for inline primitives, anywhere within the body of a method.  This is a three byte bytecode, the first byte being 248, and the second byte being a big-endian 16-bit primitive index. If the top bit of the first byte of the primitive index is 1 then this is a normal primitive invocation.  If it is zero then the remaining 15 bits define 32k primitives, organized as four 8k "pages".  The first page is used for and reserved by the Sista optimizing compiler.  The second page is usd for and reserved by the Lowcode FFI marshalling primitive set.  The other two sets are unspecified and unused.</div><div><br></div><div>Here is the specification of the Sista unsafe instructions (unsafe operations, set 00). The lowcode set uses external specifications.</div><div>We sort the inline primitive operations by arity.  Nullary primitives occupy the 0-999 range. Unary primitives occupy the 1-1999 range, up until 8 args. 8191 instructions can be encoded in each unsafe operation set, instructions from 0 to 7 arguments can have 1000 different instructions each, while 8 args instructions can have 192 different instructions.</div><div><br></div><div>Sista defines the following inlined primitives (CallPrimitive iiiiiiii 100jjjjj, n = jjjjjiiiiiiii)</div><div>1000<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>class</div><div>1001<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>pointer numSlots</div><div>1002<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>pointer basicSize</div><div>1003<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>byte8Type format numBytes (includes CompiledMethod)</div><div>1004<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>short16Type format numShorts</div><div>1005<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>word32Type format numWords</div><div>1006<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>doubleWord64Type format numDoubleWords</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span></div><div>1010<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>ensure number of bytes available.</div><div>1011<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>fixed-sized new. (objects with 0 to n inst vars)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span></div><div>1020 <span class="gmail-Apple-tab-span" style="white-space:pre">  </span>identityHash (non-immediate, non-Behavior)</div><div>1021<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>identityHash (SmallInteger)</div><div>1022<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>identityHash (Character)</div><div>1023<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>identityHash (SmallFloat64)</div><div>1024<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>identityHash (Behavior, has hash?)</div><div><br></div><div>1030 <span class="gmail-Apple-tab-span" style="white-space:pre">       </span>immediateAsInteger (Character)</div><div>1031 <span class="gmail-Apple-tab-span" style="white-space:pre">    </span>immediateAsInteger (SmallFloat64)</div><div>1035 <span class="gmail-Apple-tab-span" style="white-space:pre"> </span>immediateAsFloat <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>(Smallinteger)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span></div><div>2000<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>SmallInteger #+.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2001<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>SmallInteger #-.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2002<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>SmallInteger #*.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2003<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>SmallInteger #/.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2004<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>SmallInteger #//.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2005<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>SmallInteger #\\.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2006<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>SmallInteger #quo:.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div><br></div><div>2011<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>Variable-sized pointers new (new:). Array, etc.</div><div>2012<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Variable-sized byte new (new:). ByteArray, ByteString, etc.</div><div>2013<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>Variable-sized 16-bit new (new:). DoubleByteArray, etc.</div><div>2014<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Variable-sized 32-bit new (new:). Bitmap, FloatArray, etc.</div><div>2015<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>Variable-sized 64-bit new (new:). DoubleWordArray, etc.</div><div><br></div><div>2016<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>SmallInteger #bitAnd:.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2017<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>SmallInteger #bitOr:.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2018<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>SmallInteger #bitXor:.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2019<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>SmallInteger #bitShiftLeft:.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div>2020<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>SmallInteger #bitShiftRight:.  Both arguments are SmallIntegers and the result fits in a SmallInteger (* depends on word size)</div><div><br></div><div>2032<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>SmallInteger #>.  Both arguments are SmallIntegers</div><div>2033<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>SmallInteger #<.  Both arguments are SmallIntegers</div><div>2034<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>SmallInteger #>=.  Both arguments are SmallIntegers</div><div>2035<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>SmallInteger #<=.  Both arguments are SmallIntegers</div><div>2036<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>SmallInteger #=.  Both arguments are SmallIntegers</div><div>2037<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>SmallInteger #~=.  Both arguments are SmallIntegers</div><div><br></div><div>2064<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Pointer Object>>at:.<span class="gmail-Apple-tab-span" style="white-space:pre">            </span>The receiver is guaranteed to be a pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger</div><div>2065<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>Byte Object>>at:.<span class="gmail-Apple-tab-span" style="white-space:pre">                       </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The result is a SmallInteger.</div><div>2066<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>16-bit Word Object>>at:.<span class="gmail-Apple-tab-span" style="white-space:pre">                        </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The result is a SmallInteger.</div><div>2067<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>32-bit DoubleWord Object>>at:.<span class="gmail-Apple-tab-span" style="white-space:pre">                  </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The result is a SmallInteger or a LargePositiveInteger.</div><div>2068<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>64-bit QuadWord Object>>at:.<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The result is a SmallInteger or a LargePositiveInteger.</div><div><br></div><div>The following instructions can have the ExtB check flag (See (3)).</div><div>3000<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>Pointer Object>>at:put:.<span class="gmail-Apple-tab-span" style="white-space:pre">                        </span>The receiver is guaranteed to be a pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger</div><div>3001<span class="gmail-Apple-tab-span" style="white-space:pre">        </span>Byte Object>>at:put:.<span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The argument is a SmallInteger.  The primitive stores the least significant 8 bits.</div><div>3002<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Word Object>>at:put:.<span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The argument is a SmallInteger.  The primitive stores the least significant 16 bits.</div><div>3003<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>DoubleWord Object>>at:put:.<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The argument is a SmallInteger.  The primitive stores the least significant 32 bits.</div><div>3004<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>QuadWord Object>>at:put:.<span class="gmail-Apple-tab-span" style="white-space:pre">               </span>The receiver is guaranteed to be a non-pointer object.  The 0-relative (1-relative?) index is an in-range SmallInteger.  The argument is a SmallInteger.  The primitive stores the least significant 64 bits.</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                       </span></div><div>3021<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>Byte Object >> equals:length:<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>The receiver and the arguments are both byte objects and have both the same size (length). The length argument is a smallinteger. Answers true if all fields are equal, false if not. Comparison is bulked to word comparison.</div><div><br></div><div>4000<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Pointer Object>> fillFrom:to:with: The receiver is a Pointer object. the middle two arguments are smallintegers. Last argument is any object. Fills the object in between the two indexes with last argument. Receiver is guaranteed to be mutable. The pointer accesses are raw (no inst var check). If ExtB is set to 1, no store check is present. Else a single store check is done for the bulk operation. Answers the receiver.</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span></div><div>5000<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>Pointer Object>> replaceFrom:to:with:startingAt: Src and dest are pointer objects. ScrPos, scrLast and destLast are smallintegers. Receiver is guaranteed to be mutable.  Both ranges are in-bounds. The pointer accesses are raw (no inst var check). As for the normal primitive, the copy is linear. Answers the receiver.</div><div><br></div><div><br></div><div>Lowcode defines inlined primitives for the range CallPrimitive iiiiiiii 101jjjjj, n = jjjjjiiiiiiii. </div></div><br clear="all"><div><br></div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div></div>