Skip to content

Commit 1dc74fd

Browse files
author
Father Chrysostomos
committed
Revert "[perl #117855] Store CopFILEGV in a pad under ithreads"
This reverts commit c82ecf3. It turn out to be faulty, because a location shared betweens threads (the cop) was holding a reference count on a pad entry in a particu- lar thread. So when you free the cop, how do you know where to do SvREFCNT_dec? In reverting c82ecf3, this commit still preserves the bug fix from 1311cfc, but shifts it around.
1 parent 449dd03 commit 1dc74fd

File tree

19 files changed

+69
-161
lines changed

19 files changed

+69
-161
lines changed

MANIFEST

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3870,7 +3870,7 @@ ext/XS-APItest/t/cleanup.t test stack behaviour on unwinding
38703870
ext/XS-APItest/t/clone-with-stack.t test clone with CLONEf_COPY_STACKS works
38713871
ext/XS-APItest/t/cophh.t test COPHH API
38723872
ext/XS-APItest/t/coplabel.t test cop_*_label
3873-
ext/XS-APItest/t/cop.t test other cop stuff
3873+
ext/XS-APItest/t/copstash.t test alloccopstash
38743874
ext/XS-APItest/t/copyhints.t test hv_copy_hints_hv() API
38753875
ext/XS-APItest/t/customop.t XS::APItest: tests for custom ops
38763876
ext/XS-APItest/t/eval-filter.t Simple source filter/eval test

cop.h

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,7 @@ struct cop {
389389
#ifdef USE_ITHREADS
390390
PADOFFSET cop_stashoff; /* offset into PL_stashpad, for the
391391
package the line was compiled in */
392-
PADOFFSET cop_filegvoff; /* PL_filegv offset, for the file name the
393-
following line # is from */
392+
char * cop_file; /* file name the following line # is from */
394393
#else
395394
HV * cop_stash; /* package line was compiled in */
396395
GV * cop_filegv; /* file the following line # is from */
@@ -405,32 +404,54 @@ struct cop {
405404
};
406405

407406
#ifdef USE_ITHREADS
408-
# define CopFILEGV(c) PL_filegvpad[(c)->cop_filegvoff]
409-
# define CopFILEGV_set(c,gv) ((c)->cop_filegvoff = (gv) \
410-
? allocfilegv((GV *)SvREFCNT_inc_NN(gv)) \
411-
: 0)
407+
# define CopFILE(c) ((c)->cop_file)
408+
# define CopFILEGV(c) (CopFILE(c) \
409+
? gv_fetchfile(CopFILE(c)) : NULL)
410+
411+
# ifdef NETWARE
412+
# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv))
413+
# define CopFILE_setn(c,pv,l) ((c)->cop_file = savepv((pv),(l)))
414+
# else
415+
# define CopFILE_set(c,pv) ((c)->cop_file = savesharedpv(pv))
416+
# define CopFILE_setn(c,pv,l) ((c)->cop_file = savesharedpvn((pv),(l)))
417+
# endif
418+
419+
# define CopFILESV(c) (CopFILE(c) \
420+
? GvSV(gv_fetchfile(CopFILE(c))) : NULL)
421+
# define CopFILEAV(c) (CopFILE(c) \
422+
? GvAV(gv_fetchfile(CopFILE(c))) : NULL)
423+
# define CopFILEAVx(c) (assert_(CopFILE(c)) \
424+
GvAV(gv_fetchfile(CopFILE(c))))
412425

413426
# define CopSTASH(c) PL_stashpad[(c)->cop_stashoff]
414427
# define CopSTASH_set(c,hv) ((c)->cop_stashoff = (hv) \
415428
? alloccopstash(hv) \
416429
: 0)
417-
# define CopFILE_free(c) S_CopFILE_free(aTHX_ c)
430+
# ifdef NETWARE
431+
# define CopFILE_free(c) SAVECOPFILE_FREE(c)
432+
# else
433+
# define CopFILE_free(c) (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = NULL))
434+
# endif
418435
#else
419436
# define CopFILEGV(c) ((c)->cop_filegv)
420437
# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv))
438+
# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))
439+
# define CopFILE_setn(c,pv,l) CopFILEGV_set((c), gv_fetchfile_flags((pv),(l),0))
440+
# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : NULL)
441+
# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : NULL)
442+
# ifdef DEBUGGING
443+
# define CopFILEAVx(c) (assert(CopFILEGV(c)), GvAV(CopFILEGV(c)))
444+
# else
445+
# define CopFILEAVx(c) (GvAV(CopFILEGV(c)))
446+
# endif
447+
# define CopFILE(c) (CopFILEGV(c) \
448+
? GvNAME(CopFILEGV(c))+2 : NULL)
421449
# define CopSTASH(c) ((c)->cop_stash)
422450
# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv))
423451
# define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL))
424452

425453
#endif /* USE_ITHREADS */
426454

427-
#define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))
428-
#define CopFILE_setn(c,pv,l) CopFILEGV_set((c), gv_fetchfile_flags((pv),(l),0))
429-
#define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : NULL)
430-
#define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : NULL)
431-
#define CopFILEAVx(c) (assert_(CopFILEGV(c)) GvAV(CopFILEGV(c)))
432-
#define CopFILE(c) (CopFILEGV(c) \
433-
? GvNAME(CopFILEGV(c))+2 : NULL)
434455
#define CopSTASHPV(c) (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL)
435456
/* cop_stash is not refcounted */
436457
#define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD))

embed.fnc

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,6 @@ p |PADOFFSET|allocmy |NN const char *const name|const STRLEN len\
10241024
|const U32 flags
10251025
#ifdef USE_ITHREADS
10261026
AMp |PADOFFSET|alloccopstash|NN HV *hv
1027-
AMp |PADOFFSET|allocfilegv |NN GV *gv
10281027
#endif
10291028
: Used in perly.y
10301029
pR |OP* |oopsAV |NN OP* o
@@ -2660,8 +2659,4 @@ op |void |populate_isa |NN const char *name|STRLEN len|...
26602659
Xop |bool |feature_is_enabled|NN const char *const name \
26612660
|STRLEN namelen
26622661

2663-
: Some static inline functions that implement macros need predeclaration
2664-
: because they are used inside other static inline functions.
2665-
Aoi |void |SvREFCNT_dec_NN|NN SV *sv
2666-
26672662
: ex: set ts=8 sts=4 sw=4 noet:

embed.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,6 @@
806806
#endif
807807
#if defined(USE_ITHREADS)
808808
#define alloccopstash(a) Perl_alloccopstash(aTHX_ a)
809-
#define allocfilegv(a) Perl_allocfilegv(aTHX_ a)
810809
#define any_dup(a,b) Perl_any_dup(aTHX_ a,b)
811810
#define cx_dup(a,b,c,d) Perl_cx_dup(aTHX_ a,b,c,d)
812811
#define dirp_dup(a,b) Perl_dirp_dup(aTHX_ a,b)

embedvar.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,6 @@
146146
#define PL_exitlist (vTHX->Iexitlist)
147147
#define PL_exitlistlen (vTHX->Iexitlistlen)
148148
#define PL_fdpid (vTHX->Ifdpid)
149-
#define PL_filegvpad (vTHX->Ifilegvpad)
150-
#define PL_filegvpadix (vTHX->Ifilegvpadix)
151-
#define PL_filegvpadmax (vTHX->Ifilegvpadmax)
152149
#define PL_filemode (vTHX->Ifilemode)
153150
#define PL_firstgv (vTHX->Ifirstgv)
154151
#define PL_forkprocess (vTHX->Iforkprocess)

ext/B/B.pm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,8 +1228,6 @@ Since perl 5.17.1
12281228
12291229
=item file
12301230
1231-
=item filegvoff (threaded only)
1232-
12331231
=item cop_seq
12341232
12351233
=item arybase

ext/B/B.xs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -682,11 +682,7 @@ struct OP_methods {
682682
#ifdef USE_ITHREADS
683683
STR_WITH_LEN("pmoffset"),IVp, offsetof(struct pmop, op_pmoffset),/*20*/
684684
STR_WITH_LEN("filegv"), op_offset_special, 0, /*21*/
685-
# if PERL_VERSION < 19
686685
STR_WITH_LEN("file"), char_pp, offsetof(struct cop, cop_file), /*22*/
687-
# else
688-
STR_WITH_LEN("file"), op_offset_special, 0, /*22*/
689-
# endif
690686
STR_WITH_LEN("stash"), op_offset_special, 0, /*23*/
691687
# if PERL_VERSION < 17
692688
STR_WITH_LEN("stashpv"), char_pp, offsetof(struct cop, cop_stashpv), /*24*/
@@ -732,11 +728,6 @@ struct OP_methods {
732728
STR_WITH_LEN("folded"), op_offset_special, 0, /*50*/
733729
#endif
734730
#endif
735-
#if PERL_VERSION < 19 || !defined(USE_ITHREADS)
736-
STR_WITH_LEN("filegvoff"),op_offset_special, 0, /*51*/
737-
#else
738-
STR_WITH_LEN("filegvoff"),PADOFFSETp,offsetof(struct cop, cop_filegvoff),/*51*/
739-
#endif
740731
};
741732

742733
#include "const-c.inc"
@@ -1040,7 +1031,7 @@ next(o)
10401031
ret = make_sv_object(aTHX_ (SV *)CopFILEGV((COP*)o));
10411032
break;
10421033
#endif
1043-
#if !defined(USE_ITHREADS) || PERL_VERSION >= 19
1034+
#ifndef USE_ITHREADS
10441035
case 22: /* file */
10451036
ret = sv_2mortal(newSVpv(CopFILE((COP*)o), 0));
10461037
break;

ext/XS-APItest/APItest.xs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3387,13 +3387,6 @@ CODE:
33873387
OUTPUT:
33883388
RETVAL
33893389

3390-
bool
3391-
test_allocfilegv()
3392-
CODE:
3393-
RETVAL = PL_filegvpad[allocfilegv(PL_defgv)] == PL_defgv;
3394-
OUTPUT:
3395-
RETVAL
3396-
33973390
#endif
33983391

33993392
bool

ext/XS-APItest/t/cop.t renamed to ext/XS-APItest/t/copstash.t

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ use Config;
22
use Test::More;
33
BEGIN { plan skip_all => 'no threads' unless $Config{useithreads} }
44

5-
plan tests => 2;
5+
plan tests => 1;
66

77
use XS::APItest;
88

99
ok test_alloccopstash;
10-
ok test_allocfilegv;

gv.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,9 +2105,12 @@ Perl_gv_check(pTHX_ HV *stash)
21052105
continue;
21062106
file = GvFILE(gv);
21072107
CopLINE_set(PL_curcop, GvLINE(gv));
2108-
/* set file name for warning */
2109-
CopFILE_setn(PL_curcop, file, HEK_LEN(GvFILE_HEK(gv)));
2110-
SvREFCNT_dec(CopFILEGV(PL_curcop));
2108+
#ifdef USE_ITHREADS
2109+
CopFILE(PL_curcop) = (char *)file; /* set for warning */
2110+
#else
2111+
CopFILEGV(PL_curcop)
2112+
= gv_fetchfile_flags(file, HEK_LEN(GvFILE_HEK(gv)), 0);
2113+
#endif
21112114
Perl_warner(aTHX_ packWARN(WARN_ONCE),
21122115
"Name \"%"HEKf"::%"HEKf
21132116
"\" used only once: possible typo",

inline.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,6 @@ S_av_top_index(pTHX_ AV *av)
2323
return AvFILL(av);
2424
}
2525

26-
/* ------------------------------- cop.h ------------------------------ */
27-
28-
#ifdef USE_ITHREADS
29-
PERL_STATIC_INLINE void
30-
S_CopFILE_free(pTHX_ COP * const c)
31-
{
32-
GV * const gv = CopFILEGV(c);
33-
if (!gv) return;
34-
if (SvREFCNT(gv) == 1) PL_filegvpad[c->cop_filegvoff] = NULL;
35-
SvREFCNT_dec_NN(gv);
36-
c->cop_filegvoff = 0;
37-
}
38-
#endif
39-
4026
/* ------------------------------- cv.h ------------------------------- */
4127

4228
PERL_STATIC_INLINE I32 *
@@ -122,7 +108,6 @@ PERL_STATIC_INLINE void
122108
S_SvREFCNT_dec_NN(pTHX_ SV *sv)
123109
{
124110
U32 rc = SvREFCNT(sv);
125-
PERL_ARGS_ASSERT_SVREFCNT_DEC_NN;
126111
if (LIKELY(rc > 1))
127112
SvREFCNT(sv) = rc - 1;
128113
else

intrpvar.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -657,9 +657,6 @@ PERLVAR(I, regex_padav, AV *) /* All regex objects, indexed via the
657657
PERLVAR(I, stashpad, HV **) /* for CopSTASH */
658658
PERLVARI(I, stashpadmax, PADOFFSET, 64)
659659
PERLVARI(I, stashpadix, PADOFFSET, 0)
660-
PERLVAR(I, filegvpad, GV **) /* for CopFILEGV */
661-
PERLVARI(I, filegvpadmax, PADOFFSET, 64)
662-
PERLVARI(I, filegvpadix, PADOFFSET, 0)
663660
#endif
664661

665662
#ifdef USE_REENTRANT_API

makedef.pl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,6 @@ sub readvar {
363363
PL_stashpad
364364
PL_stashpadix
365365
PL_stashpadmax
366-
PL_filegvpad
367-
PL_filegvpadix
368-
PL_filegvpadmax
369366
Perl_alloccopstash
370367
Perl_allocfilegv
371368
Perl_clone_params_del

op.c

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -634,64 +634,31 @@ C<PL_stashpad> for the stash passed to it.
634634
*/
635635

636636
#ifdef USE_ITHREADS
637-
638637
PADOFFSET
639-
S_alloc_global_pad_slot(pTHX_ SV *sv, svtype type, SV ***padp,
640-
PADOFFSET *ixp, PADOFFSET *maxp)
638+
Perl_alloccopstash(pTHX_ HV *hv)
641639
{
642640
PADOFFSET off = 0, o = 1;
643641
bool found_slot = FALSE;
644-
SV **pad = *padp;
645642

646-
if (pad[*ixp] == sv) return *ixp;
643+
PERL_ARGS_ASSERT_ALLOCCOPSTASH;
644+
645+
if (PL_stashpad[PL_stashpadix] == hv) return PL_stashpadix;
647646

648-
for (; o < *maxp; ++o) {
649-
if (pad[o] == sv) return *ixp = o;
650-
if (!pad[o] || SvTYPE(pad[o]) != type)
647+
for (; o < PL_stashpadmax; ++o) {
648+
if (PL_stashpad[o] == hv) return PL_stashpadix = o;
649+
if (!PL_stashpad[o] || SvTYPE(PL_stashpad[o]) != SVt_PVHV)
651650
found_slot = TRUE, off = o;
652651
}
653652
if (!found_slot) {
654-
Renew(*padp, *maxp + 10, SV *);
655-
pad = *padp;
656-
Zero(pad + *maxp, 10, SV *);
657-
off = *maxp;
658-
*maxp += 10;
653+
Renew(PL_stashpad, PL_stashpadmax + 10, HV *);
654+
Zero(PL_stashpad + PL_stashpadmax, 10, HV *);
655+
off = PL_stashpadmax;
656+
PL_stashpadmax += 10;
659657
}
660658

661-
pad[*ixp = off] = sv;
659+
PL_stashpad[PL_stashpadix = off] = hv;
662660
return off;
663661
}
664-
665-
PADOFFSET
666-
Perl_alloccopstash(pTHX_ HV *hv)
667-
{
668-
PERL_ARGS_ASSERT_ALLOCCOPSTASH;
669-
return S_alloc_global_pad_slot(aTHX_
670-
(SV *)hv, SVt_PVHV, (SV ***)&PL_stashpad, &PL_stashpadix,
671-
&PL_stashpadmax
672-
);
673-
}
674-
#endif
675-
676-
/*
677-
=for apidoc allocfilegv
678-
679-
Available only under threaded builds, this function allocates an entry in
680-
C<PL_filegvpad> for the GV passed to it.
681-
682-
=cut
683-
*/
684-
685-
#ifdef USE_ITHREADS
686-
PADOFFSET
687-
Perl_allocfilegv(pTHX_ GV *gv)
688-
{
689-
PERL_ARGS_ASSERT_ALLOCFILEGV;
690-
return S_alloc_global_pad_slot(aTHX_
691-
(SV *)gv, SVt_PVGV, (SV ***)&PL_filegvpad, &PL_filegvpadix,
692-
&PL_filegvpadmax
693-
);
694-
}
695662
#endif
696663

697664
/* free the body of an op without examining its contents.
@@ -5752,10 +5719,7 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
57525719
PL_parser->copline = NOLINE;
57535720
}
57545721
#ifdef USE_ITHREADS
5755-
/* While CopFILEGV_set does work under ithreads, this is faster, as it
5756-
avoids a linear scan of the filegv pad: */
5757-
if((cop->cop_filegvoff = PL_curcop->cop_filegvoff))
5758-
SvREFCNT_inc_void_NN(PL_filegvpad[cop->cop_filegvoff]);
5722+
CopFILE_set(cop, CopFILE(PL_curcop)); /* XXX share in a pvtable? */
57595723
#else
57605724
CopFILEGV_set(cop, CopFILEGV(PL_curcop));
57615725
#endif
@@ -10898,7 +10862,7 @@ Perl_rpeep(pTHX_ OP *o)
1089810862
firstcop->cop_line = secondcop->cop_line;
1089910863
#ifdef USE_ITHREADS
1090010864
firstcop->cop_stashoff = secondcop->cop_stashoff;
10901-
firstcop->cop_filegvoff = secondcop->cop_filegvoff;
10865+
firstcop->cop_file = secondcop->cop_file;
1090210866
#else
1090310867
firstcop->cop_stash = secondcop->cop_stash;
1090410868
firstcop->cop_filegv = secondcop->cop_filegv;
@@ -10910,7 +10874,7 @@ Perl_rpeep(pTHX_ OP *o)
1091010874

1091110875
#ifdef USE_ITHREADS
1091210876
secondcop->cop_stashoff = 0;
10913-
secondcop->cop_filegvoff = 0;
10877+
secondcop->cop_file = NULL;
1091410878
#else
1091510879
secondcop->cop_stash = NULL;
1091610880
secondcop->cop_filegv = NULL;

perl.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ perl_construct(pTHXx)
286286
Perl_av_create_and_push(aTHX_ &PL_regex_padav, newSVpvs(""));
287287
PL_regex_pad = AvARRAY(PL_regex_padav);
288288
Newxz(PL_stashpad, PL_stashpadmax, HV *);
289-
Newxz(PL_filegvpad, PL_filegvpadmax, GV *);
290289
#endif
291290
#ifdef USE_REENTRANT_API
292291
Perl_reentrant_init(aTHX);
@@ -1093,7 +1092,6 @@ perl_destruct(pTHXx)
10931092

10941093
#ifdef USE_ITHREADS
10951094
Safefree(PL_stashpad); /* must come after sv_clean_all */
1096-
Safefree(PL_filegvpad);
10971095
#endif
10981096

10991097
AvREAL_off(PL_fdpid); /* no surviving entries */

proto.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ PERL_CALLCONV void Perl_Slab_Free(pTHX_ void *op)
3232
#define PERL_ARGS_ASSERT_SLAB_FREE \
3333
assert(op)
3434

35-
PERL_STATIC_INLINE void S_SvREFCNT_dec_NN(pTHX_ SV *sv)
36-
__attribute__nonnull__(pTHX_1);
37-
#define PERL_ARGS_ASSERT_SVREFCNT_DEC_NN \
38-
assert(sv)
39-
4035
PERL_CALLCONV bool Perl__is_uni_FOO(pTHX_ const U8 classnum, const UV c)
4136
__attribute__warn_unused_result__;
4237

@@ -7651,11 +7646,6 @@ PERL_CALLCONV PADOFFSET Perl_alloccopstash(pTHX_ HV *hv)
76517646
#define PERL_ARGS_ASSERT_ALLOCCOPSTASH \
76527647
assert(hv)
76537648

7654-
PERL_CALLCONV PADOFFSET Perl_allocfilegv(pTHX_ GV *gv)
7655-
__attribute__nonnull__(pTHX_1);
7656-
#define PERL_ARGS_ASSERT_ALLOCFILEGV \
7657-
assert(gv)
7658-
76597649
PERL_CALLCONV void* Perl_any_dup(pTHX_ void* v, const PerlInterpreter* proto_perl)
76607650
__attribute__warn_unused_result__
76617651
__attribute__nonnull__(pTHX_2);

0 commit comments

Comments
 (0)