At 01:48 AM 4/9/2002 -0400, Michel J Lambert wrote: > > the malloc()/free() situation which is one of the primary reasons we > > use garbage collection in the first place, so why reinvent the same > > situation with different syntax? > >Generally, malloc/free are used in more complex situations than just >stack-based memory management. But I see your point. > > > malloc/free is vulnerable to: > > 1) leakage (forgot to free) > >If you remember to mark it as used, you're pretty much guaranteed to mark >it as unused at the end of the same function.
As long as you leave the function from one place. There is no way using this method to say, "Whatever you do inside X(), I'm going to clean it up, even if you jump out of X() with longjmp()" >In general, this can't happen with setting bits. We can't unset a bit >twice, since we're only doing this on stuff returned by a function, for I may be using a hammer where a nail file would do here. I was thinking of the dangling buffer situation getting the bit cleared after the original had been moved out from under it, but I think it may be getting too late for me to continue this thing called thinking... :) You are probably right, if its a bug, its not the clearing of the bit, its keeping the invalid reference around not reachable from root. > > I suppose a variation of the scratch-pad that might be more on the > > performance line that you are thinking could be similar to the > > scope tracking that compilers do when gathering symbols into > > symbol tables. > >Ahhh, that's what I missed. I was assuming that you'd either have to push >variables on to this stack in buffer_allocate, or in the place that's >allocating them, and pop them all off with a end_GC_function. Which I >considered to be 'just as much work'. You interpreted correctly, my first mail had that in mind, then I saw your point on churn and killing the cache benefit. > > So a GC-able buffer gets created with a intial scope of cur_interp->scope, > > hidden in the allocator, and the collector skips collect on any > > buffer with scope <= the cur_scope. > >I'm a bit confused. Say I have function A call B and C. Function C will >have the same scope as B will. If C triggers a GC run, then anything >allocated in B will have the same scope as C. How will the GC system >know that it can mark those as dead? Granted your system is safe, but it >seems a little *too* safe. After return from C, it will be collected. Given, this is controlled usage for internals programmers. I wouldn't expect Parrot to do: int main() { save = GC_NEWPAD(); runops(); GC_RSTPAD(save); } I'm targetting the situation where A() creates an aggregate which calls B() and C() which might be recursive, etc. A() sets a marker, calls B()/C(). And pops the marker before returning. Its basically setting a GC "transaction" to use a SQL reference, but I don't expect internals guys to set a single large transaction over the whole interpreter. A caveat, scope 0 might be immune to this rule, else everything in the base scope might live forever. Easy enough to handle. -Melvin