summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intrpvar.h3
-rw-r--r--op.c21
-rw-r--r--perl.c5
3 files changed, 20 insertions, 9 deletions
diff --git a/intrpvar.h b/intrpvar.h
index d457028ec1..06014efc23 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 3903f53bb1..e5fed9dbb1 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 4397087ab9..e8821a500d 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