[Vm-dev] [Cog] Fall back to interpreter. How?

Igor Stasenko siguctua at gmail.com
Tue Apr 24 22:14:31 UTC 2012


On 24 April 2012 23:17, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
>
>
> On Mon, Apr 23, 2012 at 4:59 PM, Igor Stasenko <siguctua at gmail.com> wrote:
>>
>>
>> On 24 April 2012 02:42, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>> >
>> >
>> >
>> > On Mon, Apr 23, 2012 at 4:20 PM, Igor Stasenko <siguctua at gmail.com> wrote:
>> >>
>> >>
>> >> On 24 April 2012 01:57, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>> >> >
>> >> >
>> >> >
>> >> > On Mon, Apr 23, 2012 at 2:28 PM, Igor Stasenko <siguctua at gmail.com> wrote:
>> >> >>
>> >> >>
>> >> >> Hi, Eliot, all :)
>> >> >>
>> >> >> i skimming through the cogit, and i cannot clearly identify the code
>> >> >> which generating code for falling back to interpreter.
>> >> >>
>> >> >> Say,  i want to create a native code which does nothing, just
>> >> >> switching back to interpreter, so the bytecode of given method will be
>> >> >> interpreted
>> >> >> where i should look for..
>> >> >
>> >> >
>> >> > The main transition from native code to machine code is on return, through the ceReturnToInterpreterPC, which calls ceReturnToInterpreter:, which does a longjmp via the reenterInterpreter jmp_buf.  But that will only work at return time.
>> >> >
>> >> > If you want to switch to the interpreter at primitive fail time things are going to be more complicated.  So exactly when do you want to enter the interpreter?  What state is the native boost call in?
>> >> >
>> >>
>> >> The state is following:
>> >>
>> >>  - a compiled method having generated code.
>> >>  - vm enters this code, thinking its a JITed method
>> >>  - this code fails for some reason
>> >>  - on a such failure, VM should switch to interpreter and interpret
>> >> the corresponding method's body.
>> >>
>> >>  if native code doesn't fails, it should behave, as if method were
>> >> performed normally (and so no need to fall back to interpreter).
>> >>
>> >> so, it is more or less the same how primitives behave , i.e. if method
>> >> having a primitive, you call the prim, and if everything is ok, you
>> >> continue running,
>> >> if prim fails, you activating the method and interpreting its bytecode.
>> >
>> >
>> > Then you should look at compilePrimitive and compileInterpreterPrimitive:.  Basically after your NB code you want to call compileInterpreterPrimitive: with some special entry-point that will call activateNewMethod.  In fact you can probably just call activateNewMethod.
>>
>> thanks. this looks fairly simple :)
>>
>> >But what if the method is used a lot?   Don't you want to JIT the body of the method?  I suppose its not important.
>> >
>>
>> apparently i don't want to jit the body, because then i will have to maintain
>> own native code + jited code in addition, and VM has only one way to
>> identify and use CompiledMethod(s) with jited code..
>> because the idea is to make cogit think that the code NB generated at
>> language side is the code he jited itself :)
>>
>> since there is 99.9% expectation that normally primitive won't fail,
>> it is not important to optimize/jit method body anyways,
>> because it usually contain a lot of error checking and fallback code
>> and native code generation.. and it don't needs to be blazingly fast .
>
>
> Then you need something like
>
> "Save processor fp, sp and return pc in the interpreter's frame stack and instruction pointers"
> self genExternalizePointersForPrimitiveCall.
> "Switch to the C stack."
> self genLoadCStackPointersForPrimCall.
> "Call activateNewMethod."
>   self CallRT: #activateNewMethod asSymbol asInteger.
>
> (the asSymbol is important for Slang)
>
> The only issue here is that if a callback from NB can occur then the other state (newMethod argumentCount) either needs to be saved/restored around the callback or saved/restored around the NB callout.
>

Thanks, Eliot. These details is very important to me.

Sure thing, i am not going to generate callback code for it..
i wanna try to check how faster the simple primitives (like adding two numbers)
could be if i can be able to run NB code without leaving jited code.

Since any form of foreign call will require switching to C stack
anyways, my primary aim
for merging NB and jit is for implementing various numeric crunching
primitives.. and play around with them :)

I already implemented the FPUStack. class, which can do multiple
floating-point operations without
need to produce garbage Float instances. Potentially it should run faster.
But since for every operation it has to call NB primitive, currently
it slower than just same code
implemented using normal way.

>>
>> >>
>> >>
>> >> >>
>> >> >> Also, what are hooks i need for that? Which global state should be changed?
>> >> >
>> >> >
>> >> > The glue should modify the necessary global state, which is framePointer and stackPointer.
>> >> >
>> >> >>
>> >> >> And finally, is there documentation about calling convention for jited
>> >> >> code? I'd like to know what is the state of registers when VM enters
>> >> >> the jited method, and what their purpose.
>> >> >
>> >> >
>> >> > See StackToRegisterMappingCogit>>callingConvention, StackToRegisterMappingCogit>>numRegArgs and CogIA32Compiler>concreteRegister:.  With the  SimpleStackBasedCogit everything is passed on the stack.  With StackToRegisterMappingCogit, with <= 1 arg, args are passed in ReceiverResultReg and Arg0Reg (but with the new object represnetation I will up the number of register arguments to 2).  But to protect the CoInterpreter from these details the registers are only visible to primitives.  Primitive failure or prolog code pushes them onto the stack.  See StackToRegisterMappingCogit>>genPushRegisterArgsForNumArgs: and senders, especially StackToRegisterMappingCogit>>genPushRegisterArgs, which is called from three places, one for method frame build, one for primitive failure and one for closure activation.
>> >> >
>> >> > In addition, on calling a method's checked entry-point (see Cogit>compileEntry) ClassReg holds the class when the send site was linked, and ClassReg holds the message selector when the send is unlinked (which will through glue call CoInterpreter>>ceSend:super:to:numArgs:.
>> >> >
>> >> > HTH
>> >> >
>> >> > and if this is still confusing we could try skyping tomorrow.
>> >>
>> >> ah.. i am not focused on this task.. right now i collecting necessary
>> >> bits of information. But thanks for the offer and info. I will, of
>> >> course, bother you more when i will start making it for real :)
>> >>
>> >> > --
>> >> > Eliot
>> >> >
>> >> >
>> >>
>> >>
>> >>
>> >> --
>> >> Best regards,
>> >> Igor Stasenko.
>> >
>> >
>> >
>> >
>> > --
>> > best,
>> > Eliot
>> >
>> >
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko.
>
>
>
>
> --
> best,
> Eliot
>
>



-- 
Best regards,
Igor Stasenko.


More information about the Vm-dev mailing list