make SVs_PADTMP and SVs_PADSTALE share a bit

SVs_PADSTALE is only meaningful with SVs_PADMY, while
SVs_PADTMP is only meaningful with !SVs_PADMY,
so let them share the same flag bit.

Note that this doesn't yet free a bit in SvFLAGS, as the two
bits are also used for SVpad_STATE, SVpad_TYPED.

(This is is follow-on to 62bb6514085e5eddc42b4fdaf3713ccdb7f1da85.)
This commit is contained in:
David Mitchell 2011-10-07 15:38:56 +01:00
parent d0c0e7dd0c
commit 9a214eecd0
6 changed files with 48 additions and 31 deletions

6
dump.c
View File

@ -1527,10 +1527,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
if (!((flags & SVpad_NAME) == SVpad_NAME
&& (type == SVt_PVMG || type == SVt_PVNV))) {
if (flags & SVs_PADSTALE) sv_catpv(d, "PADSTALE,");
if ((flags & SVs_PADMY) && (flags & SVs_PADSTALE))
sv_catpv(d, "PADSTALE,");
}
if (!((flags & SVpad_NAME) == SVpad_NAME && type == SVt_PVMG)) {
if (flags & SVs_PADTMP) sv_catpv(d, "PADTMP,");
if (!(flags & SVs_PADMY) && (flags & SVs_PADTMP))
sv_catpv(d, "PADTMP,");
if (flags & SVs_PADMY) sv_catpv(d, "PADMY,");
}
append_flags(d, flags, first_sv_flags_names);

2
pad.c
View File

@ -1720,7 +1720,7 @@ Perl_pad_free(pTHX_ PADOFFSET po)
);
if (PL_curpad[po] && PL_curpad[po] != &PL_sv_undef) {
SvPADTMP_off(PL_curpad[po]);
SvFLAGS(PL_curpad[po]) &= ~SVs_PADTMP; /* also clears SVs_PADSTALE */
}
if ((I32)po < PL_padix)
PL_padix = po - 1;

View File

@ -2082,11 +2082,17 @@ PP(pp_dbstate)
STATIC SV **
S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 flags)
{
bool padtmp = 0;
PERL_ARGS_ASSERT_ADJUST_STACK_ON_LEAVE;
if (flags & SVs_PADTMP) {
flags &= ~SVs_PADTMP;
padtmp = 1;
}
if (gimme == G_SCALAR) {
if (MARK < SP)
*++newsp = (SvFLAGS(*SP) & flags) ? *SP : sv_mortalcopy(*SP);
*++newsp = ((SvFLAGS(*SP) & flags) || (padtmp && SvPADTMP(*SP)))
? *SP : sv_mortalcopy(*SP);
else {
/* MEXTEND() only updates MARK, so reuse it instead of newsp. */
MARK = newsp;
@ -2098,7 +2104,7 @@ S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 fla
else if (gimme == G_ARRAY) {
/* in case LEAVE wipes old return values */
while (++MARK <= SP) {
if (SvFLAGS(*MARK) & flags)
if ((SvFLAGS(*MARK) & flags) || (padtmp && SvPADTMP(*MARK)))
*++newsp = *MARK;
else {
*++newsp = sv_mortalcopy(*MARK);

View File

@ -922,7 +922,8 @@ Perl_leave_scope(pTHX_ I32 base)
SvPADSTALE_on(sv); /* mark as no longer live */
}
else { /* Someone has a claim on this, so abandon it. */
const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
assert( SvFLAGS(sv) & SVs_PADMY);
assert(!(SvFLAGS(sv) & SVs_PADTMP));
switch (SvTYPE(sv)) { /* Console ourselves with a new value */
case SVt_PVAV: *(SV**)ptr = MUTABLE_SV(newAV()); break;
case SVt_PVHV: *(SV**)ptr = MUTABLE_SV(newHV()); break;
@ -931,7 +932,7 @@ Perl_leave_scope(pTHX_ I32 base)
SvREFCNT_dec(sv); /* Cast current value to the winds. */
/* preserve pad nature, but also mark as not live
* for any closure capturing */
SvFLAGS(*(SV**)ptr) |= padflags | SVs_PADSTALE;
SvFLAGS(*(SV**)ptr) |= (SVs_PADMY|SVs_PADSTALE);
}
break;
case SAVEt_DELETE:

6
sv.c
View File

@ -2228,7 +2228,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
if (isGV_with_GP(sv))
return glob_2number(MUTABLE_GV(sv));
if (!(SvFLAGS(sv) & SVs_PADTMP)) {
if (!SvPADTMP(sv)) {
if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
}
@ -2613,7 +2613,7 @@ Perl_sv_2nv_flags(pTHX_ register SV *const sv, const I32 flags)
return 0.0;
}
if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
assert (SvTYPE(sv) >= SVt_NV);
/* Typically the caller expects that sv_any is not NULL now. */
@ -2975,7 +2975,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags
*lp = 0;
if (flags & SV_UNDEF_RETURNS_NULL)
return NULL;
if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
if (SvTYPE(sv) < SVt_PV)
/* Typically the caller expects that sv_any is not NULL now. */

50
sv.h
View File

@ -310,9 +310,10 @@ perform the upgrade if necessary. See C<svtype>.
CvIMPORTED_CV_ON() if it needs to be
expanded to a real GV */
#define SVs_PADSTALE 0x00010000 /* lexical has gone out of scope */
#define SVpad_STATE 0x00010000 /* pad name is a "state" var */
#define SVs_PADTMP 0x00020000 /* in use as tmp */
#define SVs_PADTMP 0x00020000 /* in use as tmp; only if ! SVs_PADMY */
#define SVs_PADSTALE 0x00020000 /* lexical has gone out of scope;
only valid for SVs_PADMY */
#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */
#define SVs_PADMY 0x00040000 /* in use a "my" variable */
#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */
@ -909,34 +910,41 @@ the scalar's value cannot change unless written to.
#define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST)
#define SvPADSTALE(sv) (SvFLAGS(sv) & SVs_PADSTALE)
#define SvPADSTALE_off(sv) (SvFLAGS(sv) &= ~SVs_PADSTALE)
#define SvPADTMP(sv) (SvFLAGS(sv) & SVs_PADTMP)
#define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP)
#define SvPADMY(sv) (SvFLAGS(sv) & SVs_PADMY)
#define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY)
/* SVs_PADTMP and SVs_PADSTALE share the same bit, mediated by SVs_PADMY */
#define SvPADTMP(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP)) == SVs_PADTMP)
#define SvPADSTALE(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADSTALE)) \
== (SVs_PADMY|SVs_PADSTALE))
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define SvPADTMP_on(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(!(SvFLAGS(_svpad) & (SVs_PADMY|SVs_PADSTALE))); \
(SvFLAGS(_svpad) |= SVs_PADTMP); \
# define SvPADTMP_on(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(!(SvFLAGS(_svpad) & SVs_PADMY)); \
SvFLAGS(_svpad) |= SVs_PADTMP; \
})
# define SvPADMY_on(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(!(SvFLAGS(_svpad) & SVs_PADTMP)); \
(SvFLAGS(_svpad) |= SVs_PADMY); \
# define SvPADTMP_off(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(!(SvFLAGS(_svpad) & SVs_PADMY)); \
SvFLAGS(_svpad) &= ~SVs_PADTMP; \
})
# define SvPADSTALE_on(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(!(SvFLAGS(_svpad) & SVs_PADTMP)); \
(SvFLAGS(_svpad) |= SVs_PADSTALE); \
# define SvPADSTALE_on(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(SvFLAGS(_svpad) & SVs_PADMY); \
SvFLAGS(_svpad) |= SVs_PADSTALE; \
})
# define SvPADSTALE_off(sv) ({ \
SV *const _svpad = MUTABLE_SV(sv); \
assert(SvFLAGS(_svpad) & SVs_PADMY); \
SvFLAGS(_svpad) &= ~SVs_PADSTALE; \
})
#else
# define SvPADTMP_on(sv) (SvFLAGS(sv) |= SVs_PADTMP)
# define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY)
# define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP)
# define SvPADSTALE_on(sv) (SvFLAGS(sv) |= SVs_PADSTALE)
# define SvPADSTALE_off(sv) (SvFLAGS(sv) &= ~SVs_PADSTALE)
#endif
#define SvTEMP(sv) (SvFLAGS(sv) & SVs_TEMP)