From ab95db60dabd8d8c36f2a83a140b52898d8d4f68 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Mon, 5 Jul 2010 22:07:30 +0100 Subject: [PATCH] add all stash backrefs individually when joining When joining a thread, a 'mini' interpreter clone is performed to clone the returned SVs and dependents back into the parent interpreter. To make things simple in this case, don't clone the xhv_backreferences array of any stashes, but individually add in any cloned GVs and CVs whose [CG]vSTASH points that way. This is faster (avoids an expensive test per CV/GV) and better (doesn't clone unnecessary SVs in the backref array) --- sv.c | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/sv.c b/sv.c index 4ca7333..88da54b 100644 --- a/sv.c +++ b/sv.c @@ -11222,18 +11222,8 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) /* Danger Will Robinson - GvGP(dstr) isn't initialised at the point of this comment. */ GvSTASH(dstr) = hv_dup(GvSTASH(dstr), param); - if(param->flags & CLONEf_JOIN_IN) { - const HEK * const hvname - = HvNAME_HEK(GvSTASH(dstr)); - if( hvname - && GvSTASH(dstr) == gv_stashpvn( - HEK_KEY(hvname), HEK_LEN(hvname), 0 - ) - ) - Perl_sv_add_backref( - aTHX_ MUTABLE_SV(GvSTASH(dstr)), dstr - ); - } + if (param->flags & CLONEf_JOIN_IN) + Perl_sv_add_backref(aTHX_ MUTABLE_SV(GvSTASH(dstr)), dstr); GvGP(dstr) = gp_dup(GvGP(sstr), param); (void)GpREFCNT_inc(GvGP(dstr)); } else @@ -11333,7 +11323,16 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) cBOOL(HvSHAREKEYS(sstr)), param) : 0; /* backref array needs refcnt=2; see sv_add_backref */ daux->xhv_backreferences = - saux->xhv_backreferences + (param->flags & CLONEf_JOIN_IN) + /* when joining, we let the individual GVs and + * CVs add themselves to backref as + * needed. This avoids pulling in stuff + * that isn't required, and simplifies the + * case where stashes aren't cloned back + * if they already exist in the parent + * thread */ + ? NULL + : saux->xhv_backreferences ? MUTABLE_AV(SvREFCNT_inc( sv_dup_inc((const SV *)saux->xhv_backreferences, param))) : 0; @@ -11358,18 +11357,8 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) case SVt_PVFM: /* NOTE: not refcounted */ CvSTASH(dstr) = hv_dup(CvSTASH(dstr), param); - if(param->flags & CLONEf_JOIN_IN && CvSTASH(dstr)) { - const HEK * const hvname - = HvNAME_HEK(CvSTASH(dstr)); - if( hvname - && CvSTASH(dstr) == gv_stashpvn( - HEK_KEY(hvname), HEK_LEN(hvname), 0 - ) - ) - Perl_sv_add_backref( - aTHX_ MUTABLE_SV(CvSTASH(dstr)), dstr - ); - } + if ((param->flags & CLONEf_JOIN_IN) && CvSTASH(dstr)) + Perl_sv_add_backref(aTHX_ MUTABLE_SV(CvSTASH(dstr)), dstr); OP_REFCNT_LOCK; if (!CvISXSUB(dstr)) CvROOT(dstr) = OpREFCNT_inc(CvROOT(dstr)); -- 1.8.3.1