At 04:41 PM 1/6/2004 -0700, Luke Palmer wrote:
>I want these things to be garbage collected, but DOD doesn't trace the
>buffer. I can't seem to find a way to mark the frames without making
>the chunks into PMCs (yuck). Is there a way to do this?
I was about to answer your question when I saw your followup where
you answered it yourself.
Thats probably the way I would do it. A continuation can know how to
mark everything it closes over, and it doesn't have to be a PMC.
The brute force method is to copy the whole pad stack as soon
as a register frame is pushed or popped. As long as the stack is
tree based (where multiple copies of a set of frames can point
to the same parent), you only need to copy the current chunk, not
the whole stack, although most of the samples I ran at
the time never used more than a single register pad stack chunk (I think
it was 16 frames per chunk) so its probably an unnecessary short-cut,
just copy all chunks.
The downside to our implementation is in the return continuation case.
The common case is to create the continuation that you plan to
return with, and you already know there will be no need for
copy-on-write in most cases because typically the execution
path will return using that continuation, and that will then become
the "main" execution context. The original interpreter context and
all its associated stacks that existed at the time of the snapshot
will usually immediately be readonly orphans as soon as you activate the
return continuation (unless you saved the initial main context first).
It'd be more optimal to skip marking COW altogether in certain cases.
I think I've just confused myself so I'm sure I lost everyone.
The short of it is: the general case of closing over everything and
setting COW on everything for each return continuation is inefficient,
because the pattern becomes:
1) Freeze continuation B (mark all stacks COW in A, stacks that B references)
2) Activate return continuation B (replaces old interpreter
3) Continue execution which inevitably does stack modification and
causes a COPY + CLEAR COW bit on everything in B's now private copy.
B's private copy usually becomes the new "permanent" interpreter
context, until the next continuation (C, etc.) is activated. Taking return
and over has the effect of repeatedly making the main context readonly.
Without reference counting (ugg) I'm not sure how else to implement
continuations correctly and achieve any sort of shortcut to skip copying
things. As I said to Dan when I first patched them in; hopefully
someone smarter than me would come along and do it better/faster, I only
care that it actually _works_, and for now, it doesn't, completely.
Also, good papers on VM design with continuations seemed to be rare 2 yrs ago
and I expect they still are.
Now that I've taken you on a 2 mile tangent, back to the topic.
I'd be happy to see your patch.