summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2005-12-30 01:08:46 +0000
committerNicholas Clark <nick@ccl4.org>2005-12-30 01:08:46 +0000
commit86f5593612e0fa4d1eddfb78098731af1f9f4548 (patch)
tree6cd5fac00a17f52ae05f8fc41c9a752899cb4e6f /mg.c
parente33435896f177fccb609ddddaf85afbfdc7a4e5f (diff)
downloadperl-86f5593612e0fa4d1eddfb78098731af1f9f4548.tar.gz
RMAGIC on symbol tables is bad, m'kay.
Allow hashes (and therefore all symbol tables) to store the backreference array in the hv_aux structure, and thereby undo the performance damage of 24966, which resulted in 60% of all hash lookups trying to mg_find tiehash magic. p4raw-id: //depot/perl@26530
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c37
1 files changed, 1 insertions, 36 deletions
diff --git a/mg.c b/mg.c
index 4a5c1f2604..44e48d224b 100644
--- a/mg.c
+++ b/mg.c
@@ -2043,42 +2043,7 @@ Perl_vivify_defelem(pTHX_ SV *sv)
int
Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
{
- AV *const av = (AV*)mg->mg_obj;
- SV **svp = AvARRAY(av);
- PERL_UNUSED_ARG(sv);
-
- /* Not sure why the av can get freed ahead of its sv, but somehow it does
- in ext/B/t/bytecode.t test 15 (involving print <DATA>) */
- if (svp && !SvIS_FREED(av)) {
- SV *const *const last = svp + AvFILLp(av);
-
- while (svp <= last) {
- if (*svp) {
- SV *const referrer = *svp;
- if (SvWEAKREF(referrer)) {
- /* XXX Should we check that it hasn't changed? */
- SvRV_set(referrer, 0);
- SvOK_off(referrer);
- SvWEAKREF_off(referrer);
- } else if (SvTYPE(referrer) == SVt_PVGV ||
- SvTYPE(referrer) == SVt_PVLV) {
- /* You lookin' at me? */
- assert(GvSTASH(referrer));
- assert(GvSTASH(referrer) == (HV*)sv);
- GvSTASH(referrer) = 0;
- } else {
- Perl_croak(aTHX_
- "panic: magic_killbackrefs (flags=%"UVxf")",
- (UV)SvFLAGS(referrer));
- }
-
- *svp = Nullsv;
- }
- svp++;
- }
- }
- SvREFCNT_dec(av); /* remove extra count added by sv_add_backref() */
- return 0;
+ return Perl_sv_kill_backrefs(aTHX_ sv, (AV*)mg->mg_obj);
}
int