This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
gv_check(): use aux flag rather than IsCOW
authorDavid Mitchell <davem@iabyn.com>
Sat, 15 Feb 2014 16:38:31 +0000 (16:38 +0000)
committerDavid Mitchell <davem@iabyn.com>
Fri, 28 Feb 2014 13:42:49 +0000 (13:42 +0000)
Currently the SVf_IsCOW flag doesn't have any meaning for HVs,
except that it is used in the specific case of gv_check() to temporarily
mark a stash as being scanned. Since stashes will have the HV_AUX fields,
we can use a flags bit in the new xhv_aux_flags field instead.

This then potentially frees up the SVf_IsCOW for use as a new general flag
bit for *all* HVs (including non-stash ones).

gv.c
hv.h
sv.h

diff --git a/gv.c b/gv.c
index 42cd69c..4a10f9b 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -2258,23 +2258,30 @@ Perl_gv_check(pTHX_ HV *stash)
 {
     dVAR;
     I32 i;
+    struct xpvhv_aux *aux;
 
     PERL_ARGS_ASSERT_GV_CHECK;
 
     if (!HvARRAY(stash))
        return;
+
+    assert(SvOOK(stash));
+    aux = HvAUX(stash);
+
     for (i = 0; i <= (I32) HvMAX(stash); i++) {
         const HE *entry;
-       /* SvIsCOW is unused on HVs, so we can use it to mark stashes we
-          are currently searching through recursively.  */
-       SvIsCOW_on(stash);
+        /* mark stash is being scanned, to avoid recursing */
+        aux->xhv_aux_flags |= HvAUXf_SCAN_STASH;
        for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) {
             GV *gv;
             HV *hv;
            if (HeKEY(entry)[HeKLEN(entry)-1] == ':' &&
                (gv = MUTABLE_GV(HeVAL(entry))) && isGV(gv) && (hv = GvHV(gv)))
            {
-               if (hv != PL_defstash && hv != stash && !SvIsCOW(hv))
+               if (hv != PL_defstash && hv != stash
+                    && !(SvOOK(hv)
+                        && (HvAUX(hv)->xhv_aux_flags & HvAUXf_SCAN_STASH))
+                )
                     gv_check(hv);              /* nested package */
            }
             else if ( *HeKEY(entry) != '_'
@@ -2298,7 +2305,7 @@ Perl_gv_check(pTHX_ HV *stash)
                             HEKfARG(GvNAME_HEK(gv)));
            }
        }
-       SvIsCOW_off(stash);
+        aux->xhv_aux_flags &= ~HvAUXf_SCAN_STASH;
     }
 }
 
diff --git a/hv.h b/hv.h
index 498e6f0..5ad1459 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -122,6 +122,8 @@ struct xpvhv_aux {
     U32         xhv_aux_flags;      /* assorted extra flags */
 };
 
+#define HvAUXf_SCAN_STASH   0x1   /* stash is being scanned by gv_check */
+
 /* hash structure: */
 /* This structure must match the beginning of struct xpvmg in sv.h. */
 struct xpvhv {
diff --git a/sv.h b/sv.h
index 715b124..a54fd8f 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -364,7 +364,6 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVpad_NAMELIST SVp_SCREAM  /* AV is a padnamelist */
 #define SVf_IsCOW      0x00010000  /* copy on write (shared hash key if
                                       SvLEN == 0) */
-                                   /* Also used on HVs in gv.c:gv_check */
 #define SVs_PADTMP     0x00020000  /* in use as tmp; only if ! SVs_PADMY */
 #define SVs_PADSTALE   0x00020000  /* lexical has gone out of scope;
                                        only valid for SVs_PADMY */