After reading Leopold Toetsch's post, I'm going to simplify part of my proposal slightly.
Benjamin Goldberg wrote: [snip] > To avoid premature cleanup, any time that the contents of a > refcounted variable is assigned to a non-refcounted variable, an > opcode to set a "reachable by non-refcounted variable" flag on the > value precedes the assignment. Actually, as Leopold suggested, we could merely set a global interpreter->needs_lazy_dod flag to true. [snip] > [*] How does this flag get cleared, you might ask? > > Simplest would be to not clear it at all. This would be mostly > harmless in terms of when objects get destructed, but would probably > result in more DoD runs than we really need -- blech. [**] > > A more "proper" solution would be to clear it during/after each DoD > run. > > During the course of a DoD run, when we look for what PMCs are > reachable, we keep track of what each thing was reachable *from*. This needs a bit of clarification, I think. IIRC, DoD normally happens something vaguely like this: for my $p (@all_pmcs) { clear_is_live_flag($p); } our $traverse; sub set_is_live_flag($p) { if( !test_is_live_flag($p) and test_is_agregate($p) ) { $traverse = [$p, $traverse]; } really_set_is_live_flag($p); } set_is_live_flag($_) for @rootset; while( $traverse ) { ((my $p), $traverse) = splice @$traverse; $p->set_live_flag_on_contained_objects(); } for my $p (@all_pmcs) { next if test_is_live_flag($p); free_pmc($p); } My proposal would change the set_is_live_flag to something like: sub set_is_live_flag($p, $contained_in) { if( test_uses_refcounting($p) and not test_has_refcount_trait($contained_in) ) { $needs_lazy_dod = 1; } if( !test_is_live_flag($p) and test_is_agregate($p) ) { $traverse = [$p, $traverse]; } really_set_is_live_flag($p); } Where $contained_in would be the variable (or agregate object) which the object $p is contained in. -- $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "[EMAIL PROTECTED] ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}