Change 30683 by [EMAIL PROTECTED] on 2007/03/22 14:00:14

        Re-order the flags values for struct refcounted_he to allow the
        possibility of storing 2 futher types. Add a void * to the union
        as it won't increase the size, but may become useful.

Affected files ...

... //depot/perl/hv.c#342 edit
... //depot/perl/hv.h#100 edit

Differences ...

==== //depot/perl/hv.c#342 (text) ====
Index: perl/hv.c
--- perl/hv.c#341~30440~        2007-03-01 09:46:49.000000000 -0800
+++ perl/hv.c   2007-03-22 07:00:14.000000000 -0700
@@ -2581,11 +2581,13 @@
        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_type(SVt_PV);
@@ -2595,7 +2597,7 @@
        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:
@@ -2605,14 +2607,6 @@
     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
 
@@ -2821,7 +2815,6 @@
        value_len = 0;
        key_offset = 1;
     }
-    flags = value_type;
 
 #ifdef USE_ITHREADS
     he = (struct refcounted_he*)
@@ -2840,17 +2833,19 @@
     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.

==== //depot/perl/hv.h#100 (text) ====
Index: perl/hv.h
--- perl/hv.h#99~30520~ 2007-03-08 08:31:36.000000000 -0800
+++ perl/hv.h   2007-03-22 07:00:14.000000000 -0700
@@ -390,6 +390,8 @@
    between threads (because it hangs from OPs, which are shared), hence the
    alternate definition and mutex.  */
 
+struct refcounted_he;
+
 #ifdef PERL_CORE
 
 /* Gosh. This really isn't a good name any longer.  */
@@ -406,6 +408,7 @@
        IV                refcounted_he_u_iv;
        UV                refcounted_he_u_uv;
        STRLEN            refcounted_he_u_len;
+       void             *refcounted_he_u_ptr;  /* Might be useful in future */
     } refcounted_he_val;
     /* First byte is flags. Then NUL-terminated value. Then for ithreads,
        non-NUL terminated key.  */
@@ -414,12 +417,22 @@
 
 /* Flag bits are HVhek_UTF8, HVhek_WASUTF8, then */
 #define HVrhek_undef   0x00 /* Value is undef. */
-#define HVrhek_PV      0x10 /* Value is a string. */
-#define HVrhek_IV      0x20 /* Value is IV/UV. */
-#define HVrhek_delete  0x30 /* Value is placeholder - signifies delete. */
-#define HVrhek_typemask        0x30
-#define HVrhek_UTF8    0x40 /* string value is utf8. */
-#define HVrhek_UV      0x40 /* integer value is UV. */
+#define HVrhek_delete  0x10 /* Value is placeholder - signifies delete. */
+#define HVrhek_IV      0x20 /* Value is IV. */
+#define HVrhek_UV      0x30 /* Value is UV. */
+#define HVrhek_PV      0x40 /* Value is a (byte) string. */
+#define HVrhek_PV_UTF8 0x50 /* Value is a (utf8) string. */
+/* Two spare. As these have to live in the optree, you can't store anything
+   interpreter specific, such as SVs. :-( */
+#define HVrhek_typemask 0x70
+
+#ifdef USE_ITHREADS
+/* A big expression to find the key offset */
+#define REF_HE_KEY(chain)                                              \
+       ((((chain->refcounted_he_data[0] & 0x60) == 0x40)               \
+           ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0)     \
+        + 1 + chain->refcounted_he_data)
+#endif
 
 #  ifdef USE_ITHREADS
 #    define HINTS_REFCNT_LOCK          MUTEX_LOCK(&PL_hints_mutex)
End of Patch.

Reply via email to