(redirecting to vm-dev)<br><br><div class="gmail_quote">On Mon, Aug 16, 2010 at 1:18 AM, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com">siguctua@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;">
Hello, Eliot.<br>
<br>
I just started exploring the Cog, and here&#39;s my first idea:<br>
- with NativeBoost, i can actually generate the native code, which can<br>
be inlined into other methods.<br>
<br>
So, then, whenever Cog sees, that primitive is NativeBoost primitive<br>
and it going to invoke<br>
a native code, then its possible to inline this method into outer<br>
method by copying a native code into<br>
generated method&#39;s code.<br></blockquote><div><br></div><div>Right, sounds good.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
I remember you mentioned that primitive invocation in Cog is rather<br>
ineffective , because<br>
you have to do some deoptimizations before entering a primitive.<br></blockquote><div><br></div><div>No, that&#39;s not the issue.  In Cog there are two kinds of primitives, generated primitives and C primitives.  Cog generates the code for generated primitives and these are fast; their code is inlined in the start of the method immediately following the unchecked entry-point and preceeding frame build.  See Cogit&gt;&gt;compilePrimitive and Cogit&gt;&gt;primitiveGeneratorOrNil.  C primitives are the conventional primitives that the interpreter can call, i.e. the contents of the PrimitiveTable plus all the named primitives.  The issue is that these C primitives must be called on the C stack since Cog has no way of knowing how much stack a C primitive uses and Cog stack pages are fixed size.  So the JIT must generate a stack switching call to invoke C primitives from machine code.  This call is very like a system call and it is certainly slower than a normal C call and hence slower than invoking a C primitive from within the interpreter.  See SimpleStackBasedCogit&gt;&gt;compileInterpreterPrimitive:.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">I wonder if its possible to do such things.<br>
The problem, what i see is that NativeBoost&#39;s native code works as a<br>
primitive (its using interpreterProxy<br>
and its functions, and generated code honoring all VM/primitive<br>
conventions), so if primitive fails, it should<br>
enter the method&#39;s bytecode.<br></blockquote><div><br></div><div>I think you&#39;ll need to generate two forms of the machine code, one that is used as NativeBoost works now, and one that is designed to be inlined into a Cog native method.  You may also also want to include metadata so that the JIT can add metadata for embedded object references and relocateable calls (since Cog moves native methods) to the NB code it inlines into a native method.  See Cogit&#39;s method map protocol, and Cogit&gt;&gt;relocateMethodsPreCompaction &amp; Cogit&gt;&gt;relocateCallsAndSelfReferencesInMethod:.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
This maybe a major barrier, which could make a native code inlining<br>
highly problematic.<br>
<br>
What you think about it?<br></blockquote><div><br></div><div>I think it should work well if different versions are created for the interpreter and the Cogit.  The issues are to do with knowing what are the conventions the Cogit requires and those that C requires.</div>
<div><br></div><div>It strikes me that you may be able to use one single piece of machine code and just add metadata.  The machine code looks like:</div><div><br></div><div>A NativeBoost primitive:</div><div>     C frame building code</div>
<div>start of common code:</div><div>     code that actually implements the primitive</div><div>start of exit code</div><div>    C frame tear-down and return code</div><div>start of primitive failure code:</div><div>    call interpreterProxy-&gt;primitiveFail/primitiveFailFor</div>
<div>    jump to start of exit code</div><div><br></div><div>and add metadata for Cog that specifies where &quot;start of common code&quot; &amp; &quot;start of exit code&quot; is, where in the common code any object references or relocateable call references are, (and perhaps where any jumps to &quot;start of primitive failure code&quot; are).</div>
<div>When the Cogit compiles a method containing this NB primitive it inlines from &quot;start of common code&quot; up to (but not including) &quot;start of exit code&quot; and plants a jump over its generated primitive failure code.  Make sense?</div>
<div><br></div><div>best</div><div>Eliot</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
--<br>
Best regards,<br>
Igor Stasenko AKA sig.<br>
<br>
</font></blockquote></div><br>