Move widecharmap out of the shared structure _reg_trie_data into the
[p5sagit/p5-mst-13.2.git] / regcomp.c
index 0601033..3d1211a 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -798,9 +798,9 @@ S_cl_or(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl, con
 
 #ifdef DEBUGGING
 /*
-   dump_trie(trie)
-   dump_trie_interim_list(trie,next_alloc)
-   dump_trie_interim_table(trie,next_alloc)
+   dump_trie(trie,widecharmap)
+   dump_trie_interim_list(trie,widecharmap,next_alloc)
+   dump_trie_interim_table(trie,widecharmap,next_alloc)
 
    These routines dump out a trie in a somewhat readable format.
    The _interim_ variants are used for debugging the interim
@@ -813,17 +813,16 @@ S_cl_or(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl, con
 */
 
 /*
-  dump_trie(trie)
   Dumps the final compressed table form of the trie to Perl_debug_log.
   Used for debugging make_trie().
 */
  
 STATIC void
-S_dump_trie(pTHX_ const struct _reg_trie_data *trie,U32 depth)
+S_dump_trie(pTHX_ const struct _reg_trie_data *trie, HV *widecharmap, U32 depth)
 {
     U32 state;
     SV *sv=sv_newmortal();
-    int colwidth= trie->widecharmap ? 6 : 4;
+    int colwidth= widecharmap ? 6 : 4;
     GET_RE_DEBUG_FLAGS_DECL;
 
 
@@ -894,18 +893,18 @@ S_dump_trie(pTHX_ const struct _reg_trie_data *trie,U32 depth)
     }
 }    
 /*
-  dump_trie_interim_list(trie,next_alloc)
   Dumps a fully constructed but uncompressed trie in list form.
   List tries normally only are used for construction when the number of 
   possible chars (trie->uniquecharcount) is very high.
   Used for debugging make_trie().
 */
 STATIC void
-S_dump_trie_interim_list(pTHX_ const struct _reg_trie_data *trie, U32 next_alloc,U32 depth)
+S_dump_trie_interim_list(pTHX_ const struct _reg_trie_data *trie,
+                        HV *widecharmap, U32 next_alloc, U32 depth)
 {
     U32 state;
     SV *sv=sv_newmortal();
-    int colwidth= trie->widecharmap ? 6 : 4;
+    int colwidth= widecharmap ? 6 : 4;
     GET_RE_DEBUG_FLAGS_DECL;
     /* print out the table precompression.  */
     PerlIO_printf( Perl_debug_log, "%*sState :Word | Transition Data\n%*s%s",
@@ -947,19 +946,19 @@ S_dump_trie_interim_list(pTHX_ const struct _reg_trie_data *trie, U32 next_alloc
 }    
 
 /*
-  dump_trie_interim_table(trie,next_alloc)
   Dumps a fully constructed but uncompressed trie in table form.
   This is the normal DFA style state transition table, with a few 
   twists to facilitate compression later. 
   Used for debugging make_trie().
 */
 STATIC void
-S_dump_trie_interim_table(pTHX_ const struct _reg_trie_data *trie, U32 next_alloc, U32 depth)
+S_dump_trie_interim_table(pTHX_ const struct _reg_trie_data *trie,
+                         HV *widecharmap, U32 next_alloc, U32 depth)
 {
     U32 state;
     U16 charid;
     SV *sv=sv_newmortal();
-    int colwidth= trie->widecharmap ? 6 : 4;
+    int colwidth= widecharmap ? 6 : 4;
     GET_RE_DEBUG_FLAGS_DECL;
     
     /*
@@ -1204,7 +1203,7 @@ is the recommended Unicode-aware way of saying
                                                                 \
     if ( noper_next < tail ) {                                  \
         if (!trie->jump)                                        \
-            Newxz( trie->jump, word_count + 1, U16);            \
+            trie->jump = PerlMemShared_calloc( word_count + 1, sizeof(U16) ); \
         trie->jump[curword] = (U16)(noper_next - convert);      \
         if (!jumper)                                            \
             jumper = noper_next;                                \
@@ -1218,7 +1217,8 @@ is the recommended Unicode-aware way of saying
         /* we only allocate the nextword buffer when there    */\
         /* a dupe, so first time we have to do the allocation */\
         if (!trie->nextword)                                    \
-            Newxz( trie->nextword, word_count + 1, U16);        \
+            trie->nextword =                                   \
+               PerlMemShared_calloc( word_count + 1, sizeof(U16));     \
         while ( trie->nextword[dupe] )                          \
             dupe= trie->nextword[dupe];                         \
         trie->nextword[dupe]= curword;                          \
@@ -1248,6 +1248,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
     dVAR;
     /* first pass, loop through and scan words */
     reg_trie_data *trie;
+    HV *widecharmap = NULL;
     regnode *cur;
     const U32 uniflags = UTF8_ALLOW_DEFAULT;
     STRLEN len = 0;
@@ -1266,7 +1267,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                          )
                      );
 
-    const U32 data_slot = add_data( pRExC_state, 1, "t" );
+    const U32 data_slot = add_data( pRExC_state, 2, "tu" );
     SV *re_trie_maxbuff;
 #ifndef DEBUGGING
     /* these are only used during construction but are useful during
@@ -1280,14 +1281,14 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
     PERL_UNUSED_ARG(depth);
 #endif
 
-    Newxz( trie, 1, reg_trie_data );
+    trie = PerlMemShared_calloc( 1, sizeof(reg_trie_data) );
     trie->refcount = 1;
     trie->startstate = 1;
     trie->wordcount = word_count;
     RExC_rxi->data->data[ data_slot ] = (void*)trie;
-    Newxz( trie->charmap, 256, U16 );
+    trie->charmap = PerlMemShared_calloc( 256, sizeof(U16) );
     if (!(UTF && folder))
-        Newxz( trie->bitmap, ANYOF_BITMAP_SIZE, char );
+       trie->bitmap = PerlMemShared_calloc( ANYOF_BITMAP_SIZE, 1 );
     DEBUG_r({
         trie->words = newAV();
     });
@@ -1369,10 +1370,10 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                 }
             } else {
                 SV** svpp;
-                if ( !trie->widecharmap )
-                    trie->widecharmap = newHV();
+                if ( !widecharmap )
+                    widecharmap = newHV();
 
-                svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 1 );
+                svpp = hv_fetch( widecharmap, (char*)&uvc, sizeof( UV ), 1 );
 
                 if ( !svpp )
                     Perl_croak( aTHX_ "error creating/fetching widecharmap entry for 0x%"UVXf, uvc );
@@ -1396,11 +1397,11 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
     DEBUG_TRIE_COMPILE_r(
         PerlIO_printf( Perl_debug_log, "%*sTRIE(%s): W:%d C:%d Uq:%d Min:%d Max:%d\n",
                 (int)depth * 2 + 2,"",
-                ( trie->widecharmap ? "UTF8" : "NATIVE" ), (int)word_count,
+                ( widecharmap ? "UTF8" : "NATIVE" ), (int)word_count,
                (int)TRIE_CHARCOUNT(trie), trie->uniquecharcount,
                (int)trie->minlen, (int)trie->maxlen )
     );
-    Newxz( trie->wordlen, word_count, U32 );
+    trie->wordlen = PerlMemShared_calloc( word_count, sizeof(U32) );
 
     /*
         We now know what we are dealing with in terms of unique chars and
@@ -1442,8 +1443,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
         DEBUG_TRIE_COMPILE_MORE_r( PerlIO_printf( Perl_debug_log, 
             "%*sCompiling trie using list compiler\n",
             (int)depth * 2 + 2, ""));
-
-        Newxz( trie->states, TRIE_CHARCOUNT(trie) + 2, reg_trie_state );
+       
+       trie->states = PerlMemShared_calloc( TRIE_CHARCOUNT(trie) + 2,
+                                            sizeof(reg_trie_state) );
         TRIE_LIST_NEW(1);
         next_alloc = 2;
 
@@ -1467,7 +1469,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                     if ( uvc < 256 ) {
                         charid = trie->charmap[ uvc ];
                    } else {
-                        SV** const svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 0);
+                        SV** const svpp = hv_fetch( widecharmap, (char*)&uvc, sizeof( UV ), 0);
                         if ( !svpp ) {
                             charid = 0;
                         } else {
@@ -1507,14 +1509,16 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
 
         /* next alloc is the NEXT state to be allocated */
         trie->statecount = next_alloc; 
-        Renew( trie->states, next_alloc, reg_trie_state );
+        trie->states = PerlMemShared_realloc( trie->states, next_alloc
+                                             * sizeof(reg_trie_state) );
 
         /* and now dump it out before we compress it */
         DEBUG_TRIE_COMPILE_MORE_r(
-            dump_trie_interim_list(trie,next_alloc,depth+1)
+            dump_trie_interim_list(trie,widecharmap,next_alloc,depth+1)
         );
 
-        Newxz( trie->trans, transcount ,reg_trie_trans );
+        trie->trans
+           = PerlMemShared_calloc( transcount, sizeof(reg_trie_trans) );
         {
             U32 state;
             U32 tp = 0;
@@ -1545,7 +1549,10 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                     }
                     if ( transcount < tp + maxid - minid + 1) {
                         transcount *= 2;
-                        Renew( trie->trans, transcount, reg_trie_trans );
+                       trie->trans
+                           = PerlMemShared_realloc( trie->trans,
+                                                    transcount
+                                                    * sizeof(reg_trie_trans) );
                         Zero( trie->trans + (transcount / 2), transcount / 2 , reg_trie_trans );
                     }
                     base = trie->uniquecharcount + tp - minid;
@@ -1625,9 +1632,11 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
             "%*sCompiling trie using table compiler\n",
             (int)depth * 2 + 2, ""));
 
-        Newxz( trie->trans, ( TRIE_CHARCOUNT(trie) + 1 ) * trie->uniquecharcount + 1,
-              reg_trie_trans );
-        Newxz( trie->states, TRIE_CHARCOUNT(trie) + 2, reg_trie_state );
+       trie->trans = PerlMemShared_calloc( ( TRIE_CHARCOUNT(trie) + 1 )
+                                           * trie->uniquecharcount + 1,
+                                           sizeof(reg_trie_trans) );
+        trie->states = PerlMemShared_calloc( TRIE_CHARCOUNT(trie) + 2,
+                                            sizeof(reg_trie_state) );
         next_alloc = trie->uniquecharcount + 1;
 
 
@@ -1655,7 +1664,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                     if ( uvc < 256 ) {
                         charid = trie->charmap[ uvc ];
                     } else {
-                        SV* const * const svpp = hv_fetch( trie->widecharmap, (char*)&uvc, sizeof( UV ), 0);
+                        SV* const * const svpp = hv_fetch( widecharmap, (char*)&uvc, sizeof( UV ), 0);
                         charid = svpp ? (U16)SvIV(*svpp) : 0;
                     }
                     if ( charid ) {
@@ -1679,7 +1688,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
 
         /* and now dump it out before we compress it */
         DEBUG_TRIE_COMPILE_MORE_r(
-            dump_trie_interim_table(trie,next_alloc,depth+1)
+            dump_trie_interim_table(trie,widecharmap,next_alloc,depth+1)
         );
 
         {
@@ -1784,7 +1793,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
             }
         }
         trie->lasttrans = pos + 1;
-        Renew( trie->states, laststate, reg_trie_state);
+        trie->states = PerlMemShared_realloc( trie->states, laststate
+                                             * sizeof(reg_trie_state) );
         DEBUG_TRIE_COMPILE_MORE_r(
                 PerlIO_printf( Perl_debug_log,
                    "%*sAlloc: %d Orig: %"IVdf" elements, Final:%"IVdf". Savings of %%%5.2f\n",
@@ -1804,11 +1814,12 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
                 (UV)trie->lasttrans)
     );
     /* resize the trans array to remove unused space */
-    Renew( trie->trans, trie->lasttrans, reg_trie_trans);
+    trie->trans = PerlMemShared_realloc( trie->trans, trie->lasttrans
+                                        * sizeof(reg_trie_trans) );
 
     /* and now dump out the compressed format */
     DEBUG_TRIE_COMPILE_r(
-        dump_trie(trie,depth+1)
+        dump_trie(trie,widecharmap,depth+1)
     );
 
     {   /* Modify the program and insert the new TRIE node*/ 
@@ -1854,7 +1865,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
         /* But first we check to see if there is a common prefix we can 
            split out as an EXACT and put in front of the TRIE node.  */
         trie->startstate= 1;
-        if ( trie->bitmap && !trie->widecharmap && !trie->jump  ) {
+        if ( trie->bitmap && !widecharmap && !trie->jump  ) {
             U32 state;
             for ( state = 1 ; state < trie->statecount-1 ; state++ ) {
                 U32 ofs = 0;
@@ -1984,7 +1995,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
             {
                 OP( convert ) = TRIEC;
                 Copy(trie->bitmap, ((struct regnode_charclass *)convert)->bitmap, ANYOF_BITMAP_SIZE, char);
-                Safefree(trie->bitmap);
+                PerlMemShared_free(trie->bitmap);
                 trie->bitmap= NULL;
             } else 
                 OP( convert ) = TRIE;
@@ -2018,6 +2029,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *firs
             Set_Node_Offset_Length(convert,mjd_offset,mjd_nodelen);
         });
     } /* end node insert */
+    RExC_rxi->data->data[ data_slot + 1 ] = (void*)widecharmap;
 #ifndef DEBUGGING
     SvREFCNT_dec(TRIE_REVCHARMAP(trie));
 #endif
@@ -2049,7 +2061,8 @@ S_make_trie_failtable(pTHX_ RExC_state_t *pRExC_state, regnode *source,  regnode
    try 'g' and succeed, prodceding to match 'cdgu'.
  */
  /* add a fail transition */
-    reg_trie_data *trie=(reg_trie_data *)RExC_rxi->data->data[ARG(source)];
+    const U32 trie_offset = ARG(source);
+    reg_trie_data *trie=(reg_trie_data *)RExC_rxi->data->data[trie_offset];
     U32 *q;
     const U32 ucharcount = trie->uniquecharcount;
     const U32 numstates = trie->statecount;
@@ -2068,13 +2081,13 @@ S_make_trie_failtable(pTHX_ RExC_state_t *pRExC_state, regnode *source,  regnode
 
 
     ARG_SET( stclass, data_slot );
-    Newxz( aho, 1, reg_ac_data );
+    aho = PerlMemShared_calloc( 1, sizeof(reg_ac_data) );
     RExC_rxi->data->data[ data_slot ] = (void*)aho;
-    aho->trie=trie;
-    aho->states=(reg_trie_state *)savepvn((const char*)trie->states,
-        numstates * sizeof(reg_trie_state));
+    aho->trie=trie_offset;
+    aho->states=(reg_trie_state *)PerlMemShared_malloc( numstates * sizeof(reg_trie_state) );
+    Copy( trie->states, aho->states, numstates, reg_trie_state );
     Newxz( q, numstates, U32);
-    Newxz( aho->fail, numstates, U32 );
+    aho->fail = PerlMemShared_calloc( numstates, sizeof(U32) );
     aho->refcount = 1;
     fail = aho->fail;
     /* initialize fail[0..1] to be 1 so that we always have
@@ -3860,25 +3873,21 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
     return min < stopmin ? min : stopmin;
 }
 
-STATIC I32
-S_add_data(RExC_state_t *pRExC_state, I32 n, const char *s)
+STATIC U32
+S_add_data(RExC_state_t *pRExC_state, U32 n, const char *s)
 {
-    if (RExC_rxi->data) {
-       const U32 count = RExC_rxi->data->count;
-       Renewc(RExC_rxi->data,
-              sizeof(*RExC_rxi->data) + sizeof(void*) * (count + n - 1),
-              char, struct reg_data);
+    U32 count = RExC_rxi->data ? RExC_rxi->data->count : 0;
+
+    Renewc(RExC_rxi->data,
+          sizeof(*RExC_rxi->data) + sizeof(void*) * (count + n - 1),
+          char, struct reg_data);
+    if(count)
        Renew(RExC_rxi->data->what, count + n, U8);
-       RExC_rxi->data->count += n;
-    }
-    else {
-       Newxc(RExC_rxi->data, sizeof(*RExC_rxi->data) + sizeof(void*) * (n - 1),
-            char, struct reg_data);
+    else
        Newx(RExC_rxi->data->what, n, U8);
-       RExC_rxi->data->count = n;
-    }
-    Copy(s, RExC_rxi->data->what + RExC_rxi->data->count - n, n, U8);
-    return RExC_rxi->data->count - n;
+    RExC_rxi->data->count = count + n;
+    Copy(s, RExC_rxi->data->what + count, n, U8);
+    return count;
 }
 
 #ifndef PERL_IN_XSUB_RE
@@ -4221,13 +4230,13 @@ reStudy:
            regnode *trie_op;
            /* this can happen only on restudy */
            if ( OP(first) == TRIE ) {
-                struct regnode_1 *trieop;
-                Newxz(trieop,1,struct regnode_1);
+                struct regnode_1 *trieop =
+                   PerlMemShared_calloc(1, sizeof(struct regnode_1));
                 StructCopy(first,trieop,struct regnode_1);
                 trie_op=(regnode *)trieop;
             } else {
-                struct regnode_charclass *trieop;
-                Newxz(trieop,1,struct regnode_charclass);
+                struct regnode_charclass *trieop =
+                   PerlMemShared_calloc(1, sizeof(struct regnode_charclass));
                 StructCopy(first,trieop,struct regnode_charclass);
                 trie_op=(regnode *)trieop;
             }
@@ -4433,7 +4442,7 @@ reStudy:
            && !(data.start_class->flags & ANYOF_EOS)
            && !cl_is_anything(data.start_class))
        {
-           const I32 n = add_data(pRExC_state, 1, "f");
+           const U32 n = add_data(pRExC_state, 1, "f");
 
            Newx(RExC_rxi->data->data[n], 1,
                struct regnode_charclass_class);
@@ -4503,7 +4512,7 @@ reStudy:
        if (!(data.start_class->flags & ANYOF_EOS)
            && !cl_is_anything(data.start_class))
        {
-           const I32 n = add_data(pRExC_state, 1, "f");
+           const U32 n = add_data(pRExC_state, 1, "f");
 
            Newx(RExC_rxi->data->data[n], 1,
                struct regnode_charclass_class);
@@ -5070,7 +5079,8 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
                /* FALL THROUGH */
            case '{':           /* (?{...}) */
            {
-               I32 count = 1, n = 0;
+               I32 count = 1;
+               U32 n = 0;
                char c;
                char *s = RExC_parse;
 
@@ -5159,7 +5169,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
                {
                    char ch = RExC_parse[0] == '<' ? '>' : '\'';
                    char *name_start= RExC_parse++;
-                   I32 num = 0;
+                   U32 num = 0;
                    SV *sv_dat=reg_scan_name(pRExC_state,
                        SIZE_ONLY ? REG_RSN_RETURN_NULL : REG_RSN_RETURN_DATA);
                    if (RExC_parse == name_start || *RExC_parse != ch)
@@ -6305,7 +6315,7 @@ tryagain:
                goto defchar;
            } else {
                char* name_start = (RExC_parse += 2);
-               I32 num = 0;
+               U32 num = 0;
                 SV *sv_dat = reg_scan_name(pRExC_state,
                     SIZE_ONLY ? REG_RSN_RETURN_NULL : REG_RSN_RETURN_DATA);
                 ch= (ch == '<') ? '>' : '\'';
@@ -8220,9 +8230,8 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o)
         const reg_ac_data * const ac = IS_TRIE_AC(op) ?
                (reg_ac_data *)progi->data->data[n] :
                NULL;
-        const reg_trie_data * const trie = !IS_TRIE_AC(op) ?
-            (reg_trie_data*)progi->data->data[n] :
-            ac->trie;
+        const reg_trie_data * const trie
+           = (reg_trie_data*)progi->data->data[!IS_TRIE_AC(op) ? n : ac->trie];
         
         Perl_sv_catpvf(aTHX_ sv, "-%s",reg_name[o->flags]);
         DEBUG_TRIE_COMPILE_r(
@@ -8513,6 +8522,7 @@ Perl_pregfree(pTHX_ struct regexp *r)
            switch (ri->data->what[n]) {
            case 's':
            case 'S':
+           case 'u':
                SvREFCNT_dec((SV*)ri->data->data[n]);
                break;
            case 'f':
@@ -8549,12 +8559,11 @@ Perl_pregfree(pTHX_ struct regexp *r)
                     refcount = --aho->refcount;
                     OP_REFCNT_UNLOCK;
                     if ( !refcount ) {
-                        Safefree(aho->states);
-                        Safefree(aho->fail);
-                        aho->trie=NULL; /* not necessary to free this as it is 
-                                           handled by the 't' case */
-                        Safefree(ri->data->data[n]); /* do this last!!!! */
-                        Safefree(ri->regstclass);
+                        PerlMemShared_free(aho->states);
+                        PerlMemShared_free(aho->fail);
+                        /* do this last!!!! */
+                        PerlMemShared_free(ri->data->data[n]);
+                        PerlMemShared_free(ri->regstclass);
                     }
                 }
                 break;
@@ -8567,26 +8576,25 @@ Perl_pregfree(pTHX_ struct regexp *r)
                     refcount = --trie->refcount;
                     OP_REFCNT_UNLOCK;
                     if ( !refcount ) {
-                        Safefree(trie->charmap);
-                        if (trie->widecharmap)
-                            SvREFCNT_dec((SV*)trie->widecharmap);
-                        Safefree(trie->states);
-                        Safefree(trie->trans);
+                        PerlMemShared_free(trie->charmap);
+                        PerlMemShared_free(trie->states);
+                        PerlMemShared_free(trie->trans);
                         if (trie->bitmap)
-                            Safefree(trie->bitmap);
+                            PerlMemShared_free(trie->bitmap);
                         if (trie->wordlen)
-                            Safefree(trie->wordlen);
+                            PerlMemShared_free(trie->wordlen);
                         if (trie->jump)
-                            Safefree(trie->jump);
+                            PerlMemShared_free(trie->jump);
                         if (trie->nextword)
-                            Safefree(trie->nextword);
+                            PerlMemShared_free(trie->nextword);
 #ifdef DEBUGGING
                         if (trie->words)
                             SvREFCNT_dec((SV*)trie->words);
                         if (trie->revcharmap)
                             SvREFCNT_dec((SV*)trie->revcharmap);
 #endif
-                        Safefree(ri->data->data[n]); /* do this last!!!! */
+                        /* do this last!!!! */
+                        PerlMemShared_free(ri->data->data[n]);
                    }
                }
                break;
@@ -8683,15 +8691,14 @@ Perl_regdupe(pTHX_ const regexp *r, CLONE_PARAMS *param)
        for (i = 0; i < count; i++) {
            d->what[i] = ri->data->what[i];
            switch (d->what[i]) {
-               /* legal options are one of: sSfpontT
+               /* legal options are one of: sSfpontTu
                   see also regcomp.h and pregfree() */
            case 's':
            case 'S':
+           case 'p': /* actually an AV, but the dup function is identical.  */
+           case 'u': /* actually an HV, but the dup function is identical.  */
                d->data[i] = sv_dup_inc((SV *)ri->data->data[i], param);
                break;
-           case 'p':
-               d->data[i] = av_dup_inc((AV *)ri->data->data[i], param);
-               break;
            case 'f':
                /* This is cheating. */
                Newx(d->data[i], 1, struct regnode_charclass_class);
@@ -8706,25 +8713,20 @@ Perl_regdupe(pTHX_ const regexp *r, CLONE_PARAMS *param)
                d->data[i] = (void*)OpREFCNT_inc((OP*)ri->data->data[i]);
                OP_REFCNT_UNLOCK;
                break;
-           case 'n':
-               d->data[i] = ri->data->data[i];
-               break;
-           case 't':
-               d->data[i] = ri->data->data[i];
-               OP_REFCNT_LOCK;
-               ((reg_trie_data*)d->data[i])->refcount++;
-               OP_REFCNT_UNLOCK;
-               break;
            case 'T':
-               d->data[i] = ri->data->data[i];
-               OP_REFCNT_LOCK;
-               ((reg_ac_data*)d->data[i])->refcount++;
-               OP_REFCNT_UNLOCK;
                /* Trie stclasses are readonly and can thus be shared
                 * without duplication. We free the stclass in pregfree
                 * when the corresponding reg_ac_data struct is freed.
                 */
                reti->regstclass= ri->regstclass;
+               /* Fall through */
+           case 't':
+               OP_REFCNT_LOCK;
+               ((reg_trie_data*)ri->data->data[i])->refcount++;
+               OP_REFCNT_UNLOCK;
+               /* Fall through */
+           case 'n':
+               d->data[i] = ri->data->data[i];
                break;
             default:
                Perl_croak(aTHX_ "panic: re_dup unknown data code '%c'", ri->data->what[i]);
@@ -9089,9 +9091,8 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
            const reg_ac_data * const ac = op>=AHOCORASICK ?
                (reg_ac_data *)ri->data->data[n] :
                NULL;
-           const reg_trie_data * const trie = op<AHOCORASICK ?
-               (reg_trie_data*)ri->data->data[n] :
-               ac->trie;
+           const reg_trie_data * const trie =
+               (reg_trie_data*)ri->data->data[op<AHOCORASICK ? n : ac->trie];
            const regnode *nextbranch= NULL;
            I32 word_idx;
             sv_setpvn(sv, "", 0);