<br><br><div class="gmail_quote">On Wed, Nov 19, 2008 at 2:43 PM, Michael van der Gulik <span dir="ltr"><<a href="mailto:mikevdg@gmail.com">mikevdg@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><br><div class="gmail_quote"><div><div></div><div class="Wj3C7c">On Thu, Nov 20, 2008 at 11:33 AM, Michael van der Gulik <span dir="ltr"><<a href="mailto:mikevdg@gmail.com" target="_blank">mikevdg@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
<br><br><div class="gmail_quote"><div>On Mon, Nov 17, 2008 at 4:11 PM, Igor Stasenko <span dir="ltr"><<a href="mailto:siguctua@gmail.com" target="_blank">siguctua@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
<div><div><br>
<br>
</div></div>The only cause of this can be compiler.<br>
Instead of generating an instruction for sending #class message, it<br>
generates a bytecode to fetch the class from receiver oop , instead of<br>
sending real message.<br>
</blockquote></div><div><br>Yes, the Compiler and Smalltalk bytecode set is doing this. I need this change too at some stage, so I've spent some time on it.<br><br>See this: <a href="http://users.ipa.net/%7Edwighth/smalltalk/bluebook/bluebook_chapter28.html" target="_blank">http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_chapter28.html</a><br>
</div></div><br>The send bytecode in question is decimal 199. This pushes the receiver's class on the stack, no questions asked.<br><br>I've looked at modifying the compiler, but I'm finding it to be a daunting piece of software.<br>
<br>The send bytecode is written to the compiled method stream in SelectorNode>>emit:args:on:super: at the top of the method as a "short send". <br><br>The SelectorNode instance is initialised as a shared class variable called "StdSelectors" in VariableNode>>initialize. As you can see there, its values are retrieved from the SystemDictionary. Once initialised as a class variable, it is again copied in Encoder>>initScopeAndLiteralTables.<br>
<br>So the special selectors array lives in the SystemDictionary's special objects array in slot 24, meaning that the VM also refers to these selectors. I'm not sure why the VM wants them.<br><br>As with fixing this, I guess that replacing the value in the special selectors array and then running VariableNode>>initialize might do the trick. Or it might crash the VM.<br>
<font color="#888888"></font></blockquote></div></div><div><br><br>...which worked!<br><br>To make #class a normal message send, do this:<br><br>Inspect "Smalltalk specialObjectsArray".<br>Find item 24, inspect it. This should be the special selectors array, but it might not be.<br>
Find item 47 in the special objects array. It should be "#class", but it might not be.<br>In the special objects array inspector, evaluate "self at: 47 put: #primitiveClass".<br>Evaluate "VariableNode initialize".<br>
</div></div><br>-- or --<br><br>Evaluate "(Smalltalk specialObjectsArray at: 24) at: 47 put: #primitiveClass"<br>(but that would be less fun)<br><br>and then recompile your code.<br><br>Why does the VM need access to this special selectors array?</blockquote>
<div><br></div><div>Read the blue book VM chapters (<a href="http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_imp_toc.html">http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_imp_toc.html</a>). The special selectors kill two birds with one stone.</div>
<div><br></div><div>a) they allow the VM to optimize certain sends to certain types (static type prediction). e.g. #+ compiles to bytecode 176 and this will add two integers or two floats or a float receiver and an integer without doing a send.</div>
<div><br></div><div>b) they save space in the literal frame because the selector isn't stored, instead it is implicit in the bytecode.</div><div><br></div><div>But if one of the special selector operations can't be handled inline (e.g. integer addition overflows, or you try and add a Fraction, or compare two strings, or...) or isn't handled inline (e.g. next, nextPut: etc) then the VM needs to send the message implied by the bytecode. It does that my accessing the selector (and perhaps the argument count)from the special selector array.</div>
<div><br></div><div>In VisualWorks there's an extended special selector scheme just to save space. (I'm proud of this because I suggested it to Peter Deutsch when I was a student at York and he gave a talk on programming environments to the department). The blue book defines a 16-bit Smalltalk, but we've all moved on to 32-bits. Since in a 32-bit Smalltalk a literal takes 4 bytes, a typical send takes therefore 5 bytes, 4 for the literal and 1 for the bytecode. By using a two byte bytecode whose second byte is the index into the special selectors, and extending the special selectors to 256 + 16 entries, you can encode an additional 256 of the most common sends in only 2 bytes.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><div></div><div class="Wj3C7c"><br>
<br>Gulik.<br><br>-- <br><a href="http://people.squeakfoundation.org/person/mikevdg" target="_blank">http://people.squeakfoundation.org/person/mikevdg</a><br><a href="http://gulik.pbwiki.com/" target="_blank">http://gulik.pbwiki.com/</a><br>
</div></div><br><br>
<br></blockquote></div><br>