[PATCH #1/7] xhv_array (was Re: Using xhv_foo instead of HvFOO)
authorAbhijit Menon-Sen <ams@wiw.org>
Sun, 17 Jun 2001 08:02:59 +0000 (13:32 +0530)
committerJarkko Hietaniemi <jhi@iki.fi>
Sun, 17 Jun 2001 13:11:11 +0000 (13:11 +0000)
Date: Sun, 17 Jun 2001 08:02:59 +0530
Message-ID: <20010617080259.A28776@lustre.linux.in>

Subject: [PATCH #2/7] xhv_eiter
From: Abhijit Menon-Sen <ams@wiw.org>
Date: Sun, 17 Jun 2001 08:13:18 +0530
Message-ID: <20010617081318.B28776@lustre.linux.in>

Subject: [PATCH #3/7] xhv_fill
From: Abhijit Menon-Sen <ams@wiw.org>
Date: Sun, 17 Jun 2001 08:25:16 +0530
Message-ID: <20010617082516.C28776@lustre.linux.in>

Subject: [PATCH #4/7] xhv_keys
From: Abhijit Menon-Sen <ams@wiw.org>
Date: Sun, 17 Jun 2001 08:36:17 +0530
Message-ID: <20010617083617.D28776@lustre.linux.in>

Subject: [PATCH #5/7] xhv_max
From: Abhijit Menon-Sen <ams@wiw.org>
Date: Sun, 17 Jun 2001 08:39:48 +0530
Message-ID: <20010617083948.E28776@lustre.linux.in>

Subject: [PATCH #6,7/7] xhv_pmroot, xhv_riter
From: Abhijit Menon-Sen <ams@wiw.org>
Date: Sun, 17 Jun 2001 08:51:11 +0530
Message-ID: <20010617085111.F28776@lustre.linux.in>

p4raw-id: //depot/perl@10656

hv.c

diff --git a/hv.c b/hv.c
index 0f695b4..46ababf 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -147,7 +147,6 @@ information on how to use this function on tied hashes.
 SV**
 Perl_hv_fetch(pTHX_ HV *hv, const char *key, I32 klen, I32 lval)
 {
-    register XPVHV* xhv;
     register U32 hash;
     register HE *entry;
     SV *sv;
@@ -184,15 +183,14 @@ Perl_hv_fetch(pTHX_ HV *hv, const char *key, I32 klen, I32 lval)
 #endif
     }
 
-    xhv = (XPVHV*)SvANY(hv);
-    if (!xhv->xhv_array) {
+    if (!HvARRAY(hv)) {
        if (lval
 #ifdef DYNAMIC_ENV_FETCH  /* if it's an %ENV lookup, we may get it on the fly */
                 || mg_find((SV*)hv, PERL_MAGIC_env)
 #endif
                                                                  )
-           Newz(503, xhv->xhv_array,
-                PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
+           Newz(503, HvARRAY(hv),
+                PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1), char);
        else
            return 0;
     }
@@ -207,7 +205,7 @@ Perl_hv_fetch(pTHX_ HV *hv, const char *key, I32 klen, I32 lval)
 
     PERL_HASH(hash, key, klen);
 
-    entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     for (; entry; entry = HeNEXT(entry)) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
            continue;
@@ -271,7 +269,6 @@ information on how to use this function on tied hashes.
 HE *
 Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash)
 {
-    register XPVHV* xhv;
     register char *key;
     STRLEN klen;
     register HE *entry;
@@ -313,15 +310,14 @@ Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash)
 #endif
     }
 
-    xhv = (XPVHV*)SvANY(hv);
-    if (!xhv->xhv_array) {
+    if (!HvARRAY(hv)) {
        if (lval
 #ifdef DYNAMIC_ENV_FETCH  /* if it's an %ENV lookup, we may get it on the fly */
                 || mg_find((SV*)hv, PERL_MAGIC_env)
 #endif
                                                                  )
-           Newz(503, xhv->xhv_array,
-                PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
+           Newz(503, HvARRAY(hv),
+                PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1), char);
        else
            return 0;
     }
@@ -335,7 +331,7 @@ Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash)
     if (!hash)
        PERL_HASH(hash, key, klen);
 
-    entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     for (; entry; entry = HeNEXT(entry)) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
            continue;
@@ -409,7 +405,6 @@ information on how to use this function on tied hashes.
 SV**
 Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 hash)
 {
-    register XPVHV* xhv;
     register I32 i;
     register HE *entry;
     register HE **oentry;
@@ -424,14 +419,13 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has
       is_utf8 = TRUE;
     }
 
-    xhv = (XPVHV*)SvANY(hv);
     if (SvMAGICAL(hv)) {
        bool needs_copy;
        bool needs_store;
        hv_magic_check (hv, &needs_copy, &needs_store);
        if (needs_copy) {
            mg_copy((SV*)hv, val, key, klen);
-           if (!xhv->xhv_array && !needs_store)
+           if (!HvARRAY(hv) && !needs_store)
                return 0;
 #ifdef ENV_IS_CASELESS
            else if (mg_find((SV*)hv, PERL_MAGIC_env)) {
@@ -452,11 +446,11 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has
     if (!hash)
        PERL_HASH(hash, key, klen);
 
-    if (!xhv->xhv_array)
-       Newz(505, xhv->xhv_array,
-            PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
+    if (!HvARRAY(hv))
+       Newz(505, HvARRAY(hv),
+            PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1), char);
 
-    oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     i = 1;
 
     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
@@ -486,10 +480,10 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has
     HeNEXT(entry) = *oentry;
     *oentry = entry;
 
-    xhv->xhv_keys++;
+    HvKEYS(hv)++;
     if (i) {                           /* initial entry? */
-       ++xhv->xhv_fill;
-       if (xhv->xhv_keys > xhv->xhv_max)
+       HvFILL(hv)++;
+       if (HvKEYS(hv) > HvMAX(hv))
            hsplit(hv);
     }
 
@@ -518,7 +512,6 @@ information on how to use this function on tied hashes.
 HE *
 Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
 {
-    register XPVHV* xhv;
     register char *key;
     STRLEN klen;
     register I32 i;
@@ -530,7 +523,6 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
     if (!hv)
        return 0;
 
-    xhv = (XPVHV*)SvANY(hv);
     if (SvMAGICAL(hv)) {
        bool needs_copy;
        bool needs_store;
@@ -542,7 +534,7 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
            keysv = sv_2mortal(newSVsv(keysv));
            mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY);
            TAINT_IF(save_taint);
-           if (!xhv->xhv_array && !needs_store)
+           if (!HvARRAY(hv) && !needs_store)
                return Nullhe;
 #ifdef ENV_IS_CASELESS
            else if (mg_find((SV*)hv, PERL_MAGIC_env)) {
@@ -564,11 +556,11 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
     if (!hash)
        PERL_HASH(hash, key, klen);
 
-    if (!xhv->xhv_array)
-       Newz(505, xhv->xhv_array,
-            PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
+    if (!HvARRAY(hv))
+       Newz(505, HvARRAY(hv),
+            PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1), char);
 
-    oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     i = 1;
 
     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
@@ -598,10 +590,10 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
     HeNEXT(entry) = *oentry;
     *oentry = entry;
 
-    xhv->xhv_keys++;
+    HvKEYS(hv)++;
     if (i) {                           /* initial entry? */
-       ++xhv->xhv_fill;
-       if (xhv->xhv_keys > xhv->xhv_max)
+       HvFILL(hv)++;
+       if (HvKEYS(hv) > HvMAX(hv))
            hsplit(hv);
     }
 
@@ -622,7 +614,6 @@ will be returned.
 SV *
 Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags)
 {
-    register XPVHV* xhv;
     register I32 i;
     register U32 hash;
     register HE *entry;
@@ -662,8 +653,7 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags)
 #endif
         }
     }
-    xhv = (XPVHV*)SvANY(hv);
-    if (!xhv->xhv_array)
+    if (!HvARRAY(hv))
        return Nullsv;
 
     if (is_utf8 && !(PL_hints & HINT_UTF8_DISTINCT)) {
@@ -675,7 +665,7 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags)
 
     PERL_HASH(hash, key, klen);
 
-    oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     entry = *oentry;
     i = 1;
     for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
@@ -691,18 +681,18 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags)
            Safefree(key);
        *oentry = HeNEXT(entry);
        if (i && !*oentry)
-           xhv->xhv_fill--;
+           HvFILL(hv)--;
        if (flags & G_DISCARD)
            sv = Nullsv;
        else {
            sv = sv_2mortal(HeVAL(entry));
            HeVAL(entry) = &PL_sv_undef;
        }
-       if (entry == xhv->xhv_eiter)
+       if (entry == HvEITER(hv))
            HvLAZYDEL_on(hv);
        else
            hv_free_ent(hv, entry);
-       --xhv->xhv_keys;
+       HvKEYS(hv)--;
        return sv;
     }
     if (key != keysave)
@@ -724,7 +714,6 @@ precomputed hash value, or 0 to ask for it to be computed.
 SV *
 Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash)
 {
-    register XPVHV* xhv;
     register I32 i;
     register char *key;
     STRLEN klen;
@@ -762,8 +751,7 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash)
 #endif
        }
     }
-    xhv = (XPVHV*)SvANY(hv);
-    if (!xhv->xhv_array)
+    if (!HvARRAY(hv))
        return Nullsv;
 
     keysave = key = SvPV(keysv, klen);
@@ -775,7 +763,7 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash)
     if (!hash)
        PERL_HASH(hash, key, klen);
 
-    oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     entry = *oentry;
     i = 1;
     for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
@@ -791,18 +779,18 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash)
            Safefree(key);
        *oentry = HeNEXT(entry);
        if (i && !*oentry)
-           xhv->xhv_fill--;
+           HvFILL(hv)--;
        if (flags & G_DISCARD)
            sv = Nullsv;
        else {
            sv = sv_2mortal(HeVAL(entry));
            HeVAL(entry) = &PL_sv_undef;
        }
-       if (entry == xhv->xhv_eiter)
+       if (entry == HvEITER(hv))
            HvLAZYDEL_on(hv);
        else
            hv_free_ent(hv, entry);
-       --xhv->xhv_keys;
+       HvKEYS(hv)--;
        return sv;
     }
     if (key != keysave)
@@ -822,7 +810,6 @@ C<klen> is the length of the key.
 bool
 Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen)
 {
-    register XPVHV* xhv;
     register U32 hash;
     register HE *entry;
     SV *sv;
@@ -852,9 +839,8 @@ Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen)
 #endif
     }
 
-    xhv = (XPVHV*)SvANY(hv);
 #ifndef DYNAMIC_ENV_FETCH
-    if (!xhv->xhv_array)
+    if (!HvARRAY(hv))
        return 0;
 #endif
 
@@ -868,10 +854,10 @@ Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen)
     PERL_HASH(hash, key, klen);
 
 #ifdef DYNAMIC_ENV_FETCH
-    if (!xhv->xhv_array) entry = Null(HE*);
+    if (!HvARRAY(hv)) entry = Null(HE*);
     else
 #endif
-    entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     for (; entry; entry = HeNEXT(entry)) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
            continue;
@@ -916,7 +902,6 @@ computed.
 bool
 Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
 {
-    register XPVHV* xhv;
     register char *key;
     STRLEN klen;
     register HE *entry;
@@ -946,9 +931,8 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
 #endif
     }
 
-    xhv = (XPVHV*)SvANY(hv);
 #ifndef DYNAMIC_ENV_FETCH
-    if (!xhv->xhv_array)
+    if (!HvARRAY(hv))
        return 0;
 #endif
 
@@ -960,10 +944,10 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
        PERL_HASH(hash, key, klen);
 
 #ifdef DYNAMIC_ENV_FETCH
-    if (!xhv->xhv_array) entry = Null(HE*);
+    if (!HvARRAY(hv)) entry = Null(HE*);
     else
 #endif
-    entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     for (; entry; entry = HeNEXT(entry)) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
            continue;
@@ -997,11 +981,10 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
 STATIC void
 S_hsplit(pTHX_ HV *hv)
 {
-    register XPVHV* xhv = (XPVHV*)SvANY(hv);
-    I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */
+    I32 oldsize = (I32) HvMAX(hv) + 1; /* sic(k) */
     register I32 newsize = oldsize * 2;
     register I32 i;
-    register char *a = xhv->xhv_array;
+    register char *a = (char *)HvARRAY(hv);
     register HE **aep;
     register HE **bep;
     register HE *entry;
@@ -1020,18 +1003,18 @@ S_hsplit(pTHX_ HV *hv)
       PL_nomemok = FALSE;
       return;
     }
-    Copy(xhv->xhv_array, a, oldsize * sizeof(HE*), char);
+    Copy(HvARRAY(hv), a, oldsize * sizeof(HE*), char);
     if (oldsize >= 64) {
-       offer_nice_chunk(xhv->xhv_array, PERL_HV_ARRAY_ALLOC_BYTES(oldsize));
+       offer_nice_chunk(HvARRAY(hv), PERL_HV_ARRAY_ALLOC_BYTES(oldsize));
     }
     else
-       Safefree(xhv->xhv_array);
+       Safefree(HvARRAY(hv));
 #endif
 
     PL_nomemok = FALSE;
     Zero(&a[oldsize * sizeof(HE*)], (newsize-oldsize) * sizeof(HE*), char);    /* zero 2nd half*/
-    xhv->xhv_max = --newsize;
-    xhv->xhv_array = a;
+    HvMAX(hv) = --newsize;
+    HvARRAY(hv) = a;
     aep = (HE**)a;
 
     for (i=0; i<oldsize; i++,aep++) {
@@ -1043,7 +1026,7 @@ S_hsplit(pTHX_ HV *hv)
                *oentry = HeNEXT(entry);
                HeNEXT(entry) = *bep;
                if (!*bep)
-                   xhv->xhv_fill++;
+                   HvFILL(hv)++;
                *bep = entry;
                continue;
            }
@@ -1051,15 +1034,14 @@ S_hsplit(pTHX_ HV *hv)
                oentry = &HeNEXT(entry);
        }
        if (!*aep)                              /* everything moved */
-           xhv->xhv_fill--;
+           HvFILL(hv)--;
     }
 }
 
 void
 Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
 {
-    register XPVHV* xhv = (XPVHV*)SvANY(hv);
-    I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */
+    I32 oldsize = (I32) HvMAX(hv) + 1; /* sic(k) */
     register I32 newsize;
     register I32 i;
     register I32 j;
@@ -1079,7 +1061,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
     if (newsize < newmax)
        return;                                 /* overflow detection */
 
-    a = xhv->xhv_array;
+    a = (char *)HvARRAY(hv);
     if (a) {
        PL_nomemok = TRUE;
 #if defined(STRANGE_MALLOC) || defined(MYMALLOC)
@@ -1094,12 +1076,12 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
          PL_nomemok = FALSE;
          return;
        }
-       Copy(xhv->xhv_array, a, oldsize * sizeof(HE*), char);
+       Copy(HvARRAY(hv), a, oldsize * sizeof(HE*), char);
        if (oldsize >= 64) {
-           offer_nice_chunk(xhv->xhv_array, PERL_HV_ARRAY_ALLOC_BYTES(oldsize));
+           offer_nice_chunk(HvARRAY(hv), PERL_HV_ARRAY_ALLOC_BYTES(oldsize));
        }
        else
-           Safefree(xhv->xhv_array);
+           Safefree(HvARRAY(hv));
 #endif
        PL_nomemok = FALSE;
        Zero(&a[oldsize * sizeof(HE*)], (newsize-oldsize) * sizeof(HE*), char); /* zero 2nd half*/
@@ -1107,9 +1089,9 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
     else {
        Newz(0, a, PERL_HV_ARRAY_ALLOC_BYTES(newsize), char);
     }
-    xhv->xhv_max = --newsize;
-    xhv->xhv_array = a;
-    if (!xhv->xhv_fill)                                /* skip rest if no entries */
+    HvMAX(hv) = --newsize;
+    HvARRAY(hv) = a;
+    if (!HvFILL(hv))                           /* skip rest if no entries */
        return;
 
     aep = (HE**)a;
@@ -1121,7 +1103,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
                j -= i;
                *oentry = HeNEXT(entry);
                if (!(HeNEXT(entry) = aep[j]))
-                   xhv->xhv_fill++;
+                   HvFILL(hv)++;
                aep[j] = entry;
                continue;
            }
@@ -1129,7 +1111,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
                oentry = &HeNEXT(entry);
        }
        if (!*aep)                              /* everything moved */
-           xhv->xhv_fill--;
+           HvFILL(hv)--;
     }
 }
 
@@ -1145,19 +1127,17 @@ HV *
 Perl_newHV(pTHX)
 {
     register HV *hv;
-    register XPVHV* xhv;
 
     hv = (HV*)NEWSV(502,0);
     sv_upgrade((SV *)hv, SVt_PVHV);
-    xhv = (XPVHV*)SvANY(hv);
     SvPOK_off(hv);
     SvNOK_off(hv);
 #ifndef NODEFAULT_SHAREKEYS
     HvSHAREKEYS_on(hv);         /* key-sharing on by default */
 #endif
-    xhv->xhv_max = 7;          /* start with 8 buckets */
-    xhv->xhv_fill = 0;
-    xhv->xhv_pmroot = 0;
+    HvMAX(hv) = 7;             /* start with 8 buckets */
+    HvFILL(hv) = 0;
+    HvPMROOT(hv) = 0;
     (void)hv_iterinit(hv);     /* so each() will start off right */
     return hv;
 }
@@ -1252,15 +1232,13 @@ Clears a hash, making it empty.
 void
 Perl_hv_clear(pTHX_ HV *hv)
 {
-    register XPVHV* xhv;
     if (!hv)
        return;
-    xhv = (XPVHV*)SvANY(hv);
     hfreeentries(hv);
-    xhv->xhv_fill = 0;
-    xhv->xhv_keys = 0;
-    if (xhv->xhv_array)
-       (void)memzero(xhv->xhv_array, (xhv->xhv_max + 1) * sizeof(HE*));
+    HvFILL(hv) = 0;
+    HvKEYS(hv) = 0;
+    if (HvARRAY(hv))
+       (void)memzero(HvARRAY(hv), (HvMAX(hv) + 1) * sizeof(HE*));
 
     if (SvRMAGICAL(hv))
        mg_clear((SV*)hv);
@@ -1310,20 +1288,18 @@ Undefines the hash.
 void
 Perl_hv_undef(pTHX_ HV *hv)
 {
-    register XPVHV* xhv;
     if (!hv)
        return;
-    xhv = (XPVHV*)SvANY(hv);
     hfreeentries(hv);
-    Safefree(xhv->xhv_array);
+    Safefree(HvARRAY(hv));
     if (HvNAME(hv)) {
        Safefree(HvNAME(hv));
        HvNAME(hv) = 0;
     }
-    xhv->xhv_array = 0;
-    xhv->xhv_max = 7;          /* it's a normal hash */
-    xhv->xhv_fill = 0;
-    xhv->xhv_keys = 0;
+    HvARRAY(hv) = 0;
+    HvMAX(hv)   = 7;           /* it's a normal hash */
+    HvFILL(hv)  = 0;
+    HvKEYS(hv)  = 0;
 
     if (SvRMAGICAL(hv))
        mg_clear((SV*)hv);
@@ -1346,20 +1322,18 @@ value, you can get it through the macro C<HvFILL(tb)>.
 I32
 Perl_hv_iterinit(pTHX_ HV *hv)
 {
-    register XPVHV* xhv;
     HE *entry;
 
     if (!hv)
        Perl_croak(aTHX_ "Bad hash");
-    xhv = (XPVHV*)SvANY(hv);
-    entry = xhv->xhv_eiter;
+    entry = HvEITER(hv);
     if (entry && HvLAZYDEL(hv)) {      /* was deleted earlier? */
        HvLAZYDEL_off(hv);
        hv_free_ent(hv, entry);
     }
-    xhv->xhv_riter = -1;
-    xhv->xhv_eiter = Null(HE*);
-    return xhv->xhv_keys;      /* used to be xhv->xhv_fill before 5.004_65 */
+    HvRITER(hv) = -1;
+    HvEITER(hv) = Null(HE*);
+    return HvKEYS(hv);         /* used to be xhv->xhv_fill before 5.004_65 */
 }
 
 /*
@@ -1373,15 +1347,13 @@ Returns entries from a hash iterator.  See C<hv_iterinit>.
 HE *
 Perl_hv_iternext(pTHX_ HV *hv)
 {
-    register XPVHV* xhv;
     register HE *entry;
     HE *oldentry;
     MAGIC* mg;
 
     if (!hv)
        Perl_croak(aTHX_ "Bad hash");
-    xhv = (XPVHV*)SvANY(hv);
-    oldentry = entry = xhv->xhv_eiter;
+    oldentry = entry = HvEITER(hv);
 
     if ((mg = SvTIED_mg((SV*)hv, PERL_MAGIC_tied))) {
        SV *key = sv_newmortal();
@@ -1393,7 +1365,7 @@ Perl_hv_iternext(pTHX_ HV *hv)
            char *k;
            HEK *hek;
 
-           xhv->xhv_eiter = entry = new_HE();  /* one HE per MAGICAL hash */
+           HvEITER(hv) = entry = new_HE();  /* one HE per MAGICAL hash */
            Zero(entry, 1, HE);
            Newz(54, k, HEK_BASESIZE + sizeof(SV*), char);
            hek = (HEK*)k;
@@ -1410,7 +1382,7 @@ Perl_hv_iternext(pTHX_ HV *hv)
            SvREFCNT_dec(HeVAL(entry));
        Safefree(HeKEY_hek(entry));
        del_HE(entry);
-       xhv->xhv_eiter = Null(HE*);
+       HvEITER(hv) = Null(HE*);
        return Null(HE*);
     }
 #ifdef DYNAMIC_ENV_FETCH  /* set up %ENV for iteration */
@@ -1418,18 +1390,18 @@ Perl_hv_iternext(pTHX_ HV *hv)
        prime_env_iter();
 #endif
 
-    if (!xhv->xhv_array)
-       Newz(506, xhv->xhv_array,
-            PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
+    if (!HvARRAY(hv))
+       Newz(506, HvARRAY(hv),
+            PERL_HV_ARRAY_ALLOC_BYTES(HvMAX(hv) + 1), char);
     if (entry)
        entry = HeNEXT(entry);
     while (!entry) {
-       ++xhv->xhv_riter;
-       if (xhv->xhv_riter > xhv->xhv_max) {
-           xhv->xhv_riter = -1;
+       HvRITER(hv)++;
+       if (HvRITER(hv) > HvMAX(hv)) {
+           HvRITER(hv) = -1;
            break;
        }
-       entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter];
+       entry = (HvARRAY(hv))[HvRITER(hv)];
     }
 
     if (oldentry && HvLAZYDEL(hv)) {           /* was deleted earlier? */
@@ -1437,7 +1409,7 @@ Perl_hv_iternext(pTHX_ HV *hv)
        hv_free_ent(hv, oldentry);
     }
 
-    xhv->xhv_eiter = entry;
+    HvEITER(hv) = entry;
     return entry;
 }
 
@@ -1555,7 +1527,7 @@ Perl_sharepvn(pTHX_ const char *sv, I32 len, U32 hash)
 void
 Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
 {
-    register XPVHV* xhv;
+    HV *hv;
     register HE *entry;
     register HE **oentry;
     register I32 i = 1;
@@ -1579,10 +1551,10 @@ Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
        if (--*Svp == Nullsv)
            hv_delete(PL_strtab, str, len, G_DISCARD, hash);
     } */
-    xhv = (XPVHV*)SvANY(PL_strtab);
     /* assert(xhv_array != 0) */
+    hv = PL_strtab;
     LOCK_STRTAB_MUTEX;
-    oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
            continue;
@@ -1596,10 +1568,10 @@ Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
        if (--HeVAL(entry) == Nullsv) {
            *oentry = HeNEXT(entry);
            if (i && !*oentry)
-               xhv->xhv_fill--;
+               HvFILL(hv)--;
            Safefree(HeKEY_hek(entry));
            del_HE(entry);
-           --xhv->xhv_keys;
+           HvKEYS(hv)--;
        }
        break;
     }
@@ -1617,7 +1589,7 @@ Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
 HEK *
 Perl_share_hek(pTHX_ const char *str, I32 len, register U32 hash)
 {
-    register XPVHV* xhv;
+    HV *hv;
     register HE *entry;
     register HE **oentry;
     register I32 i = 1;
@@ -1641,10 +1613,10 @@ Perl_share_hek(pTHX_ const char *str, I32 len, register U32 hash)
     if (!(Svp = hv_fetch(PL_strtab, str, len, FALSE)))
        hv_store(PL_strtab, str, len, Nullsv, hash);
     */
-    xhv = (XPVHV*)SvANY(PL_strtab);
     /* assert(xhv_array != 0) */
+    hv = PL_strtab;
     LOCK_STRTAB_MUTEX;
-    oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+    oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)];
     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
            continue;
@@ -1663,11 +1635,11 @@ Perl_share_hek(pTHX_ const char *str, I32 len, register U32 hash)
        HeVAL(entry) = Nullsv;
        HeNEXT(entry) = *oentry;
        *oentry = entry;
-       xhv->xhv_keys++;
+       HvKEYS(hv)++;
        if (i) {                                /* initial entry? */
-           ++xhv->xhv_fill;
-           if (xhv->xhv_keys > xhv->xhv_max)
-               hsplit(PL_strtab);
+           HvFILL(hv)++;
+           if (HvKEYS(hv) > HvMAX(hv))
+               hsplit(hv);
        }
     }