summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2023-02-12 18:15:46 +0000
committerPaul Evans <leonerd@leonerd.org.uk>2023-02-13 17:41:49 +0000
commit857b55419b96b59cb074d897ac8e6154bbe1e1d2 (patch)
tree61d4870762090a21c87eb5630e2e3608c75103a7
parente7faea54386fae0e542ca8bfe43a8c5444c69114 (diff)
downloadperl-857b55419b96b59cb074d897ac8e6154bbe1e1d2.tar.gz
Refactor out the part of sv_dup that clones the HvAUX structure into its own helper function
-rw-r--r--embed.fnc3
-rw-r--r--embed.h1
-rw-r--r--proto.h5
-rw-r--r--sv.c132
4 files changed, 77 insertions, 64 deletions
diff --git a/embed.fnc b/embed.fnc
index 440a9c5e24..c3353044a5 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -5656,6 +5656,9 @@ S |SV ** |sv_dup_inc_multiple \
|NN SV **dest \
|SSize_t items \
|NN CLONE_PARAMS * const param
+S |void |sv_dup_hvaux |NN const SV * const ssv \
+ |NN SV *dsv \
+ |NN CLONE_PARAMS * const param
SR |SV * |sv_dup_common |NN const SV * const ssv \
|NN CLONE_PARAMS * const param
S |void |unreferenced_to_tmp_stack \
diff --git a/embed.h b/embed.h
index ea9c400763..a99c8ff74f 100644
--- a/embed.h
+++ b/embed.h
@@ -2055,6 +2055,7 @@
# endif /* defined(PERL_DEBUG_READONLY_COW) */
# if defined(USE_ITHREADS)
# define sv_dup_common(a,b) S_sv_dup_common(aTHX_ a,b)
+# define sv_dup_hvaux(a,b,c) S_sv_dup_hvaux(aTHX_ a,b,c)
# define sv_dup_inc_multiple(a,b,c,d) S_sv_dup_inc_multiple(aTHX_ a,b,c,d)
# define unreferenced_to_tmp_stack(a) S_unreferenced_to_tmp_stack(aTHX_ a)
# endif /* defined(USE_ITHREADS) */
diff --git a/proto.h b/proto.h
index 8a5f67c6f5..46dd8305c4 100644
--- a/proto.h
+++ b/proto.h
@@ -9195,6 +9195,11 @@ S_sv_dup_common(pTHX_ const SV * const ssv, CLONE_PARAMS * const param)
# define PERL_ARGS_ASSERT_SV_DUP_COMMON \
assert(ssv); assert(param)
+STATIC void
+S_sv_dup_hvaux(pTHX_ const SV * const ssv, SV *dsv, CLONE_PARAMS * const param);
+# define PERL_ARGS_ASSERT_SV_DUP_HVAUX \
+ assert(ssv); assert(dsv); assert(param)
+
STATIC SV **
S_sv_dup_inc_multiple(pTHX_ SV * const *source, SV **dest, SSize_t items, CLONE_PARAMS * const param);
# define PERL_ARGS_ASSERT_SV_DUP_INC_MULTIPLE \
diff --git a/sv.c b/sv.c
index 2e167a09c6..d0eb01a1bd 100644
--- a/sv.c
+++ b/sv.c
@@ -14423,6 +14423,72 @@ S_sv_dup_inc_multiple(pTHX_ SV *const *source, SV **dest,
return dest;
}
+/* duplicate the HvAUX of an HV */
+static void
+S_sv_dup_hvaux(pTHX_ const SV *const ssv, SV *dsv, CLONE_PARAMS *const param)
+{
+ PERL_ARGS_ASSERT_SV_DUP_HVAUX;
+
+ const struct xpvhv_aux * const saux = HvAUX(ssv);
+ struct xpvhv_aux * const daux = HvAUX(dsv);
+ /* This flag isn't copied. */
+ SvOOK_on(dsv);
+
+ if (saux->xhv_name_count) {
+ HEK ** const sname = saux->xhv_name_u.xhvnameu_names;
+ const I32 count = saux->xhv_name_count < 0
+ ? -saux->xhv_name_count
+ : saux->xhv_name_count;
+ HEK **shekp = sname + count;
+ HEK **dhekp;
+ Newx(daux->xhv_name_u.xhvnameu_names, count, HEK *);
+ dhekp = daux->xhv_name_u.xhvnameu_names + count;
+ while (shekp-- > sname) {
+ dhekp--;
+ *dhekp = hek_dup(*shekp, param);
+ }
+ }
+ else {
+ daux->xhv_name_u.xhvnameu_name = hek_dup(saux->xhv_name_u.xhvnameu_name, param);
+ }
+ daux->xhv_name_count = saux->xhv_name_count;
+
+ daux->xhv_aux_flags = saux->xhv_aux_flags;
+#ifdef PERL_HASH_RANDOMIZE_KEYS
+ daux->xhv_rand = saux->xhv_rand;
+ daux->xhv_last_rand = saux->xhv_last_rand;
+#endif
+ daux->xhv_riter = saux->xhv_riter;
+ daux->xhv_eiter = saux->xhv_eiter ? he_dup(saux->xhv_eiter, FALSE, param) : 0;
+ /* backref array needs refcnt=2; see sv_add_backref */
+ daux->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
+ ? (SvTYPE(saux->xhv_backreferences) == SVt_PVAV)
+ ? MUTABLE_AV(SvREFCNT_inc(
+ sv_dup_inc((const SV *)
+ saux->xhv_backreferences, param)))
+ : MUTABLE_AV(sv_dup((const SV *)
+ saux->xhv_backreferences, param))
+ : 0;
+
+ daux->xhv_mro_meta = saux->xhv_mro_meta
+ ? mro_meta_dup(saux->xhv_mro_meta, param)
+ : 0;
+
+ /* Record stashes for possible cloning in Perl_clone(). */
+ if (HvNAME(ssv))
+ av_push(param->stashes, dsv);
+}
+
/* duplicate an SV of any type (including AV, HV etc) */
static SV *
@@ -14731,70 +14797,8 @@ S_sv_dup_common(pTHX_ const SV *const ssv, CLONE_PARAMS *const param)
? he_dup(source, FALSE, param) : 0;
++i;
}
- if (HvHasAUX(ssv)) {
- const struct xpvhv_aux * const saux = HvAUX(ssv);
- struct xpvhv_aux * const daux = HvAUX(dsv);
- /* This flag isn't copied. */
- SvOOK_on(dsv);
-
- if (saux->xhv_name_count) {
- HEK ** const sname = saux->xhv_name_u.xhvnameu_names;
- const I32 count
- = saux->xhv_name_count < 0
- ? -saux->xhv_name_count
- : saux->xhv_name_count;
- HEK **shekp = sname + count;
- HEK **dhekp;
- Newx(daux->xhv_name_u.xhvnameu_names, count, HEK *);
- dhekp = daux->xhv_name_u.xhvnameu_names + count;
- while (shekp-- > sname) {
- dhekp--;
- *dhekp = hek_dup(*shekp, param);
- }
- }
- else {
- daux->xhv_name_u.xhvnameu_name
- = hek_dup(saux->xhv_name_u.xhvnameu_name,
- param);
- }
- daux->xhv_name_count = saux->xhv_name_count;
-
- daux->xhv_aux_flags = saux->xhv_aux_flags;
-#ifdef PERL_HASH_RANDOMIZE_KEYS
- daux->xhv_rand = saux->xhv_rand;
- daux->xhv_last_rand = saux->xhv_last_rand;
-#endif
- daux->xhv_riter = saux->xhv_riter;
- daux->xhv_eiter = saux->xhv_eiter
- ? he_dup(saux->xhv_eiter, FALSE, param) : 0;
- /* backref array needs refcnt=2; see sv_add_backref */
- daux->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
- ? (SvTYPE(saux->xhv_backreferences) == SVt_PVAV)
- ? MUTABLE_AV(SvREFCNT_inc(
- sv_dup_inc((const SV *)
- saux->xhv_backreferences, param)))
- : MUTABLE_AV(sv_dup((const SV *)
- saux->xhv_backreferences, param))
- : 0;
-
- daux->xhv_mro_meta = saux->xhv_mro_meta
- ? mro_meta_dup(saux->xhv_mro_meta, param)
- : 0;
-
- /* Record stashes for possible cloning in Perl_clone(). */
- if (HvNAME(ssv))
- av_push(param->stashes, dsv);
- }
+ if (HvHasAUX(ssv))
+ sv_dup_hvaux(ssv, dsv, param);
}
else
HvARRAY(MUTABLE_HV(dsv)) = NULL;