Leopold Toetsch <[EMAIL PROTECTED]> wrote: > - doesn't use managed memory anymore > - has now freelist handling
Thinking more about all these stacks, I think we got a problem. Let's assume this code snippet with this call trace: .sub _main newsub eh, .Exception_Handler, catch # or .Continuation set_eh eh # or pass on continuation # (1) _func1() # (2) .sub _func1 ... _func2() # (3) ... .sub _func2 ... throw exception # (4) or invoke Continuation PMC catch: # (1') The PMC register frame stack looks like (assuming a function call does C<pushtopp>): (1) <top> (2) P16...P31 (3) P16...P31 (4) --> (1') Now when the Continuation (or Exception) is invoked in (4) all the context of (1) is restored into the interpreter's context. Program flow continues in main but all stack changes (on all stacks) are effectively discarded--the whole context is reset to main's context. That means currently: we are leaking PMC register frames (2) and (3) in this example. But we could leak other register stack frames and user or pad stack entries too: .sub func2 new_pad 3 save 10 ... throw I can seen two ways to get around that: 1) use (again) managed (i.e. Buffer) memory for *all* stacks. Discarding the stacks is cleaned up by the next DOD+GC run. 2) on invoke()ing a Continuation unwind *all* stacks, that is: while (interp->ctx.<stack> != continuation->ctx.<stack>) POP(interp->ctx.<stack> During popping off all intermediate entries until the original state is reached, these stack entries are put onto the stacks freelist and aren't lost. 3) I'm missing something and can't count *But* there are coroutines too, which have additional complications, like their own register frame stacks. leo