On Sun, Aug 25, 2002 at 04:22:33PM +0100, Dave Mitchell wrote:
> Well, if understood you correctly, then a single execution of
> 
>     my $fh = IO::File->new(...)
> 
> anywhere in the program or its libraries would trigger this slow behaviour
> for the rest of the program. I'd have thought that the above, or its Perl6
> moral equivalent, is a fairly common idiom.

There may be too much book-keeping overhead in this, but

0: Default interpreter state is that
   a: there are no loose objects with deterministic destruction needed
   b: there are no rooted objects with deterministic destruction needed

(the meaning latter becomes clear below)

1: when you create an object with deterministic destruction needed, it is
   flagged as such, and the interpreter is flagged as having one of these
   loose.
2: Likewise, if you ever assign an object with deterministic destruction
   needed, the interpreter is flagged as having one of these beasts loose.
3: And if you ever assign (and overwrite) a DD object, you need to do a DOD
   run (as you might just have removed the last reference to it)

4: At the end of a block, if there are no objects of either sort, you are
   happy - just let GC work

   If there are rooted objects with deterministic destruction needed, but no
   loose objects, then you need to force a DOD run.

   If there are loose objects, then you need to do a DOD run, *and* when you
   find any deterministic destruction objects around that have parents that
   aren't deterministic, then you need to propagate the deterministic flag
   upwards (recursively, unfortunately) to the root.
   You then clear the loose object flag.


I think that the above probably slower.

However, I believe that it is possible to optimise, in that if at block
entry all deterministic destruction objects are rooted (so the loose flag is
clear) and during that block you neither create any, nor assign to or from
any, then at the end of the block you can not have caused any to go out of
scope.

(Actually, I think it's laxer than that - if you assign a DD object to
another container already marked as DD, then you've not let any DD object
become loose)

Note that this optimisation relies on all containers of all objects that
have deterministic destruction being marked as deterministic destruction.
And also, the whole thing relies on checking the deterministic destruction
flag on every object assignment. (ie this would be for everything that does
a reference count increase or decrease in in perl5 of a DD object)

If I've got the above correct, then you do have to pay a price on every
assignment (to verify that you're not moving DD objects into non-DD
objects, or overwriting a DD object) but apart from that you only have to
force a DOD run at the first block exit after a DD assignment. So once
you've done my $fh = IO::File->new(...) the DD flag is propagated up the
symbol tables (or pads) to the root for wherever $fh is at the (forced)
block exit DOD run, but after that you can leave blocks with forcing a
DOD run, providing you don't assign to or from $fh;

(Which I believe will be one of the two the common cases - these DD objects
will either be very persistent, or will go out of scope at the end of the
block that created them)

Nicholas Clark
-- 
Even better than the real thing:        http://nms-cgi.sourceforge.net/

Reply via email to