Blessed file handles aren't counted by PL_sv_objcount
This seems to be by design, as it's all quite explicit in the source. The
upshot is that if you attempt to avoid "unnecessary" work during destruction:

==== //depot/perl/sv.c#946 - /home/nick/p4perl/perl/sv.c ====
--- /tmp/tmp.7324.0     Sat Jul  2 20:14:56 2005
+++ /home/nick/p4perl/perl/sv.c Sat Jul  2 18:52:57 2005
@@ -494,8 +494,10 @@ Perl_sv_clean_objs(pTHX)
     PL_in_clean_objs = TRUE;
     visit(do_clean_objs, SVf_ROK, SVf_ROK);
 #ifndef DISABLE_DESTRUCTOR_KLUDGE
-    /* some barnacles may yet remain, clinging to typeglobs */
-    visit(do_clean_named_objs, SVt_PVGV, SVTYPEMASK);
+    if (PL_sv_objcount) {
+       /* some barnacles may yet remain, clinging to typeglobs */
+       visit(do_clean_named_objs, SVt_PVGV, SVTYPEMASK);
+    }
 #endif
     PL_in_clean_objs = FALSE;
 }


then tests fail:

op/ref.t                       89    1   1.12%  71
run/fresh_perl.t               94    1   1.06%  53


Notably both these tests have their own little hacks to ensure that the
destructor gets called at all:

op/ref.t test 71:

# using a regex in the destructor for STDOUT segfaulted because the
# REGEX pad had already been freed (ithreads build only). The
# object is required to trigger the early freeing of GV refs to to STDOUT

like (runperl(
    prog => '$x=bless[]; sub IO::Handle::DESTROY{$_="bad";s/bad/ok/;print}',
    stderr => 1
      ), qr/^(ok)+$/, 'STDOUT destructor');

run/fresh_perl.t test 53:

########
package X;
sub any { bless {} }
my $f = "FH000"; # just to thwart any future optimisations
sub afh { select select ++$f; my $r = *{$f}{IO}; delete $X::{$f}; bless $r }
sub DESTROY { print "destroyed\n" }
package main;
$x = any X; # to bump sv_objcount. IO objs aren't counted??
*f = afh X;
EXPECT
destroyed
destroyed


Isn't the current behaviour a bit of a bodge? Why is it this way?

Nicholas Clark

Reply via email to