From 0fd7ece8441d209e64f8443de20b905a8a476805 Mon Sep 17 00:00:00 2001 From: Nicholas Clark Date: Sun, 1 Jul 2007 14:23:45 +0000 Subject: [PATCH] Avoid copying the AV in Perl_mro_get_linear_isa_dfs() p4raw-id: //depot/perl@31513 --- mro.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/mro.c b/mro.c index 37573f1..c346570 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 */ -- 2.7.4