From: Nicholas Clark Date: Fri, 11 Jan 2008 17:00:59 +0000 (+0000) Subject: Pack the recycled pad offsets into an SV at PL_regex_pad[0]. This will X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=402d2eb1990caf116b392579a55f0a4f317d2738;p=p5sagit%2Fp5-mst-13.2.git Pack the recycled pad offsets into an SV at PL_regex_pad[0]. This will use less memory than an AV. p4raw-id: //depot/perl@32959 --- diff --git a/intrpvar.h b/intrpvar.h index d457028..06014ef 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -564,7 +564,8 @@ PERLVAR(Iregex_pad, SV**) /* Shortcut into the array of regex_padav */ PERLVAR(Iregex_padav, AV*) /* All regex objects, indexed via the values in op_pmoffset of pmop. - Entry 0 is an array of IVs listing + Entry 0 is an SV whose PV is a + "packed" list of IVs listing the now-free slots in the array */ #endif diff --git a/op.c b/op.c index 3903f53..e5fed9d 100644 --- a/op.c +++ b/op.c @@ -623,9 +623,11 @@ clear_pmop: */ #ifdef USE_ITHREADS if(PL_regex_pad) { /* We could be in destruction */ + const IV offset = (cPMOPo)->op_pmoffset; ReREFCNT_dec(PM_GETRE(cPMOPo)); - av_push((AV*) PL_regex_pad[0], newSViv((cPMOPo)->op_pmoffset)); - PL_regex_pad[(cPMOPo)->op_pmoffset] = &PL_sv_undef; + PL_regex_pad[offset] = &PL_sv_undef; + sv_catpvn_nomg(PL_regex_pad[0], (const char *)&offset, + sizeof(offset)); } #else ReREFCNT_dec(PM_GETRE(cPMOPo)); @@ -3364,13 +3366,20 @@ Perl_newPMOP(pTHX_ I32 type, I32 flags) #ifdef USE_ITHREADS - if (av_len((AV*) PL_regex_pad[0]) > -1) { - SV * const repointer = av_pop((AV*)PL_regex_pad[0]); - const IV offset = SvIV(repointer); + assert(SvPOK(PL_regex_pad[0])); + if (SvCUR(PL_regex_pad[0])) { + /* Pop off the "packed" IV from the end. */ + SV *const repointer_list = PL_regex_pad[0]; + const char *p = SvEND(repointer_list) - sizeof(IV); + const IV offset = *((IV*)p); + + assert(SvCUR(repointer_list) % sizeof(IV) == 0); + + SvEND_set(repointer_list, p); + pmop->op_pmoffset = offset; /* This slot should be free, so assert this: */ assert(PL_regex_pad[offset] == &PL_sv_undef); - SvREFCNT_dec(repointer); } else { SV * const repointer = &PL_sv_undef; av_push(PL_regex_padav, repointer); diff --git a/perl.c b/perl.c index 4397087..e8821a5 100644 --- a/perl.c +++ b/perl.c @@ -353,8 +353,9 @@ perl_construct(pTHXx) sv_setpvn(PERL_DEBUG_PAD(1), "", 0); /* ext/re needs these */ sv_setpvn(PERL_DEBUG_PAD(2), "", 0); /* even without DEBUGGING. */ #ifdef USE_ITHREADS - /* First entry is an array of empty elements */ - Perl_av_create_and_push(aTHX_ &PL_regex_padav,(SV*)newAV()); + /* First entry is a list of empty elements. It needs to be initialised + else all hell breaks loose in S_find_uninit_var(). */ + Perl_av_create_and_push(aTHX_ &PL_regex_padav, newSVpvs("")); PL_regex_pad = AvARRAY(PL_regex_padav); #endif #ifdef USE_REENTRANT_API