In perl.git, the branch yves/hv_h_split has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/a0ba399bd37fba040ebbc38d1c847d7f215c891a?hp=157df282bcc1926b9b40c77a97fff630df25f3b3>

- Log -----------------------------------------------------------------
commit a0ba399bd37fba040ebbc38d1c847d7f215c891a
Author: Yves Orton <[email protected]>
Date:   Fri Feb 22 21:18:04 2013 +0100

    Only realloc in hv_auxinit if we arent SvOOK already.
    
    Once we set SvOOK we should not need to realloc again.

M       hv.c

commit 9efe2e8ad6aa060aea83b4608c1a3da5f43715e8
Author: Yves Orton <[email protected]>
Date:   Fri Feb 22 21:17:03 2013 +0100

    make sure we set HvRAND whenever we set HvARRAY
    
    Defines HvARRAY_set(hv, array) which sets both properly.

M       hv.c
M       hv.h
-----------------------------------------------------------------------

Summary of changes:
 hv.c |   57 ++++++++++++++++++++++++++++-----------------------------
 hv.h |    6 ++++++
 2 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/hv.c b/hv.c
index 1dfaa1c..dd96be9 100644
--- a/hv.c
+++ b/hv.c
@@ -577,7 +577,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, 
STRLEN klen,
            Newxz(array,
                 PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */),
                 char);
-           HvARRAY(hv) = (HE**)array;
+            HvARRAY_set(hv,array);
        }
 #ifdef DYNAMIC_ENV_FETCH
        else if (action & HV_FETCH_ISEXISTS) {
@@ -765,7 +765,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, 
STRLEN klen,
        Newxz(array,
             PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */),
             char);
-       HvARRAY(hv) = (HE**)array;
+        HvARRAY_set(hv,array);
     }
 
     oentry = &(HvARRAY(hv))[hash & (I32) xhv->xhv_max];
@@ -792,9 +792,6 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, 
STRLEN klen,
      * We rotate the HvRAND(hv) each time we use it, so that each
      * insert potentially gets a different result.
      */
-    if (!HvRAND(hv)) {
-        HvRAND(hv)= ptr_hash((PTRV)HvARRAY(hv));
-    }
     if (!*oentry || HvRAND(hv) & 1) {
         HeNEXT(entry) = *oentry;
         *oentry = entry;
@@ -1146,17 +1143,20 @@ S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN 
newsize)
     PL_nomemok = FALSE;
     Zero(&a[oldsize * sizeof(HE*)], (newsize-oldsize) * sizeof(HE*), char);    
/* zero 2nd half*/
     HvMAX(hv) = --newsize;
-    HvARRAY(hv) = (HE**) a;
-
-    if (!HvTOTALKEYS(hv))       /* skip rest if no entries */
-        return;
-    
+    HvARRAY_set(hv, a);
     /* the idea of this is that we create a "random" value by hashing the 
address of
      * the array, we then use the low bit to decide if we insert at the top, 
or insert
      * second from top. After each such insert we rotate the hashed value. So 
we can
      * use the same hashed value over and over, and in normal build 
environments use
-     * very few ops to do so. ROTL32() should produce a single machine 
operation. */
-    HvRAND(hv)= bucket_rand= ptr_hash((PTRV)a);
+     * very few ops to do so. ROTL32() should produce a single machine 
operation.
+     *
+     * See definition of HvARRAY_set();
+     *
+     */
+    bucket_rand= HvRAND(hv);
+
+    if (!HvTOTALKEYS(hv))       /* skip rest if no entries */
+        return;
 
     aep = (HE**)a;
     do {
@@ -1214,7 +1214,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
     } else {
         Newxz(a, PERL_HV_ARRAY_ALLOC_BYTES(newsize), char);
         xhv->xhv_max = --newsize;
-        HvARRAY(hv) = (HE **) a;
+        HvARRAY_set(hv,a);
     }
 }
 
@@ -1272,7 +1272,7 @@ Perl_newHVhv(pTHX_ HV *ohv)
 
        HvMAX(hv)   = hv_max;
        HvTOTALKEYS(hv)  = HvTOTALKEYS(ohv);
-       HvARRAY(hv) = ents;
+        HvARRAY_set(hv,ents);
     } /* not magical */
     else {
        /* Iterate over ohv, copying keys and values one at a time. */
@@ -1742,7 +1742,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
     if (!SvOOK(hv)) {
        Safefree(HvARRAY(hv));
        xhv->xhv_max   = 7;     /* HvMAX(hv) = 7 (it's a normal hash) */
-       HvARRAY(hv) = 0;
+        HvARRAY(hv) = NULL;
+        HvRAND(hv) = 0;
     }
     /* if we're freeing the HV, the SvMAGIC field has been reused for
      * other purposes, and so there can't be any placeholder magic */
@@ -1827,20 +1828,18 @@ S_hv_auxinit(HV *hv) {
 
     PERL_ARGS_ASSERT_HV_AUXINIT;
 
-    if (!HvARRAY(hv)) {
-       Newxz(array, PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1)
-           + sizeof(struct xpvhv_aux), char);
-    } else {
-       array = (char *) HvARRAY(hv);
-       Renew(array, PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1)
-             + sizeof(struct xpvhv_aux), char);
-    }
-    if (!HvRAND(hv)) {
-        HvRAND(hv)= ptr_hash((PTRV)array);
+    if (!SvOOK(hv)) {
+        if (!HvARRAY(hv)) {
+            Newxz(array, PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1)
+                + sizeof(struct xpvhv_aux), char);
+        } else {
+            array = (char *) HvARRAY(hv);
+            Renew(array, PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1)
+                  + sizeof(struct xpvhv_aux), char);
+        }
+        HvARRAY_set(hv, array);
+        SvOOK_on(hv);
     }
-
-    HvARRAY(hv) = (HE**) array;
-    SvOOK_on(hv);
     iter = HvAUX(hv);
 
     iter->xhv_riter = -1;      /* HvRITER(hv) = -1 */
@@ -2834,7 +2833,7 @@ Perl_refcounted_he_chain_2hv(pTHX_ const struct 
refcounted_he *chain, U32 flags)
     if (!HvARRAY(hv)) {
        char *array;
        Newxz(array, PERL_HV_ARRAY_ALLOC_BYTES(max + 1), char);
-       HvARRAY(hv) = (HE**)array;
+        HvARRAY_set(hv, array);
     }
 
     placeholders = 0;
diff --git a/hv.h b/hv.h
index ebd6ca5..ff3a02d 100644
--- a/hv.h
+++ b/hv.h
@@ -216,6 +216,12 @@ C<SV*>.
 #define HvFILL(hv)     Perl_hv_fill(aTHX_ (const HV *)(hv))
 #define HvMAX(hv)      ((XPVHV*)  SvANY(hv))->xhv_max
 #define HvRAND(hv)      ((XPVHV*)  SvANY(hv))->xhv_rand
+
+#define HvARRAY_set(hv,a)   STMT_START {    \
+    HvARRAY(hv)= (HE **)a;                  \
+    HvRAND(hv)= ptr_hash((PTRV)a);          \
+} STMT_END
+
 /* This quite intentionally does no flag checking first. That's your
    responsibility.  */
 #define HvAUX(hv)      ((struct xpvhv_aux*)&(HvARRAY(hv)[HvMAX(hv)+1]))

--
Perl5 Master Repository

Reply via email to