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

Reply via email to