line_t cop_line; /* line # of this command */
/* label for this construct is now stored in cop_hints_hash */
#ifdef USE_ITHREADS
- char * cop_stashpv; /* package line was compiled in */
+ PADOFFSET cop_stashoff; /* package line was compiled in */
char * cop_file; /* file name the following line # is from */
- I32 cop_stashlen; /* negative for UTF8 */
#else
HV * cop_stash; /* package line was compiled in */
GV * cop_filegv; /* file the following line # is from */
# else
# define CopFILEAVx(c) (GvAV(gv_fetchfile(CopFILE(c))))
# endif
-# define CopSTASHPV(c) ((c)->cop_stashpv)
+# define CopSTASH(c) PL_stashpad[(c)->cop_stashoff]
+# define CopSTASH_set(c,hv) ((c)->cop_stashoff = (hv) \
+ ? alloccopstash(hv) \
+ : 0)
# ifdef NETWARE
-# define CopSTASHPV_set(c,pv,n) ((c)->cop_stashpv = \
- ((pv) ? savepvn(pv,n) : NULL))
-# else
-# define CopSTASHPV_set(c,pv,n) ((c)->cop_stashpv = (pv) \
- ? savesharedpvn(pv,n) : NULL)
-# endif
-
-# define CopSTASH_len_set(c,n) ((c)->cop_stashlen = (n))
-# define CopSTASH_len(c) ((c)->cop_stashlen)
-
-# define CopSTASH(c) (CopSTASHPV(c) \
- ? gv_stashpvn(CopSTASHPV(c), \
- CopSTASH_len(c) < 0 \
- ? -CopSTASH_len(c) \
- : CopSTASH_len(c), \
- GV_ADD|SVf_UTF8*(CopSTASH_len(c) < 0) \
- ) \
- : NULL)
-# define CopSTASH_set(c,hv) (CopSTASHPV_set(c, \
- (hv) ? HvNAME_get(hv) : NULL, \
- (hv) ? HvNAMELEN(hv) : 0), \
- CopSTASH_len_set(c, \
- (hv) ? HvNAMEUTF8(hv) \
- ? -HvNAMELEN(hv) \
- : HvNAMELEN(hv) \
- : 0))
-# define CopSTASH_eq(c,hv) ((hv) && stashpv_hvname_match(c,hv))
-# ifdef NETWARE
-# define CopSTASH_free(c) SAVECOPSTASH_FREE(c)
# define CopFILE_free(c) SAVECOPFILE_FREE(c)
# else
-# define CopSTASH_free(c) PerlMemShared_free(CopSTASHPV(c))
# define CopFILE_free(c) (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = NULL))
# endif
#else
? SvPVX(GvSV(CopFILEGV(c))) : NULL)
# define CopSTASH(c) ((c)->cop_stash)
# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv))
-# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL)
- /* cop_stash is not refcounted */
-# define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
-# define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv))
-# define CopSTASH_free(c)
# define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL))
#endif /* USE_ITHREADS */
+#define CopSTASHPV(c) (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL)
+ /* cop_stash is not refcounted */
+#define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
+#define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv))
+#define CopSTASH_free(c)
+
#define CopHINTHASH_get(c) ((COPHH*)((c)->cop_hints_hash))
#define CopHINTHASH_set(c,h) ((c)->cop_hints_hash = (h))
: Used in toke.c and perly.y
p |PADOFFSET|allocmy |NN const char *const name|const STRLEN len\
|const U32 flags
+#ifdef USE_ITHREADS
+p |PADOFFSET|alloccopstash|NN HV *hv
+#endif
: Used in perly.y
pR |OP* |oopsAV |NN OP* o
: Used in perly.y
#define pidgone(a,b) S_pidgone(aTHX_ a,b)
# endif
# if defined(USE_ITHREADS)
+#define alloccopstash(a) Perl_alloccopstash(aTHX_ a)
#define mro_meta_dup(a,b) Perl_mro_meta_dup(aTHX_ a,b)
#define padlist_dup(a,b) Perl_padlist_dup(aTHX_ a,b)
# endif
#define PL_stack_sp (vTHX->Istack_sp)
#define PL_start_env (vTHX->Istart_env)
#define PL_stashcache (vTHX->Istashcache)
+#define PL_stashpad (vTHX->Istashpad)
+#define PL_stashpadix (vTHX->Istashpadix)
+#define PL_stashpadmax (vTHX->Istashpadmax)
#define PL_statbuf (vTHX->Istatbuf)
#define PL_statcache (vTHX->Istatcache)
#define PL_statgv (vTHX->Istatgv)
#ifdef USE_ITHREADS
cv = newXS("B::PMOP::pmoffset", XS_B__OP_next, __FILE__);
XSANY.any_i32 = PMOP_pmoffset_ix;
+# if PERL_VERSION >= 17 && defined(CopSTASH_len)
cv = newXS("B::COP::stashpv", XS_B__OP_next, __FILE__);
XSANY.any_i32 = COP_stashpv_ix;
cv = newXS("B::COP::file", XS_B__OP_next, __FILE__);
XSANY.any_i32 = COP_file_ix;
+# endif
#else
cv = newXS("B::COP::stash", XS_B__OP_next, __FILE__);
XSANY.any_i32 = COP_stash_ix;
#endif
-#else
+#endif
+
+#if !defined(USE_ITHREADS) || (PERL_VERSION > 16 && !defined(CopSTASH_len))
char *
COP_stashpv(o)
superisa = GvAVn(gv);
GvMULTI_on(gv);
sv_magic(MUTABLE_SV(superisa), MUTABLE_SV(gv), PERL_MAGIC_isa, NULL, 0);
-#ifdef USE_ITHREADS
- av_push(superisa, newSVpvn_flags(CopSTASHPV(PL_curcop),
- CopSTASH_len(PL_curcop) < 0
- ? -CopSTASH_len(PL_curcop)
- : CopSTASH_len(PL_curcop),
- SVf_UTF8*(CopSTASH_len(PL_curcop) < 0)
- ));
-#else
av_push(superisa, newSVhek(CopSTASH(PL_curcop)
? HvNAME_HEK(CopSTASH(PL_curcop)) : NULL));
-#endif
return stash;
}
Entry 0 is an SV whose PV is a
"packed" list of IVs listing
the now-free slots in the array */
+PERLVAR(I, stashpad, HV **) /* for CopSTASH */
+PERLVARI(I, stashpadmax, PADOFFSET, 64)
+PERLVARI(I, stashpadix, PADOFFSET, 0)
#endif
#ifdef USE_REENTRANT_API
PL_hints_mutex
PL_my_ctx_mutex
PL_perlio_mutex
+ PL_stashpad
+ PL_stashpadix
+ PL_stashpadmax
Perl_clone_params_del
Perl_clone_params_new
Perl_parser_dup
return off;
}
+#ifdef USE_ITHREADS
+PADOFFSET
+Perl_alloccopstash(pTHX_ HV *hv)
+{
+ PADOFFSET off = 0, o = 1;
+ bool found_slot = FALSE;
+
+ PERL_ARGS_ASSERT_ALLOCCOPSTASH;
+
+ if (PL_stashpad[PL_stashpadix] == hv) return PL_stashpadix;
+
+ for (; o < PL_stashpadmax; ++o) {
+ if (PL_stashpad[o] == hv) return PL_stashpadix = o;
+ if (!PL_stashpad[o] || SvTYPE(PL_stashpad[o]) != SVt_PVHV)
+ found_slot = TRUE, off = o;
+ }
+ if (!found_slot) {
+ Renew(PL_stashpad, PL_stashpadmax + 10, HV *);
+ Zero(PL_stashpad + PL_stashpadmax, 10, HV *);
+ off = PL_stashpadmax;
+ PL_stashpadmax += 10;
+ }
+
+ PL_stashpad[PL_stashpadix = off] = hv;
+ return off;
+}
+#endif
+
/* free the body of an op without examining its contents.
* Always use this rather than FreeOp directly */
data. */
firstcop->cop_line = secondcop->cop_line;
#ifdef USE_ITHREADS
- firstcop->cop_stashpv = secondcop->cop_stashpv;
- firstcop->cop_stashlen = secondcop->cop_stashlen;
+ firstcop->cop_stashoff = secondcop->cop_stashoff;
firstcop->cop_file = secondcop->cop_file;
#else
firstcop->cop_stash = secondcop->cop_stash;
firstcop->cop_hints_hash = secondcop->cop_hints_hash;
#ifdef USE_ITHREADS
- secondcop->cop_stashpv = NULL;
+ secondcop->cop_stashoff = NULL;
secondcop->cop_file = NULL;
#else
secondcop->cop_stash = NULL;
else all hell breaks loose in S_find_uninit_var(). */
Perl_av_create_and_push(aTHX_ &PL_regex_padav, newSVpvs(""));
PL_regex_pad = AvARRAY(PL_regex_padav);
+ Newxz(PL_stashpad, PL_stashpadmax, HV *);
#endif
#ifdef USE_REENTRANT_API
Perl_reentrant_init(aTHX);
SvREFCNT_dec(PL_regex_padav);
PL_regex_padav = NULL;
PL_regex_pad = NULL;
+ Safefree(PL_stashpad);
#endif
SvREFCNT_dec(MUTABLE_SV(PL_stashcache));
#endif
#if defined(USE_ITHREADS)
+PERL_CALLCONV PADOFFSET Perl_alloccopstash(pTHX_ HV *hv)
+ __attribute__nonnull__(pTHX_1);
+#define PERL_ARGS_ASSERT_ALLOCCOPSTASH \
+ assert(hv)
+
PERL_CALLCONV void* Perl_any_dup(pTHX_ void* v, const PerlInterpreter* proto_perl)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_2);
#define SAVEPARSER(p) save_pushptr((p), SAVEt_PARSER)
#ifdef USE_ITHREADS
-# define SAVECOPSTASH(c) (SAVEPPTR(CopSTASHPV(c)), \
- SAVEI32(CopSTASH_len(c)))
-# define SAVECOPSTASH_FREE(c) (SAVESHAREDPV(CopSTASHPV(c)), \
- SAVEI32(CopSTASH_len(c)))
+# define SAVECOPSTASH(c) SAVEIV((c)->cop_stashoff)
+# define SAVECOPSTASH_FREE(c) SAVEIV((c)->cop_stashoff)
# define SAVECOPFILE(c) SAVEPPTR(CopFILE(c))
# define SAVECOPFILE_FREE(c) SAVESHAREDPV(CopFILE(c))
#else
hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab));
ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab);
- /* These two PVs will be free'd special way so must set them same way op.c does */
- PL_compiling.cop_stashpv = savesharedpv(PL_compiling.cop_stashpv);
- ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_stashpv, PL_compiling.cop_stashpv);
-
+ /* This PV will be free'd special way so must set it same way op.c does */
PL_compiling.cop_file = savesharedpv(PL_compiling.cop_file);
ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file);
PL_regex_padav = av_dup_inc(proto_perl->Iregex_padav, param);
PL_regex_pad = AvARRAY(PL_regex_padav);
+ PL_stashpadmax = proto_perl->Istashpadmax;
+ PL_stashpadix = proto_perl->Istashpadix ;
+ Newx(PL_stashpad, PL_stashpadmax, HV *);
+ {
+ PADOFFSET o = 0;
+ for (; o < PL_stashpadmax; ++o)
+ PL_stashpad[o] = hv_dup(proto_perl->Istashpad[o], param);
+ }
+
/* shortcuts to various I/O objects */
PL_ofsgv = gv_dup_inc(proto_perl->Iofsgv, param);
PL_stdingv = gv_dup(proto_perl->Istdingv, param);
bool
Perl_stashpv_hvname_match(pTHX_ const COP *c, const HV *hv)
{
- const char * stashpv = CopSTASHPV(c);
- const char * name = HvNAME_get(hv);
- const bool utf8 = CopSTASH_len(c) < 0;
- const I32 len = utf8 ? -CopSTASH_len(c) : CopSTASH_len(c);
- PERL_UNUSED_CONTEXT;
PERL_ARGS_ASSERT_STASHPV_HVNAME_MATCH;
-
- if (!stashpv || !name)
- return stashpv == name;
- if ( !HvNAMEUTF8(hv) != !utf8 ) {
- if (utf8) {
- return (bytes_cmp_utf8(
- (const U8*)stashpv, len,
- (const U8*)name, HEK_LEN(HvNAME_HEK(hv))) == 0);
- } else {
- return (bytes_cmp_utf8(
- (const U8*)name, HEK_LEN(HvNAME_HEK(hv)),
- (const U8*)stashpv, len) == 0);
- }
- }
- else
- return (stashpv == name
- || (HEK_LEN(HvNAME_HEK(hv)) == len
- && memEQ(stashpv, name, len)));
- /*NOTREACHED*/
- return FALSE;
+ return CopSTASH(c) == hv;
}
#endif