[Vm-dev] Re: [squeak-dev] Inlining native code in Cog

Eliot Miranda eliot.miranda at gmail.com
Mon Aug 16 18:00:17 UTC 2010

(redirecting to vm-dev)

On Mon, Aug 16, 2010 at 1:18 AM, Igor Stasenko <siguctua at gmail.com> wrote:

> Hello, Eliot.
> I just started exploring the Cog, and here's my first idea:
> - with NativeBoost, i can actually generate the native code, which can
> be inlined into other methods.
> So, then, whenever Cog sees, that primitive is NativeBoost primitive
> and it going to invoke
> a native code, then its possible to inline this method into outer
> method by copying a native code into
> generated method's code.

Right, sounds good.

> I remember you mentioned that primitive invocation in Cog is rather
> ineffective , because
> you have to do some deoptimizations before entering a primitive.

No, that'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>>compilePrimitive and Cogit>>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

I wonder if its possible to do such things.
> The problem, what i see is that NativeBoost's native code works as a
> primitive (its using interpreterProxy
> and its functions, and generated code honoring all VM/primitive
> conventions), so if primitive fails, it should
> enter the method's bytecode.

I think you'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's method map protocol, and
Cogit>>relocateMethodsPreCompaction &

This maybe a major barrier, which could make a native code inlining
> highly problematic.
> What you think about it?

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.

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:

A NativeBoost primitive:
     C frame building code
start of common code:
     code that actually implements the primitive
start of exit code
    C frame tear-down and return code
start of primitive failure code:
    call interpreterProxy->primitiveFail/primitiveFailFor
    jump to start of exit code

and add metadata for Cog that specifies where "start of common code" &
"start of exit code" is, where in the common code any object references or
relocateable call references are, (and perhaps where any jumps to "start of
primitive failure code" are).
When the Cogit compiles a method containing this NB primitive it inlines
from "start of common code" up to (but not including) "start of exit code"
and plants a jump over its generated primitive failure code.  Make sense?


> --
> Best regards,
> Igor Stasenko AKA sig.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20100816/193d43f7/attachment.htm

More information about the Vm-dev mailing list