On Nov 10, 2004, at 3:08 PM, Leopold Toetsch wrote:

Jeff Clites <[EMAIL PROTECTED]> wrote:

But there's one wiggle: If you've created a continuation previously
(and it still exists), then any call has to preserve the frame

Well, that's what continuations are doing. They do preserve the frame,
which they have taken a snapshot of. And they preserve any frames up the
call chain. This is needed and implemented and working.

But here's the part I'm thinking about:

Continuations only copy the interpreter context, which contains the register bp, but of course the actual contents of the register frame are not duplicated. (This is as it should be.) The contents of the register frame are effectively preserved because in sub->invoke() we allocate a new register frame, and change the bp to point there. (That's fine too.)

But, in a tail-call-optimization case, we don't need to call new_register_frame() and copy_regs()--ex hypothesi, we can re-use the register frame already in-place. That's a big savings--that's the optimization I'm after. But of course, we can only do that if we know that a "real" continuation hasn't also captured the context.

But in light of what you say here...

The concept of a return continuation (which recycles itself and the
frame it returned from) doesn't have an influence on tail calls.
Whenever you see a continuation "on the surface", it's one that is
preserving the frames and the context. Eventually there isn't even a
RetContinuation object but just a pointer to the calling frame. But
whenever you can see a continuations it's a real one

...it sounds like we have an easy way to tell if a "real" continuation has a claim on the register frame, because creating such a real continuation can mark the frame, and we can check for the mark in our tail-call implementation, and if it's marked then fall back to new_register_frame/copy_regs. (In fact that mark should be a reference count, keeping track of how many continuations "have a claim" on the register frame. That way, if a real continuation is created, but GC claims it before our tail-call attempt, we can still use our optimization.)


But maybe we're already doing something like that, and I missed it.

AFAIK the only problem with tailcalls and tail-recursive functions is to
prperly detect them in some optimizer, or to convert to such tailcalls.

Seems like that shouldn't be too bad--we only need to know that there's effectively no code between the function call and subsequent return. (Though maybe telling call from return will be tricky.)


JEff



Reply via email to