diff options
author | David Mitchell <davem@iabyn.com> | 2010-08-01 15:18:51 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2010-08-01 21:47:31 +0100 |
commit | 5648c0ae71de0db3ebfb4199727bc21e89c146c0 (patch) | |
tree | 6154d88ceb21e1a21bfa48cbe08a805564149b0e /hv.c | |
parent | 757971c467ea1792cbf102db9a0cc3a9dde58fea (diff) | |
download | perl-5648c0ae71de0db3ebfb4199727bc21e89c146c0.tar.gz |
optimise single backreferences
Rather than creating an AV and pushing the backref onto it,
store a single backref directly in the mg_obj or xhv_backreferences
slot.
If the backref is an AV, then we skip this optimisation (although I don't
think at the moment, that an AV would ever be pointed to by some backref
magic). So the test of whether the optimisation is is in effect is whether
the thing in the slot is an AV or not.
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 29 |
1 files changed, 19 insertions, 10 deletions
@@ -1682,17 +1682,25 @@ S_hfreeentries(pTHX_ HV *hv) * iteration we have to allow for this. */ if (iter->xhv_backreferences) { - /* The sv_magic will increase the reference count of the AV, - so we need to drop it first. */ - SvREFCNT_dec(iter->xhv_backreferences); - if (AvFILLp(iter->xhv_backreferences) == -1) { - /* Turns out that the array is empty. Just free it. */ + if (SvTYPE(iter->xhv_backreferences) == SVt_PVAV) { + /* The sv_magic will increase the reference count of the AV, + so we need to drop it first. */ SvREFCNT_dec(iter->xhv_backreferences); + if (AvFILLp(iter->xhv_backreferences) == -1) { + /* Turns out that the array is empty. Just free it. */ + SvREFCNT_dec(iter->xhv_backreferences); - } else { - sv_magic(MUTABLE_SV(hv), - MUTABLE_SV(iter->xhv_backreferences), - PERL_MAGIC_backref, NULL, 0); + } else { + sv_magic(MUTABLE_SV(hv), + MUTABLE_SV(iter->xhv_backreferences), + PERL_MAGIC_backref, NULL, 0); + } + } + else { + MAGIC *mg; + sv_magic(MUTABLE_SV(hv), NULL, PERL_MAGIC_backref, NULL, 0); + mg = mg_find(MUTABLE_SV(hv), PERL_MAGIC_backref); + mg->mg_obj = (SV*)iter->xhv_backreferences; } iter->xhv_backreferences = NULL; } @@ -2047,7 +2055,8 @@ Perl_hv_kill_backrefs(pTHX_ HV *hv) { if (av) { HvAUX(hv)->xhv_backreferences = 0; Perl_sv_kill_backrefs(aTHX_ MUTABLE_SV(hv), av); - SvREFCNT_dec(av); + if (SvTYPE(av) == SVt_PVAV) + SvREFCNT_dec(av); } } |