Stack frames in the CV->PADLIST? $f isn't in something I'd immediately recognize as living in PADLIST but perhaps it is in a temporary. PadWalker would show it, I'll bet. UPDATED. It'd be possible to remove those RV to the self-CV and decrement their reference count.
use B 'svref_2object';
package B::SV;
use overload '""' => sub {
my ( $self ) = @_;
return sprintf '%s=(%x)', ref $self, $$self;
};
package main;
sub padinfo {
my $cv = svref_2object( $_[0] );
my $cvdepth = $cv->DEPTH;
my ( $namesav, @stackav ) = $cv->PADLIST->ARRAY;
my @names = map { $_->can('PV') ? $_->PV : undef } $namesav->ARRAY
+;
my @stack_ref = map [ $_->ARRAY ], @stackav;
print STDERR "$_[0]\n";
for my $depth ( 0 .. $#stack_ref ) {
if ( $depth == $DEPTH ) {
print STDERR '-' x 32;
print STDERR "LEVELS FOLLOWING MAY BE REAPED\n";
}
print STDERR " $depth\n";
for my $ix ( 0 .. $#{ $stack_ref[$depth] } ) {
next unless defined $names[$ix];
print STDERR " $names[$ix]: $stack_ref[$depth][$ix]\n";
print STDERR ' REFCNT:'. $stack_ref[$depth][$ix]->R
+EFCNT."\n";
if ( $stack_ref[$depth][$ix]->can( 'RV' ) ) {
print STDERR ' '.$stack_ref[$depth][$ix]->R
+V."\n";
print STDERR ' REFCNT:'.$stack_ref[$depth][
+$ix]->RV->REFCNT."\n";
}
}
}
}
sub refcnt {
print STDERR svref_2object( $_[0] )->REFCNT . "\n";
}
my $f;
$f = sub { my $g = time; $f->( $_[0] - 1 ) if $_[0] >= 0 };
refcnt $f;
refcnt \ $f;
padinfo $f;
$f->(1);
refcnt $f;
refcnt \i $f;
padinfo $f;
PRODUCES 1 # $f
3 # \$f
CODE(0x812a180)
--------------------------------LEVELS FOLLOWING MAY BE REAPED
0
$g: B::NULL=(81b6818)
REFCNT:1
$f: B::RV=(812aac8)
REFCNT:2
B::CV=(812a180)
REFCNT:1
1 # $f
5 # \$f
CODE(0x812a180)
--------------------------------LEVELS FOLLOWING MAY BE REAPED
0
$g: B::IV=(81b6818)
REFCNT:1
$f: B::RV=(812aac8)
REFCNT:4
B::CV=(812a180)
REFCNT:1
1
$g: B::IV=(81abe14)
REFCNT:1
$f: B::RV=(812aac8)
REFCNT:4
B::CV=(812a180)
REFCNT:1
2
$g: B::IV=(81abb98)
REFCNT:1
$f: B::RV=(812aac8)
REFCNT:4
B::CV=(812a180)
REFCNT:1
|