This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
cflags.SH: 30327 wasn't portable Bourne (avoid '!: not found')
[perl5.git] / hv.c
diff --git a/hv.c b/hv.c
index b7f53a9..4266e8b 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -68,23 +68,19 @@ S_new_he(pTHX)
     HE* he;
     void ** const root = &PL_body_roots[HE_SVSLOT];
 
-    LOCK_SV_MUTEX;
     if (!*root)
        S_more_he(aTHX);
     he = (HE*) *root;
     assert(he);
     *root = HeNEXT(he);
-    UNLOCK_SV_MUTEX;
     return he;
 }
 
 #define new_HE() new_he()
 #define del_HE(p) \
     STMT_START { \
-       LOCK_SV_MUTEX; \
        HeNEXT(p) = (HE*)(PL_body_roots[HE_SVSLOT]);    \
        PL_body_roots[HE_SVSLOT] = p; \
-       UNLOCK_SV_MUTEX; \
     } STMT_END
 
 
@@ -1401,12 +1397,9 @@ HV *
 Perl_newHV(pTHX)
 {
     register XPVHV* xhv;
-    HV * const hv = (HV*)newSV(0);
-
-    sv_upgrade((SV *)hv, SVt_PVHV);
+    HV * const hv = (HV*)newSV_type(SVt_PVHV);
     xhv = (XPVHV*)SvANY(hv);
-    SvPOK_off(hv);
-    SvNOK_off(hv);
+    assert(!SvOK(hv));
 #ifndef NODEFAULT_SHAREKEYS
     HvSHAREKEYS_on(hv);         /* key-sharing on by default */
 #endif
@@ -2296,6 +2289,7 @@ Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
 void
 Perl_unshare_hek(pTHX_ HEK *hek)
 {
+    assert(hek);
     unshare_hek_or_pvn(hek, NULL, 0, 0);
 }
 
@@ -2587,22 +2581,23 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he)
        value = &PL_sv_placeholder;
        break;
     case HVrhek_IV:
-       value = (he->refcounted_he_data[0] & HVrhek_UV)
-           ? newSVuv(he->refcounted_he_val.refcounted_he_u_iv)
-           : newSViv(he->refcounted_he_val.refcounted_he_u_uv);
+       value = newSViv(he->refcounted_he_val.refcounted_he_u_iv);
+       break;
+    case HVrhek_UV:
+       value = newSVuv(he->refcounted_he_val.refcounted_he_u_uv);
        break;
     case HVrhek_PV:
+    case HVrhek_PV_UTF8:
        /* Create a string SV that directly points to the bytes in our
           structure.  */
-       value = newSV(0);
-       sv_upgrade(value, SVt_PV);
+       value = newSV_type(SVt_PV);
        SvPV_set(value, (char *) he->refcounted_he_data + 1);
        SvCUR_set(value, he->refcounted_he_val.refcounted_he_u_len);
        /* This stops anything trying to free it  */
        SvLEN_set(value, 0);
        SvPOK_on(value);
        SvREADONLY_on(value);
-       if (he->refcounted_he_data[0] & HVrhek_UTF8)
+       if ((he->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV_UTF8)
            SvUTF8_on(value);
        break;
     default:
@@ -2612,18 +2607,10 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he)
     return value;
 }
 
-#ifdef USE_ITHREADS
-/* A big expression to find the key offset */
-#define REF_HE_KEY(chain) \
-       ((((chain->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV) \
-           ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0)       \
-        + 1 + chain->refcounted_he_data)
-#endif
-
 /*
 =for apidoc refcounted_he_chain_2hv
 
-Generates an returns a C<HV *> by walking up the tree starting at the passed
+Generates and returns a C<HV *> by walking up the tree starting at the passed
 in C<struct refcounted_he *>.
 
 =cut
@@ -2828,7 +2815,6 @@ Perl_refcounted_he_new(pTHX_ struct refcounted_he *const parent,
        value_len = 0;
        key_offset = 1;
     }
-    flags = value_type;
 
 #ifdef USE_ITHREADS
     he = (struct refcounted_he*)
@@ -2847,17 +2833,19 @@ Perl_refcounted_he_new(pTHX_ struct refcounted_he *const parent,
     if (value_type == HVrhek_PV) {
        Copy(value_p, he->refcounted_he_data + 1, value_len + 1, char);
        he->refcounted_he_val.refcounted_he_u_len = value_len;
-       if (SvUTF8(value)) {
-           flags |= HVrhek_UTF8;
-       }
+       /* Do it this way so that the SvUTF8() test is after the SvPV, in case
+          the value is overloaded, and doesn't yet have the UTF-8flag set.  */
+       if (SvUTF8(value))
+           value_type = HVrhek_PV_UTF8;
     } else if (value_type == HVrhek_IV) {
        if (SvUOK(value)) {
            he->refcounted_he_val.refcounted_he_u_uv = SvUVX(value);
-           flags |= HVrhek_UV;
+           value_type = HVrhek_UV;
        } else {
            he->refcounted_he_val.refcounted_he_u_iv = SvIVX(value);
        }
     }
+    flags = value_type;
 
     if (is_utf8) {
        /* Hash keys are always stored normalised to (yes) ISO-8859-1.