in reply to Re^5: Reference of constants and literals
in thread Reference of constants and literals
What refcount is kept greater than 1?
This is what happens to scalar lexicals on scope exit:
848: ptr = (void*)&PL_curpad[SSPOPLONG]; 849: sv = *(SV**)ptr; 850: 858: /* Can clear pad variable in place? */ 859: if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) { 860: /* 861: * if a my variable that was made readonly is going out of 862: * scope, we want to remove the readonlyness so that it can 863: * go out of scope quietly 864: */ 865: if (SvPADMY(sv) && !SvFAKE(sv)) 866: SvREADONLY_off(sv); 867: 868: if (SvTHINKFIRST(sv)) 869: sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF); 870: if (SvMAGICAL(sv)) 871: mg_free(sv); 872: 885: SvOK_off(sv); 888: SvPADSTALE_on(sv); /* mark as no longer live */ 889: } 890: else { /* Someone has a claim on this, so abandon it. */ 891: const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP); 895: *(SV**)ptr = newSV(0); 897: SvREFCNT_dec(sv); /* Cast current value to the winds. */ 898: /* preserve pad nature, but also mark as not live 899: * for any closure capturing */ 900: SvFLAGS(*(SV**)ptr) |= padflags | SVs_PADSTALE; 901: }
(Lifted from Perl_leave_scope in scope.c in perl.git.)
Note line 895. It allocates a new value for $x. Lexicals are allocated on scope exit, not on scope entry. That means $x's refcount at scope exit is what's meaningful. Its refcount is not checked on scope entry or when my is executed.
And $x's refcount at scope exit is 2. It is referenced by both the f's pad and the reference.
>perl -MDevel::Peek -le"sub f{ my $rv = \my $x; Dump($x); $rv } print +f() for 1..5" SV = NULL(0x0) at 0x235fcc REFCNT = 2 FLAGS = (PADBUSY,PADMY) SCALAR(0x235fcc) SV = NULL(0x0) at 0x236038 REFCNT = 2 FLAGS = (PADBUSY,PADMY) SCALAR(0x236038) SV = NULL(0x0) at 0x235fcc REFCNT = 2 FLAGS = (PADBUSY,PADMY) SCALAR(0x235fcc) SV = NULL(0x0) at 0x236038 REFCNT = 2 FLAGS = (PADBUSY,PADMY) SCALAR(0x236038) SV = NULL(0x0) at 0x235fcc REFCNT = 2 FLAGS = (PADBUSY,PADMY) SCALAR(0x235fcc)
Your bless doesn't prove anything since the presence of an object forces a reallocation. See line 859.
Update: Added code from scope.c
|
|---|