It's possible to write the dup of struct reg_substr_datum with a
Nicholas Clark [Fri, 23 Mar 2007 23:32:19 +0000 (23:32 +0000)]
memcpy() replacing the member by member copy. Curiously gcc's -Os
produces the same sized code, but not all optimisers may manage this.
Also, by reading and re-assigning to the copied data for the sv_dup()s
we hope to avoid any cache misses on the copied from data.

p4raw-id: //depot/perl@30740

regcomp.c

index 8b8cec4..9aa6872 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -8903,8 +8903,7 @@ Perl_re_dup(pTHX_ const regexp *r, CLONE_PARAMS *param)
 {
     dVAR;
     regexp *ret;
-    I32 i, npar;
-    struct reg_substr_datum *s;
+    I32 npar;
 
     if (!r)
        return (REGEXP *)NULL;
@@ -8929,14 +8928,20 @@ Perl_re_dup(pTHX_ const regexp *r, CLONE_PARAMS *param)
     }
 
     if (r->substrs) {
+       struct reg_substr_datum *s;
+       const struct reg_substr_datum *s_end;
+
         Newx(ret->substrs, 1, struct reg_substr_data);
-        for (s = ret->substrs->data, i = 0; i < 3; i++, s++) {
-            s->min_offset = r->substrs->data[i].min_offset;
-            s->max_offset = r->substrs->data[i].max_offset;
-            s->end_shift  = r->substrs->data[i].end_shift;
-            s->substr     = sv_dup_inc(r->substrs->data[i].substr, param);
-            s->utf8_substr = sv_dup_inc(r->substrs->data[i].utf8_substr, param);
-        }
+       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);
+
+       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;