make tr/// threadsafe by moving swash into pad
Dave Mitchell [Fri, 12 Jan 2007 10:42:05 +0000 (10:42 +0000)]
p4raw-id: //depot/perl@29765

doop.c
op.c

diff --git a/doop.c b/doop.c
index d5cef28..dc525d3 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -307,7 +307,12 @@ S_do_trans_simple_utf8(pTHX_ SV * const sv)
     const I32 grows = PL_op->op_private & OPpTRANS_GROWS;
     STRLEN len;
 
-    SV* const  rv = (SV*)cSVOP->op_sv;
+    SV* const  rv =
+#ifdef USE_ITHREADS
+                   PAD_SVl(cPADOP->op_padix);
+#else
+                   (SV*)cSVOP->op_sv;
+#endif
     HV* const  hv = (HV*)SvRV(rv);
     SV* const * svp = hv_fetchs(hv, "NONE", FALSE);
     const UV none = svp ? SvUV(*svp) : 0x7fffffff;
@@ -403,7 +408,12 @@ S_do_trans_count_utf8(pTHX_ SV * const sv)
     I32 matches = 0;
     STRLEN len;
 
-    SV* const rv = (SV*)cSVOP->op_sv;
+    SV* const  rv =
+#ifdef USE_ITHREADS
+                   PAD_SVl(cPADOP->op_padix);
+#else
+                   (SV*)cSVOP->op_sv;
+#endif
     HV* const hv = (HV*)SvRV(rv);
     SV* const * const svp = hv_fetchs(hv, "NONE", FALSE);
     const UV none = svp ? SvUV(*svp) : 0x7fffffff;
@@ -447,7 +457,12 @@ S_do_trans_complex_utf8(pTHX_ SV * const sv)
     const I32 squash   = PL_op->op_private & OPpTRANS_SQUASH;
     const I32 del      = PL_op->op_private & OPpTRANS_DELETE;
     const I32 grows    = PL_op->op_private & OPpTRANS_GROWS;
-    SV * const rv = (SV*)cSVOP->op_sv;
+    SV* const  rv =
+#ifdef USE_ITHREADS
+                   PAD_SVl(cPADOP->op_padix);
+#else
+                   (SV*)cSVOP->op_sv;
+#endif
     HV * const hv = (HV*)SvRV(rv);
     SV * const *svp = hv_fetchs(hv, "NONE", FALSE);
     const UV none = svp ? SvUV(*svp) : 0x7fffffff;
diff --git a/op.c b/op.c
index 1f7e13d..f0f26dc 100644 (file)
--- a/op.c
+++ b/op.c
@@ -438,8 +438,15 @@ Perl_op_clear(pTHX_ OP *o)
        /* FALL THROUGH */
     case OP_TRANS:
        if (o->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) {
+#ifdef USE_ITHREADS
+           if (cPADOPo->op_padix > 0) {
+               pad_swipe(cPADOPo->op_padix, TRUE);
+               cPADOPo->op_padix = 0;
+           }
+#else
            SvREFCNT_dec(cSVOPo->op_sv);
            cSVOPo->op_sv = NULL;
+#endif
        }
        else {
            PerlMemShared_free(cPVOPo->op_pv);
@@ -2829,6 +2836,7 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
     const I32 complement = o->op_private & OPpTRANS_COMPLEMENT;
     const I32 squash     = o->op_private & OPpTRANS_SQUASH;
     I32 del              = o->op_private & OPpTRANS_DELETE;
+    SV* swash;
     PL_hints |= HINT_BLOCK_SCOPE;
 
     if (SvUTF8(tstr))
@@ -3024,12 +3032,21 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
 
        PerlMemShared_free(cPVOPo->op_pv);
        cPVOPo->op_pv = NULL;
-       cSVOPo->op_sv = (SV*)swash_init("utf8", "", listsv, bits, none);
+
+       swash = (SV*)swash_init("utf8", "", listsv, bits, none);
+#ifdef USE_ITHREADS
+       cPADOPo->op_padix = pad_alloc(OP_TRANS, SVs_PADTMP);
+       SvREFCNT_dec(PAD_SVl(cPADOPo->op_padix));
+       PAD_SETSV(cPADOPo->op_padix, swash);
+       SvPADTMP_on(swash);
+#else
+       cSVOPo->op_sv = swash;
+#endif
        SvREFCNT_dec(listsv);
        SvREFCNT_dec(transv);
 
        if (!del && havefinal && rlen)
-           (void)hv_store((HV*)SvRV((cSVOPo->op_sv)), "FINAL", 5,
+           (void)hv_store((HV*)SvRV(swash), "FINAL", 5,
                           newSVuv((UV)final), 0);
 
        if (grows)