summaryrefslogtreecommitdiff
path: root/op.h
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-12-05 12:53:30 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-12-05 21:31:42 -0800
commit230834321e308444d408bdbf755d181b67e82d4c (patch)
tree0775daf798c8ecb31604e073e21eeba3a65b9375 /op.h
parentbcea25a760263ce058f5588c6ae62af6f09a211e (diff)
downloadperl-230834321e308444d408bdbf755d181b67e82d4c.tar.gz
Stop renamed packages from making reset() crash
This only affected threaded builds. I think the comments in the added test explain well enough what was happening. The solution is to store a stashpad offset in the pmop, instead of the name of the stash. This is similar to what was done with cop stashes in d4d03940c58a. Not only does this fix the crash, but it also makes compilation faster and saves memory (no separate malloc for every m?pat?). I had to move Safefree(PL_stashpad) later on in perl_destruct, because freeing a pmop causes the PL_stashpad to be accessed, and pmops can be freed during sv_clean_all. Its previous location was not a problem for cops, as PL_stashpad[cop->cop_stashoff] is only accessed when PL_curcop==that_cop and Perl code is running, not when cops are freed.
Diffstat (limited to 'op.h')
-rw-r--r--op.h45
1 files changed, 11 insertions, 34 deletions
diff --git a/op.h b/op.h
index 97228b1ce2..c1800df828 100644
--- a/op.h
+++ b/op.h
@@ -371,10 +371,7 @@ struct pmop {
union {
OP * op_pmreplstart; /* Only used in OP_SUBST */
#ifdef USE_ITHREADS
- struct {
- char * op_pmstashpv; /* Only used in OP_MATCH, with PMf_ONCE set */
- U32 op_pmstashflags; /* currently only SVf_UTF8 or 0 */
- } op_pmstashthr;
+ PADOFFSET op_pmstashoff; /* Only used in OP_MATCH, with PMf_ONCE set */
#else
HV * op_pmstash;
#endif
@@ -454,30 +451,13 @@ struct pmop {
#ifdef USE_ITHREADS
-# define PmopSTASHPV(o) \
- (((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstashthr.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_pmstashthr.op_pmstashpv = savesharedpv(pv)); \
- })
-# else
-# define PmopSTASHPV_set(o,pv) \
- ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashpv = savesharedpv(pv))
-# endif
-# define PmopSTASH_flags(o) ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashflags)
-# define PmopSTASH_flags_set(o,flags) ((o)->op_pmstashstartu.op_pmstashthr.op_pmstashflags = flags)
-# define PmopSTASH(o) (PmopSTASHPV(o) \
- ? gv_stashpv((o)->op_pmstashstartu.op_pmstashthr.op_pmstashpv, \
- GV_ADD | PmopSTASH_flags(o)) : NULL)
-# define PmopSTASH_set(o,hv) (PmopSTASHPV_set(o, (hv) ? HvNAME_get(hv) : NULL), \
- PmopSTASH_flags_set(o, \
- ((hv) && HvNAME_HEK(hv) && \
- HvNAMEUTF8(hv)) \
- ? SVf_UTF8 \
- : 0))
-# define PmopSTASH_free(o) PerlMemShared_free(PmopSTASHPV(o))
-
+# define PmopSTASH(o) ((o)->op_pmflags & PMf_ONCE \
+ ? PL_stashpad[(o)->op_pmstashstartu.op_pmstashoff] \
+ : NULL)
+# define PmopSTASH_set(o,hv) \
+ (assert_((o)->op_pmflags & PMf_ONCE) \
+ (o)->op_pmstashstartu.op_pmstashoff = \
+ (hv) ? alloccopstash(hv) : NULL)
#else
# define PmopSTASH(o) \
(((o)->op_pmflags & PMf_ONCE) ? (o)->op_pmstashstartu.op_pmstash : NULL)
@@ -489,13 +469,10 @@ struct pmop {
# else
# define PmopSTASH_set(o,hv) ((o)->op_pmstashstartu.op_pmstash = (hv))
# endif
-# define PmopSTASHPV(o) (PmopSTASH(o) ? HvNAME_get(PmopSTASH(o)) : NULL)
- /* op_pmstashstartu.op_pmstash is not refcounted */
-# define PmopSTASHPV_set(o,pv) PmopSTASH_set((o), gv_stashpv(pv,GV_ADD))
-/* Note that if this becomes non-empty, then S_forget_pmop in op.c will need
- changing */
-# define PmopSTASH_free(o)
#endif
+#define PmopSTASHPV(o) (PmopSTASH(o) ? HvNAME_get(PmopSTASH(o)) : NULL)
+ /* op_pmstashstartu.op_pmstash is not refcounted */
+#define PmopSTASHPV_set(o,pv) PmopSTASH_set((o), gv_stashpv(pv,GV_ADD))
struct svop {
BASEOP