Pass the current and desired hash sizes to S_hsplit().
authorNicholas Clark <nick@ccl4.org>
Thu, 21 Feb 2013 18:45:38 +0000 (19:45 +0100)
committerNicholas Clark <nick@ccl4.org>
Tue, 26 Feb 2013 15:00:19 +0000 (16:00 +0100)
Whilst this is slightly more work for its existing two callers, it will
permit Perl_hv_ksplit() to also call it.

Use STRLEN for the parameters, and change a local variable from I32 to
STRLEN to match.

embed.fnc
embed.h
hv.c
proto.h

index a288c5a..c9832d4 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -1769,7 +1769,7 @@ po        |SV*    |hfree_next_entry       |NN HV *hv|NN STRLEN *indexp
 #endif
 
 #if defined(PERL_IN_HV_C)
-s      |void   |hsplit         |NN HV *hv
+s      |void   |hsplit         |NN HV *hv|STRLEN const oldsize|STRLEN newsize
 s      |void   |hfreeentries   |NN HV *hv
 s      |SV*    |hv_free_ent_ret|NN HV *hv|NN HE *entry
 sa     |HE*    |new_he
diff --git a/embed.h b/embed.h
index c66eba9..9654979 100644 (file)
--- a/embed.h
+++ b/embed.h
 #  if defined(PERL_IN_HV_C)
 #define clear_placeholders(a,b)        S_clear_placeholders(aTHX_ a,b)
 #define hfreeentries(a)                S_hfreeentries(aTHX_ a)
-#define hsplit(a)              S_hsplit(aTHX_ a)
+#define hsplit(a,b,c)          S_hsplit(aTHX_ a,b,c)
 #define hv_auxinit             S_hv_auxinit
 #define hv_delete_common(a,b,c,d,e,f,g)        S_hv_delete_common(aTHX_ a,b,c,d,e,f,g)
 #define hv_free_ent_ret(a,b)   S_hv_free_ent_ret(aTHX_ a,b)
diff --git a/hv.c b/hv.c
index 8b447c8..51fe12d 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -796,6 +796,8 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
 
     xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */
     if ( DO_HSPLIT(xhv) ) {
+        const STRLEN oldsize = xhv->xhv_max + 1;
+
         /* This logic was in S_hsplit, but as the shared string table can't
            contain placeholders, and we are the only other caller of S_hsplit,
            it could only trigger from this callsite. So move it here.  */
@@ -806,7 +808,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
                readonly flag, because Storable always pre-splits the hash.  */
             hv_clear_placeholders(hv);
         }
-        hsplit(hv);
+        hsplit(hv, oldsize, oldsize * 2);
     }
 
     if (return_svp) {
@@ -1095,13 +1097,10 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
 }
 
 STATIC void
-S_hsplit(pTHX_ HV *hv)
+S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize)
 {
     dVAR;
-    XPVHV* const xhv = (XPVHV*)SvANY(hv);
-    const I32 oldsize = (I32) xhv->xhv_max+1; /* HvMAX(hv)+1 (sick) */
-    I32 newsize = oldsize * 2;
-    I32 i;
+    STRLEN i;
     char *a = (char*) HvARRAY(hv);
     HE **aep;
 
@@ -1123,7 +1122,7 @@ S_hsplit(pTHX_ HV *hv)
 
     PL_nomemok = FALSE;
     Zero(&a[oldsize * sizeof(HE*)], (newsize-oldsize) * sizeof(HE*), char);    /* zero 2nd half*/
-    xhv->xhv_max = --newsize;  /* HvMAX(hv) = --newsize */
+    HvMAX(hv) = --newsize;
     HvARRAY(hv) = (HE**) a;
     aep = (HE**)a;
 
@@ -2672,7 +2671,8 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, U32 hash, int flags)
        xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */
        if (!next) {                    /* initial entry? */
        } else if ( DO_HSPLIT(xhv) ) {
-            hsplit(PL_strtab);
+            const STRLEN oldsize = xhv->xhv_max + 1;
+            hsplit(PL_strtab, oldsize, oldsize * 2);
        }
     }
 
diff --git a/proto.h b/proto.h
index 18f46cc..9192960 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -5701,7 +5701,7 @@ STATIC void       S_hfreeentries(pTHX_ HV *hv)
 #define PERL_ARGS_ASSERT_HFREEENTRIES  \
        assert(hv)
 
-STATIC void    S_hsplit(pTHX_ HV *hv)
+STATIC void    S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize)
                        __attribute__nonnull__(pTHX_1);
 #define PERL_ARGS_ASSERT_HSPLIT        \
        assert(hv)