X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.c;h=4266e8be9b05305a934fc72b03f95449f2d38b03;hb=19b95bf092bc6fdb9455fe107fc46111b0a1ec31;hp=bc1e305fdf288d678ac72d48e9ae5257a757648e;hpb=fd7de8a8466b26f91b016c44f0d429fd3725d9d0;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.c b/hv.c index bc1e305..4266e8b 100644 --- a/hv.c +++ b/hv.c @@ -43,7 +43,7 @@ S_more_he(pTHX) HE* he; HE* heend; - he = (HE*) Perl_get_arena(aTHX_ PERL_ARENA_SIZE); + he = (HE*) Perl_get_arena(aTHX_ PERL_ARENA_SIZE, HE_SVSLOT); heend = &he[PERL_ARENA_SIZE / sizeof(HE) - 1]; PL_body_roots[HE_SVSLOT] = he; @@ -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 by walking up the tree starting at the passed +Generates and returns a C by walking up the tree starting at the passed in C. =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.