Dan Sugalski <[EMAIL PROTECTED]> wrote:
> At 9:18 PM +0200 7/20/04, Leopold Toetsch wrote:
[ I've to come back to my proposed scheme ]
>>No. The whole frame is the continuation. Its holding exactly the
>>interpreter state at the time of calling into the sub. Including
>>registers, which makes register preserving obsolete.
> Which means that as soon as you use it the first time it becomes
> useless, since you can't know when it stops being used. That makes
> them one use--every time you enter the sub you need a new one, just
> as if you were calling in recursively.
I don't think so. As it might not be outerly clear, how it would look
like: here are two code snippets showing the basics of my idea.
1.) Calling a sub
next = sub_pmc->invoke->(&interp, sub_pmc, next);
^^^^^^^
void *
invoke(Interp** interp, PMC* self, void *next) {
Interp *caller = *interp;
parrot_sub_t sub = PMC_sub(self);
Interp *frame = sub->frame;
if (!frame || frame->caller)
frame = copy_interp(caller);
else
update_context(frame, caller);
frame->prev = sub->frame;
sub->frame = frame;
frame->caller = caller;
frame->sub_pmc = self;
copy_func_params(frame, caller);
*interp = frame;
next = switch_to_segment(frame, sub->seg);
return next;
}
2.) return from a sub
PMC *self = interp->sub_pmc;
next = self->vtable->return(&interp, self)
void *
return(Interp** interp, PMC* self) {
parrot_sub_t sub = PMC_sub(self);
Interp *frame = sub->frame;
Interp *caller = frame->caller;
Interp *prev = sub->frame = frame->prev;
if (prev && !prev->caller)
add_frame_cache(prev, sub); [1]
copy_return_values(caller, frame);
*interp = caller;
return switch_to_segment(caller, sub->seg);
}
> It's just not going to fly, Leo.
Im Gegenteil ;)
I know, that there are issues with threads. But we have to duplicate or
C<< pmc->vtable->share >> anyway. But copying the sub PMC is cheap, much
more expensive is that we have to reJIT (and/or re-predereference) the
code, because these run loops have absolute register addresses. Doing
that now at a much more fine-grained level, i.e. per subroutine that is
executed in a thread and not per file, might be even a big win.
Above scheme is thread-safe, if there are locks around the code. This
could be an alternative to duplicating subroutine PMCs, it depends. But
for now, I'd like to get single-threaded execution running - fast.
[1] If there is no caller on that frame, it would go into some kind of
frame cache, which C<copy_interp()> could use, or it could be kept for
that sub, probably depending on memory usage.
leo