diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-09-02 22:27:52 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-09-11 20:08:59 -0700 |
commit | 9ef8d5694201d933f4a61efde1fac904a29f55de (patch) | |
tree | 096f340563d3100f7dd46c2483e557c3a340c69b /pad.c | |
parent | 1d04412210d503c047816a9e347ca6628b4860fd (diff) | |
download | perl-9ef8d5694201d933f4a61efde1fac904a29f55de.tar.gz |
pad.c: Share pad name lists between clones
Pad names are immutable once the sub is compiled. They are shared
between clones. Instead of creating a new array containing the same
pad name SVs, just share the whole array.
cv_undef does not need to modify the pad name list when removing an
anonymous sub, so we can just delete that code. That was the only
thing modifying them between compilation and freeing, as far as I
could tell.
Diffstat (limited to 'pad.c')
-rw-r--r-- | pad.c | 15 |
1 files changed, 7 insertions, 8 deletions
@@ -265,7 +265,6 @@ Perl_pad_new(pTHX_ int flags) /* ... create new pad ... */ Newxz(padlist, 1, PADLIST); - padname = newAV(); pad = newAV(); if (flags & padnew_CLONE) { @@ -277,10 +276,13 @@ Perl_pad_new(pTHX_ int flags) AV * const a0 = newAV(); /* will be @_ */ av_store(pad, 0, MUTABLE_SV(a0)); AvREIFY_only(a0); + + padname = (PAD *)SvREFCNT_inc_simple_NN(PL_comppad_name); } else { padlist->xpadl_id = PL_padlist_generation++; av_store(pad, 0, NULL); + padname = newAV(); } /* Most subroutines never recurse, hence only need 2 entries in the padlist @@ -295,11 +297,11 @@ Perl_pad_new(pTHX_ int flags) /* ... then update state variables */ - PL_comppad_name = padname; PL_comppad = pad; PL_curpad = AvARRAY(pad); if (! (flags & padnew_CLONE)) { + PL_comppad_name = padname; PL_comppad_name_fill = 0; PL_min_intro_pending = 0; PL_padix = 0; @@ -420,8 +422,6 @@ Perl_cv_undef(pTHX_ CV *cv) U32 inner_rc = SvREFCNT(innercv); assert(inner_rc); assert(SvTYPE(innercv) != SVt_PVFM); - namepad[ix] = NULL; - SvREFCNT_dec(namesv); if (SvREFCNT(comppad) < 2) { /* allow for /(?{ sub{} })/ */ curpad[ix] = NULL; @@ -460,7 +460,7 @@ Perl_cv_undef(pTHX_ CV *cv) } { PAD * const sv = PadlistARRAY(padlist)[0]; - if (sv == PL_comppad_name) + if (sv == PL_comppad_name && SvREFCNT(sv) == 1) PL_comppad_name = NULL; SvREFCNT_dec(sv); } @@ -1937,7 +1937,7 @@ Perl_cv_clone(pTHX_ CV *proto) dVAR; I32 ix; PADLIST* const protopadlist = CvPADLIST(proto); - const PAD *const protopad_name = *PadlistARRAY(protopadlist); + PAD *const protopad_name = *PadlistARRAY(protopadlist); const PAD *const protopad = PadlistARRAY(protopadlist)[1]; SV** const pname = AvARRAY(protopad_name); SV** const ppad = AvARRAY(protopad); @@ -2004,12 +2004,11 @@ Perl_cv_clone(pTHX_ CV *proto) if (SvMAGIC(proto)) mg_copy((SV *)proto, (SV *)cv, 0, 0); + PL_comppad_name = protopad_name; CvPADLIST(cv) = pad_new(padnew_CLONE|padnew_SAVE); CvPADLIST(cv)->xpadl_id = protopadlist->xpadl_id; av_fill(PL_comppad, fpad); - for (ix = fname; ix > 0; ix--) - av_store(PL_comppad_name, ix, SvREFCNT_inc(pname[ix])); PL_curpad = AvARRAY(PL_comppad); |