From: Nicholas Clark Date: Fri, 30 Dec 2005 16:53:39 +0000 (+0000) Subject: Document why it's a bad plan to move the backreferences array from X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5b285ea4a6ead2df7b4a0a11b0aff949429e0500;p=p5sagit%2Fp5-mst-13.2.git Document why it's a bad plan to move the backreferences array from the magic structure to the hv_aux structure during backreference deletion. Add an optimisation for an empty backreference array. p4raw-id: //depot/perl@26542 --- diff --git a/hv.c b/hv.c index e560ba7..27c4bec 100644 --- a/hv.c +++ b/hv.c @@ -1664,11 +1664,16 @@ S_hfreeentries(pTHX_ HV *hv) if (iter) { if (iter->xhv_backreferences) { /* So donate them to regular backref magic to keep them safe. The - sv_magic will increase the reference count of the AV, so we need - to drop it first. */ + sv_magic will increase the reference count of the AV, so we + need to drop it first. */ SvREFCNT_dec(iter->xhv_backreferences); - sv_magic((SV*)hv, (SV*)iter->xhv_backreferences, - PERL_MAGIC_backref, NULL, 0); + if (AvFILLp(iter->xhv_backreferences) == -1) { + /* Turns out that the array is empty. Just free it. */ + SvREFCNT_dec(iter->xhv_backreferences); + } else { + sv_magic((SV*)hv, (SV*)iter->xhv_backreferences, + PERL_MAGIC_backref, NULL, 0); + } iter->xhv_backreferences = 0; } } diff --git a/sv.c b/sv.c index 3e3bb18..5372215 100644 --- a/sv.c +++ b/sv.c @@ -4409,6 +4409,10 @@ S_sv_del_backref(pTHX_ SV *tsv, SV *sv) if (SvTYPE(tsv) == SVt_PVHV && SvOOK(tsv)) { av = *Perl_hv_backreferences_p(aTHX_ (HV*)tsv); + /* We mustn't attempt to "fix up" the hash here by moving the + backreference array back to the hv_aux structure, as that is stored + in the main HvARRAY(), and hfreentries assumes that no-one + reallocates HvARRAY() while it is running. */ } if (!av) { const MAGIC *const mg