Switching an active context in Cog

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Switching an active context in Cog

Igor Stasenko
 
Hello,

i want to adopt an image-side scheduling for Cog and since
everything which sounds like 'Process' will be wiped out from VM,
i need a way to cleanly switch the active context to a new one.

I think that as a guide for implementation could be taken
CoInterpreter>>transferTo: newProc from: sourceCode

but i am a bit confused by following:

self push: instructionPointer.
...(switching code)...
instructionPointer := self popStack.


does that means, that instruction pointer is always stored in last
stack position
instead of some fixed slot of context?

--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Switching an active context in Cog

Eliot Miranda-2
 
Hi Igor,

On Mon, Aug 16, 2010 at 9:42 AM, Igor Stasenko <[hidden email]> wrote:

Hello,

i want to adopt an image-side scheduling for Cog and since
everything which sounds like 'Process' will be wiped out from VM,
i need a way to cleanly switch the active context to a new one.

I think that as a guide for implementation could be taken
CoInterpreter>>transferTo: newProc from: sourceCode

but i am a bit confused by following:

self push: instructionPointer.
...(switching code)...
instructionPointer := self popStack.


does that means, that instruction pointer is always stored in last
stack position
instead of some fixed slot of context?

You need to internalize http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/. Cog /does not/ use contexts for managing execution.  It uses stack frames, and in an inactive stack frame on top of stack the instructionPointer is at top of stack (*).  So I suggest you read the above blog entry at least three times until it all starts to make sense.  Then you'll have to understand how the CoInterpreter complicates things by having two kinds of frame, one for interpreted methods and one for JIT-ed native methods, see CoInterpreter class>>initializeFrameIndices, and understand that an interpreter frame needs two instruction pointers, the normal one which is a return address for native code that jumps into the interpreter (see ceReturnToInterpreter:), and the one in the interpreted frame's iframeSavedIP slot which holds the bytecode pc (at which the interpreter should start executing).


(*) of course Cog does use contexts, but they are used as little as possible.  When you say "thisCOntext" a context gets created for a frame, and when teh stack zone fills up, stack pages are freed by copying all frames on a page to the heap as contexts, and when a snapshot is created all stack pages are freed, converting all frames to contexts.  So from the image this optimization is completely invisible, apparently all method activations are contexts, but the VM creates context objects only when necessary or convenient, and certainly /not/ on every send.

HTH,
Eliot


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: Switching an active context in Cog

Igor Stasenko

On 16 August 2010 21:26, Eliot Miranda <[hidden email]> wrote:

>
> Hi Igor,
>
> On Mon, Aug 16, 2010 at 9:42 AM, Igor Stasenko <[hidden email]> wrote:
>>
>> Hello,
>>
>> i want to adopt an image-side scheduling for Cog and since
>> everything which sounds like 'Process' will be wiped out from VM,
>> i need a way to cleanly switch the active context to a new one.
>>
>> I think that as a guide for implementation could be taken
>> CoInterpreter>>transferTo: newProc from: sourceCode
>>
>> but i am a bit confused by following:
>>
>> self push: instructionPointer.
>> ...(switching code)...
>> instructionPointer := self popStack.
>>
>>
>> does that means, that instruction pointer is always stored in last
>> stack position
>> instead of some fixed slot of context?
>
> You need to internalize http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/. Cog /does not/ use contexts for managing execution.  It uses stack frames, and in an inactive stack frame on top of stack the instructionPointer is at top of stack (*).  So I suggest you read the above blog entry at least three times until it all starts to make sense.  Then you'll have to understand how the CoInterpreter complicates things by having two kinds of frame, one for interpreted methods and one for JIT-ed native methods, see CoInterpreter class>>initializeFrameIndices, and understand that an interpreter frame needs two instruction pointers, the normal one which is a return address for native code that jumps into the interpreter (see ceReturnToInterpreter:), and the one in the interpreted frame's iframeSavedIP slot which holds the bytecode pc (at which the interpreter should start executing).
>

I am actually need few things to understand: how much state should be
preserved/swapped and in what order.
I seen you post and even tried to read it befor, but reading it
without using in practice is almost waste of time, because
i best work using trial & fail process, instead of reading books and
following rules :) That's how my mindset works,
and that's why i liked smalltalk so much, when i first seen it,
because it makes trial & fail process extremely easy and
enjoyful.
But thanks for reminder, i'll use your blog post as a reference :)

> (*) of course Cog does use contexts, but they are used as little as possible.  When you say "thisCOntext" a context gets created for a frame, and when teh stack zone fills up, stack pages are freed by copying all frames on a page to the heap as contexts, and when a snapshot is created all stack pages are freed, converting all frames to contexts.  So from the image this optimization is completely invisible, apparently all method activations are contexts, but the VM creates context objects only when necessary or convenient, and certainly /not/ on every send.

Yes, i am aware that contexts is used as less as possible. But from
language perspective, a context is still a smallest possible
unit of computation, which you can safely operate with. So, it is
logical to have a primitive which switching an active context,
instead of active process(es).
Also, same thing is userful for callbacks, by taking a simple block
closure, which should handle callback
and turning it into context, which then can be activated, once
callback is called.

> HTH,
> Eliot
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>
>
>



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Switching an active context in Cog

Eliot Miranda-2
 


On Mon, Aug 16, 2010 at 1:05 PM, Igor Stasenko <[hidden email]> wrote:

On 16 August 2010 21:26, Eliot Miranda <[hidden email]> wrote:
>
> Hi Igor,
>
> On Mon, Aug 16, 2010 at 9:42 AM, Igor Stasenko <[hidden email]> wrote:
>>
>> Hello,
>>
>> i want to adopt an image-side scheduling for Cog and since
>> everything which sounds like 'Process' will be wiped out from VM,
>> i need a way to cleanly switch the active context to a new one.
>>
>> I think that as a guide for implementation could be taken
>> CoInterpreter>>transferTo: newProc from: sourceCode
>>
>> but i am a bit confused by following:
>>
>> self push: instructionPointer.
>> ...(switching code)...
>> instructionPointer := self popStack.
>>
>>
>> does that means, that instruction pointer is always stored in last
>> stack position
>> instead of some fixed slot of context?
>
> You need to internalize http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/. Cog /does not/ use contexts for managing execution.  It uses stack frames, and in an inactive stack frame on top of stack the instructionPointer is at top of stack (*).  So I suggest you read the above blog entry at least three times until it all starts to make sense.  Then you'll have to understand how the CoInterpreter complicates things by having two kinds of frame, one for interpreted methods and one for JIT-ed native methods, see CoInterpreter class>>initializeFrameIndices, and understand that an interpreter frame needs two instruction pointers, the normal one which is a return address for native code that jumps into the interpreter (see ceReturnToInterpreter:), and the one in the interpreted frame's iframeSavedIP slot which holds the bytecode pc (at which the interpreter should start executing).
>

I am actually need few things to understand: how much state should be
preserved/swapped and in what order.
I seen you post and even tried to read it befor, but reading it
without using in practice is almost waste of time, because
i best work using trial & fail process, instead of reading books and
following rules :) That's how my mindset works,
and that's why i liked smalltalk so much, when i first seen it,
because it makes trial & fail process extremely easy and
enjoyful.

<blush>me too</blush>
 
But thanks for reminder, i'll use your blog post as a reference :)

> (*) of course Cog does use contexts, but they are used as little as possible.  When you say "thisCOntext" a context gets created for a frame, and when teh stack zone fills up, stack pages are freed by copying all frames on a page to the heap as contexts, and when a snapshot is created all stack pages are freed, converting all frames to contexts.  So from the image this optimization is completely invisible, apparently all method activations are contexts, but the VM creates context objects only when necessary or convenient, and certainly /not/ on every send.

Yes, i am aware that contexts is used as less as possible. But from
language perspective, a context is still a smallest possible
unit of computation, which you can safely operate with. So, it is
logical to have a primitive which switching an active context,
instead of active process(es).
Also, same thing is userful for callbacks, by taking a simple block
closure, which should handle callback
and turning it into context, which then can be activated, once
callback is called.

Right, so you implement that primitive, but in Cog it must be implemented like transferTo:from:.  i.e. in the frame you're leaving you must push the instruction pointer and ensure the frame has a context (since the context will persist, not necessarily the frame).  The context you're transferring to needs to have a frame before one can continue, so the primitive uses makeBaseFrameFor: if the context is not already married to a frame.

cheers,
Eliot
 

> HTH,
> Eliot
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>
>
>



--
Best regards,
Igor Stasenko AKA sig.