From: Nicholas Clark Date: Mon, 18 May 2009 11:50:06 +0000 (+0100) Subject: Tidy the implementation of Perl_mg_dup(). X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=45f7fcc88f316d3cfef48062f141b1586354cfec;p=p5sagit%2Fp5-mst-13.2.git Tidy the implementation of Perl_mg_dup(). As all the structure elements are directly assigned to, use Newx() rather than Newxz(). Replace the explicit assignments with a direct structure copy. When reading values from the parent, read from those copied to the new structure, rather than the identical value in the old structure, to recduce CPU cache pressure. --- diff --git a/sv.c b/sv.c index 70e6a9b..6212955 100644 --- a/sv.c +++ b/sv.c @@ -10516,51 +10516,52 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param) for (; mg; mg = mg->mg_moremagic) { MAGIC *nmg; - Newxz(nmg, 1, MAGIC); + Newx(nmg, 1, MAGIC); *mgprev_p = nmg; mgprev_p = &(nmg->mg_moremagic); - nmg->mg_virtual = mg->mg_virtual; /* XXX copy dynamic vtable? */ - nmg->mg_private = mg->mg_private; - nmg->mg_type = mg->mg_type; - nmg->mg_flags = mg->mg_flags; + /* There was a comment "XXX copy dynamic vtable?" but as we don't have + dynamic vtables, I'm not sure why Sarathy wrote it. The comment dates + from the original commit adding Perl_mg_dup() - revision 4538. + Similarly there is the annotation "XXX random ptr?" next to the + assignment to nmg->mg_ptr. */ + *nmg = *mg; + /* FIXME for plugins - if (mg->mg_type == PERL_MAGIC_qr) { - nmg->mg_obj = MUTABLE_SV(CALLREGDUPE((REGEXP*)mg->mg_obj, param)); + if (nmg->mg_type == PERL_MAGIC_qr) { + nmg->mg_obj = MUTABLE_SV(CALLREGDUPE((REGEXP*)nmg->mg_obj, param)); } else */ - if(mg->mg_type == PERL_MAGIC_backref) { + if(nmg->mg_type == PERL_MAGIC_backref) { /* The backref AV has its reference count deliberately bumped by 1. */ nmg->mg_obj - = SvREFCNT_inc(av_dup_inc((const AV *) mg->mg_obj, param)); + = SvREFCNT_inc(av_dup_inc((const AV *) nmg->mg_obj, param)); } else { - nmg->mg_obj = (mg->mg_flags & MGf_REFCOUNTED) - ? sv_dup_inc(mg->mg_obj, param) - : sv_dup(mg->mg_obj, param); - } - nmg->mg_len = mg->mg_len; - nmg->mg_ptr = mg->mg_ptr; /* XXX random ptr? */ - if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) { - if (mg->mg_len > 0) { - nmg->mg_ptr = SAVEPVN(mg->mg_ptr, mg->mg_len); - if (mg->mg_type == PERL_MAGIC_overload_table && - AMT_AMAGIC((AMT*)mg->mg_ptr)) + nmg->mg_obj = (nmg->mg_flags & MGf_REFCOUNTED) + ? sv_dup_inc(nmg->mg_obj, param) + : sv_dup(nmg->mg_obj, param); + } + + if (nmg->mg_ptr && nmg->mg_type != PERL_MAGIC_regex_global) { + if (nmg->mg_len > 0) { + nmg->mg_ptr = SAVEPVN(nmg->mg_ptr, nmg->mg_len); + if (nmg->mg_type == PERL_MAGIC_overload_table && + AMT_AMAGIC((AMT*)nmg->mg_ptr)) { - const AMT * const amtp = (AMT*)mg->mg_ptr; AMT * const namtp = (AMT*)nmg->mg_ptr; I32 i; for (i = 1; i < NofAMmeth; i++) { - namtp->table[i] = cv_dup_inc(amtp->table[i], param); + namtp->table[i] = cv_dup_inc(namtp->table[i], param); } } } - else if (mg->mg_len == HEf_SVKEY) - nmg->mg_ptr = (char*)sv_dup_inc((const SV *)mg->mg_ptr, param); + else if (nmg->mg_len == HEf_SVKEY) + nmg->mg_ptr = (char*)sv_dup_inc((const SV *)nmg->mg_ptr, param); } - if ((mg->mg_flags & MGf_DUP) && mg->mg_virtual && mg->mg_virtual->svt_dup) { + if ((nmg->mg_flags & MGf_DUP) && nmg->mg_virtual && nmg->mg_virtual->svt_dup) { CALL_FPTR(nmg->mg_virtual->svt_dup)(aTHX_ nmg, param); } }