On Linux, don't compile with -DTHREADS_HAVE_PIDS if the
[p5sagit/p5-mst-13.2.git] / regcomp.c
index 4a019e1..c58a784 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -8723,8 +8723,6 @@ Perl_reg_temp_copy (pTHX_ struct regexp *r) {
     ret->endp = ret->startp + npar;
     ret->refcnt = 1;
     if (r->substrs) {
-        struct reg_substr_datum *s;
-        I32 i;
         Newx(ret->substrs, 1, struct reg_substr_data);
        StructCopy(r->substrs, ret->substrs, struct reg_substr_data);
 
@@ -8882,12 +8880,11 @@ Perl_regfree_internal(pTHX_ struct regexp *r)
 #define SAVEPVN(p,n)   ((p) ? savepvn(p,n) : NULL)
 
 /* 
-   regdupe - duplicate a regexp. 
-   
-   This routine is called by sv.c's re_dup and is expected to clone a 
-   given regexp structure. It is a no-op when not under USE_ITHREADS. 
-   (Originally this *was* re_dup() for change history see sv.c)
+   re_dup - duplicate a regexp. 
    
+   This routine is expected to clone a given regexp structure. It is not
+   compiler under USE_ITHREADS.
+
    After all of the core data stored in struct regexp is duplicated
    the regexp_engine.dupe method is used to copy any private data
    stored in the *pprivate pointer. This allows extensions to handle
@@ -8912,69 +8909,66 @@ Perl_re_dup(pTHX_ const regexp *r, CLONE_PARAMS *param)
 
     
     npar = r->nparens+1;
-    Newxz(ret, 1, regexp);
+    Newx(ret, 1, regexp);
+    StructCopy(r, ret, regexp);
     Newx(ret->startp, npar * 2, I32);
     Copy(r->startp, ret->startp, npar * 2, I32);
     ret->endp = ret->startp + npar;
-    if(r->swap) {
+    if(ret->swap) {
         Newx(ret->swap, 1, regexp_paren_ofs);
         /* no need to copy these */
         Newx(ret->swap->startp, npar * 2, I32);
        ret->swap->endp = ret->swap->startp + npar;
-    } else {
-        ret->swap = NULL;
     }
 
-    if (r->substrs) {
-       struct reg_substr_datum *s;
-       const struct reg_substr_datum *s_end;
-
+    if (ret->substrs) {
+       /* Do it this way to avoid reading from *r after the StructCopy().
+          That way, if any of the sv_dup_inc()s dislodge *r from the L1
+          cache, it doesn't matter.  */
+       const bool anchored = r->check_substr == r->anchored_substr;
         Newx(ret->substrs, 1, struct reg_substr_data);
        StructCopy(r->substrs, ret->substrs, struct reg_substr_data);
 
-       s = ret->substrs->data;
-       s_end
-           = s + sizeof(ret->substrs->data) / sizeof(struct reg_substr_datum);
+       ret->anchored_substr = sv_dup_inc(ret->anchored_substr, param);
+       ret->anchored_utf8 = sv_dup_inc(ret->anchored_utf8, param);
+       ret->float_substr = sv_dup_inc(ret->float_substr, param);
+       ret->float_utf8 = sv_dup_inc(ret->float_utf8, param);
 
-       do {
-            s->substr      = sv_dup_inc(s->substr, param);
-            s->utf8_substr = sv_dup_inc(s->utf8_substr, param);
-        } while (++s < s_end);
-    } else 
-        ret->substrs = NULL;    
+       /* check_substr and check_utf8, if non-NULL, point to either their
+          anchored or float namesakes, and don't hold a second reference.  */
 
-    ret->wrapped        = SAVEPVN(r->wrapped, r->wraplen+1);
-    ret->precomp        = ret->wrapped + (r->precomp - r->wrapped);
-    ret->prelen         = r->prelen;
-    ret->wraplen        = r->wraplen;
+       if (ret->check_substr) {
+           if (anchored) {
+               assert(r->check_utf8 == r->anchored_utf8);
+               ret->check_substr = ret->anchored_substr;
+               ret->check_utf8 = ret->anchored_utf8;
+           } else {
+               assert(r->check_substr == r->float_substr);
+               assert(r->check_utf8 == r->float_utf8);
+               ret->check_substr = ret->float_substr;
+               ret->check_utf8 = ret->float_utf8;
+           }
+       }
+    }
 
-    ret->mother_re      = NULL;
-    ret->refcnt         = r->refcnt;
-    ret->minlen         = r->minlen;
-    ret->minlenret      = r->minlenret;
-    ret->nparens        = r->nparens;
-    ret->lastparen      = r->lastparen;
-    ret->lastcloseparen = r->lastcloseparen;
-    ret->intflags       = r->intflags;
-    ret->extflags       = r->extflags;
-
-    ret->sublen         = r->sublen;
-
-    ret->engine         = r->engine;
-    
-    ret->paren_names    = hv_dup_inc(r->paren_names, param);
+    ret->wrapped        = SAVEPVN(ret->wrapped, ret->wraplen+1);
+    ret->precomp        = ret->wrapped + (ret->precomp - ret->wrapped);
+    ret->paren_names    = hv_dup_inc(ret->paren_names, param);
+
+    if (ret->pprivate)
+       RXi_SET(ret,CALLREGDUPE_PVT(ret,param));
 
     if (RX_MATCH_COPIED(ret))
-       ret->subbeg  = SAVEPVN(r->subbeg, r->sublen);
+       ret->subbeg  = SAVEPVN(ret->subbeg, ret->sublen);
     else
        ret->subbeg = NULL;
 #ifdef PERL_OLD_COPY_ON_WRITE
     ret->saved_copy = NULL;
 #endif
-    
-    ret->pprivate = r->pprivate;
-    if (ret->pprivate) 
-        RXi_SET(ret,CALLREGDUPE_PVT(ret,param));
+
+    ret->mother_re      = NULL;
+    ret->gofs = 0;
+    ret->seen_evals = 0;
     
     ptr_table_store(PL_ptr_table, r, ret);
     return ret;