From: Nicholas Clark Date: Fri, 6 Apr 2007 23:31:14 +0000 (+0000) Subject: Merge op_pmreplstart and op_pmstash/op_pmstashpv into a union in X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=29f2e9126439df904e8eb9163e136caf022dede1;p=p5sagit%2Fp5-mst-13.2.git Merge op_pmreplstart and op_pmstash/op_pmstashpv into a union in PMOP, as both pointers never need to be set at the same time. p4raw-id: //depot/perl@30860 --- diff --git a/dump.c b/dump.c index e85e5e9..8a6c1248 100644 --- a/dump.c +++ b/dump.c @@ -673,13 +673,13 @@ S_sequence(pTHX_ register const OP *o) sequence_tail(cLOOPo->op_lastop); break; - case OP_QR: - case OP_MATCH: case OP_SUBST: hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0); - sequence_tail(cPMOPo->op_pmreplstart); + sequence_tail(cPMOPo->op_pmstashstartu.op_pmreplstart); break; + case OP_QR: + case OP_MATCH: case OP_HELEM: break; diff --git a/ext/B/B.xs b/ext/B/B.xs index 9d62ff2..717dbf1 100644 --- a/ext/B/B.xs +++ b/ext/B/B.xs @@ -513,7 +513,11 @@ oplist(pTHX_ OP *o, SV **SP) XPUSHs(opsv); switch (o->op_type) { case OP_SUBST: +#if PERL_VERSION >= 9 + SP = oplist(aTHX_ cPMOPo->op_pmstashstartu.op_pmreplstart, SP); +#else SP = oplist(aTHX_ cPMOPo->op_pmreplstart, SP); +#endif continue; case OP_SORT: if (o->op_flags & OPf_STACKED && o->op_flags & OPf_SPECIAL) { @@ -978,14 +982,18 @@ LISTOP_children(o) RETVAL #define PMOP_pmreplroot(o) o->op_pmreplroot -#define PMOP_pmreplstart(o) o->op_pmreplstart +#if PERL_VERSION >= 9 +# define PMOP_pmreplstart(o) o->op_pmstashstartu.op_pmreplstart +#else +# define PMOP_pmreplstart(o) o->op_pmreplstart +#endif #define PMOP_pmnext(o) o->op_pmnext #define PMOP_pmregexp(o) PM_GETRE(o) #ifdef USE_ITHREADS #define PMOP_pmoffset(o) o->op_pmoffset -#define PMOP_pmstashpv(o) o->op_pmstashpv +#define PMOP_pmstashpv(o) PmopSTASHPV(o); #else -#define PMOP_pmstash(o) o->op_pmstash +#define PMOP_pmstash(o) PmopSTASH(o); #endif #define PMOP_pmflags(o) o->op_pmflags diff --git a/op.c b/op.c index bb9dc60..9d9494b 100644 --- a/op.c +++ b/op.c @@ -3525,7 +3525,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg) repl->op_next = (OP*)rcop; pm->op_pmreplroot = scalar((OP*)rcop); - pm->op_pmreplstart = LINKLIST(rcop); + assert(!(pm->op_pmflags & PMf_ONCE)); + pm->op_pmstashstartu.op_pmreplstart = LINKLIST(rcop); rcop->op_next = 0; } } @@ -8033,10 +8034,12 @@ Perl_peep(pTHX_ register OP *o) case OP_SUBST: o->op_opt = 1; - while (cPMOP->op_pmreplstart && - cPMOP->op_pmreplstart->op_type == OP_NULL) - cPMOP->op_pmreplstart = cPMOP->op_pmreplstart->op_next; - peep(cPMOP->op_pmreplstart); + assert(!(cPMOP->op_pmflags & PMf_ONCE)); + while (cPMOP->op_pmstashstartu.op_pmreplstart && + cPMOP->op_pmstashstartu.op_pmreplstart->op_type == OP_NULL) + cPMOP->op_pmstashstartu.op_pmreplstart + = cPMOP->op_pmstashstartu.op_pmreplstart->op_next; + peep(cPMOP->op_pmstashstartu.op_pmreplstart); break; case OP_EXEC: @@ -8427,7 +8430,9 @@ Perl_peep(pTHX_ register OP *o) case OP_QR: case OP_MATCH: - assert (!cPMOP->op_pmreplstart); + if (!(cPMOP->op_pmflags & PMf_ONCE)) { + assert (!cPMOP->op_pmstashstartu.op_pmreplstart); + } /* FALL THROUGH */ default: o->op_opt = 1; diff --git a/op.h b/op.h index 36a1687..31bce2f 100644 --- a/op.h +++ b/op.h @@ -319,23 +319,20 @@ struct pmop { OP * op_first; OP * op_last; OP * op_pmreplroot; /* (type is really union {OP*,GV*,PADOFFSET}) */ - OP * op_pmreplstart; #ifdef USE_ITHREADS IV op_pmoffset; #else REGEXP * op_pmregexp; /* compiled expression */ #endif U32 op_pmflags; - /* This field is only needed so that PMOPs can delete themselves from the - list held by the stash. In turn, that list is only needed for reset - to work correctly, and is now only a list of ops used by ?? matches, - which are rare. Hence it would be useful if we could find a way to - shave it. */ + union { + OP * op_pmreplstart; /* Only used in OP_SUBST */ #ifdef USE_ITHREADS - char * op_pmstashpv; + char * op_pmstashpv; /* Only used in OP_MATCH, with PMf_ONCE set */ #else - HV * op_pmstash; + HV * op_pmstash; #endif + } op_pmstashstartu; }; #ifdef USE_ITHREADS @@ -357,7 +354,9 @@ struct pmop { #define PMf_RETAINT 0x0001 /* taint $1 etc. if target tainted */ #define PMf_ONCE 0x0002 /* match successfully only once per reset, with related flag RXf_USED - in re->extflags holding state */ + in re->extflags holding state. + This is used only for ?? matches, + and only on OP_MATCH and OP_QR */ #define PMf_UNUSED 0x0004 /* free for use */ #define PMf_MAYBE_CONST 0x0008 /* replacement contains variables */ @@ -386,18 +385,35 @@ struct pmop { #ifdef USE_ITHREADS -# define PmopSTASHPV(o) ((o)->op_pmstashpv) -# define PmopSTASHPV_set(o,pv) (PmopSTASHPV(o) = savesharedpv(pv)) +# define PmopSTASHPV(o) \ + (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstashpv : NULL) +# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define PmopSTASHPV_set(o,pv) ({ \ + assert((o)->op_pmflags & PMf_ONCE); \ + ((o)->op_pmstashstartu.op_pmstashpv = savesharedpv(pv)); \ + }) +# else +# define PmopSTASHPV_set(o,pv) \ + ((o)->op_pmstashstartu.op_pmstashpv = savesharedpv(pv)) +# endif # define PmopSTASH(o) (PmopSTASHPV(o) \ - ? gv_stashpv(PmopSTASHPV(o),GV_ADD) : NULL) + ? gv_stashpv((o)->op_pmstashstartu.op_pmstashpv,GV_ADD) : NULL) # define PmopSTASH_set(o,hv) PmopSTASHPV_set(o, ((hv) ? HvNAME_get(hv) : NULL)) # define PmopSTASH_free(o) PerlMemShared_free(PmopSTASHPV(o)) #else -# define PmopSTASH(o) ((o)->op_pmstash) -# define PmopSTASH_set(o,hv) ((o)->op_pmstash = (hv)) +# define PmopSTASH(o) \ + (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstash : NULL) +# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define PmopSTASH_set(o,hv) ({ \ + assert((o)->op_pmflags & PMf_ONCE); \ + ((o)->op_pmstashstartu.op_pmstash = (hv)); \ + }) +# else +# define PmopSTASH_set(o,hv) ((o)->op_pmstashstartu.op_pmstash = (hv)) +# endif # define PmopSTASHPV(o) (PmopSTASH(o) ? HvNAME_get(PmopSTASH(o)) : NULL) - /* op_pmstash is not refcounted */ + /* op_pmstashstartu.op_pmstash is not refcounted */ # define PmopSTASHPV_set(o,pv) PmopSTASH_set((o), gv_stashpv(pv,GV_ADD)) # define PmopSTASH_free(o) #endif diff --git a/pp_ctl.c b/pp_ctl.c index e01d7e5..63b7039 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -302,7 +302,7 @@ PP(pp_substcont) (void)ReREFCNT_inc(rx); cx->sb_rxtainted |= RX_MATCH_TAINTED(rx); rxres_save(&cx->sb_rxres, rx); - RETURNOP(pm->op_pmreplstart); + RETURNOP(pm->op_pmstashstartu.op_pmreplstart); } void