summaryrefslogtreecommitdiff
path: root/mro.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2007-07-01 14:23:45 +0000
committerNicholas Clark <nick@ccl4.org>2007-07-01 14:23:45 +0000
commit0fd7ece8441d209e64f8443de20b905a8a476805 (patch)
tree801d1a6cbfa1a4e5d15177d34ad5d49ef60cc62a /mro.c
parent2e9f07a2fdf1a2d5a1f1e89b37d3b33b32ed2a72 (diff)
downloadperl-0fd7ece8441d209e64f8443de20b905a8a476805.tar.gz
Avoid copying the AV in Perl_mro_get_linear_isa_dfs()
p4raw-id: //depot/perl@31513
Diffstat (limited to 'mro.c')
-rw-r--r--mro.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/mro.c b/mro.c
index 37573f1eec..c3465706ba 100644
--- a/mro.c
+++ b/mro.c
@@ -87,7 +87,6 @@ AV*
Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level)
{
AV* retval;
- AV* tmp_retval; /* mortal to avoid leaks */
GV** gvp;
GV* gv;
AV* av;
@@ -114,8 +113,8 @@ Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level)
/* not in cache, make a new one */
- tmp_retval = (AV*)sv_2mortal((SV*)newAV());
- av_push(tmp_retval, newSVpv(stashname, 0)); /* add ourselves at the top */
+ retval = (AV*)sv_2mortal((SV *)newAV());
+ av_push(retval, newSVpv(stashname, 0)); /* add ourselves at the top */
/* fetch our @ISA */
gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
@@ -147,9 +146,7 @@ Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level)
}
else {
/* otherwise, recurse into ourselves for the MRO
- of this @ISA member, and append their MRO to ours.
- The recursive call could throw an exception, which
- has memory management implications here (tmp_retval) */
+ of this @ISA member, and append their MRO to ours */
const AV *const subrv
= mro_get_linear_isa_dfs(basestash, level + 1);
@@ -160,15 +157,17 @@ Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level)
SV *const subsv = *subrv_p++;
if(!hv_exists_ent(stored, subsv, 0)) {
hv_store_ent(stored, subsv, &PL_sv_undef, 0);
- av_push(tmp_retval, newSVsv(subsv));
+ av_push(retval, newSVsv(subsv));
}
}
}
}
- /* make the real retval out of tmp_retval, now that we're
- past the exception dangers */
- retval = av_make(AvFILLp(tmp_retval)+1, AvARRAY(tmp_retval));
+ /* now that we're past the exception dangers, grab our own reference to
+ the AV we're about to use for the result. The reference owned by the
+ mortals' stack will be released soon, so everything will balance. */
+ SvREFCNT_inc_simple_void_NN(retval);
+ SvTEMP_off(retval);
/* we don't want anyone modifying the cache entry but us,
and we do so by replacing it completely */