summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2008-01-24 13:57:20 +0000
committerNicholas Clark <nick@ccl4.org>2008-01-24 13:57:20 +0000
commit493b0a3c46c2cc9f06bf88c450ded6aa981c4fd3 (patch)
tree7d6dfdd735cd260a345eb8489b3d7976428943eb
parentc25bf6989edf21dd302c4e306179cfffbc11bb5f (diff)
downloadperl-493b0a3c46c2cc9f06bf88c450ded6aa981c4fd3.tar.gz
In struct block_loop, merge itermax and iterlval into a union
lval_max_u, as CXt_LOOP_LAZYIV doesn't use iterlval and the other LOOP types don't use itermax. This reduces struct block_loop by 1 IV. As it's the largest component of the unions making up struct context, this reduces struct context. On ILP32 it will now be 56 bytes, down from the 64 of 5.10.x, as I've already removed the element 'label'. p4raw-id: //depot/perl@33063
-rw-r--r--cop.h28
-rw-r--r--pp_ctl.c7
-rw-r--r--pp_hot.c13
-rw-r--r--scope.c2
-rw-r--r--sv.c5
5 files changed, 23 insertions, 32 deletions
diff --git a/cop.h b/cop.h
index 7c505375e5..36f1a63fc7 100644
--- a/cop.h
+++ b/cop.h
@@ -443,9 +443,14 @@ struct block_loop {
SV ** itervar;
#endif
SV * itersave;
+ union {
/* (from inspection of source code) for a .. range of strings this is the
current string. */
- SV * iterlval;
+ SV * iterlval;
+ /* (from inspection of source code) for a .. range of numbers this is the
+ maximum value. */
+ IV itermax;
+ } lval_max_u;
union {
/* (from inspection of source code) for a foreach loop this is the array
being iterated over. For a .. range of numbers it's the current value.
@@ -456,19 +461,7 @@ struct block_loop {
IV itermin;
} ary_min_u;
IV iterix;
- /* (from inspection of source code) for a .. range of numbers this is the
- maximum value. */
- IV itermax;
};
-/* It might be possible to squeeze this structure further. As best I can tell
- itermax and iterlval are never used at the same time, so it might be possible
- to make them into a union. However, I'm not confident that there are enough
- flag bits/NULLable pointers in this structure alone to encode which is
- active. There is, however, U8 of space free in struct block, which could be
- used. Right now it may not be worth squeezing this structure further, as it's
- the largest part of struct block, and currently struct block is 64 bytes on
- an ILP32 system, which will give good cache alignment.
-*/
#ifdef USE_ITHREADS
# define CxITERVAR(c) \
@@ -508,7 +501,7 @@ struct block_loop {
cx->blk_loop.resetsp = s - PL_stack_base; \
cx->blk_loop.my_op = cLOOP; \
PUSHLOOP_OP_NEXT; \
- cx->blk_loop.iterlval = NULL; \
+ cx->blk_loop.lval_max_u.iterlval = NULL; \
cx->blk_loop.ary_min_u.iterary = NULL; \
CX_ITERDATA_SET(cx,NULL);
@@ -516,15 +509,14 @@ struct block_loop {
cx->blk_loop.resetsp = s - PL_stack_base; \
cx->blk_loop.my_op = cLOOP; \
PUSHLOOP_OP_NEXT; \
- cx->blk_loop.iterlval = NULL; \
+ cx->blk_loop.lval_max_u.iterlval = NULL; \
cx->blk_loop.ary_min_u.iterary = NULL; \
cx->blk_loop.iterix = -1; \
CX_ITERDATA_SET(cx,dat);
#define POPLOOP(cx) \
- if (CxTYPE(cx) == CXt_LOOP_LAZYIV) \
- assert(!cx->blk_loop.iterlval); \
- SvREFCNT_dec(cx->blk_loop.iterlval); \
+ if (CxTYPE(cx) != CXt_LOOP_LAZYIV) \
+ SvREFCNT_dec(cx->blk_loop.lval_max_u.iterlval); \
if (CxITERVAR(cx)) { \
if (SvPADMY(cx->blk_loop.itersave)) { \
SV ** const s_v_p = CxITERVAR(cx); \
diff --git a/pp_ctl.c b/pp_ctl.c
index baacd41b37..20df1342a5 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1913,20 +1913,19 @@ PP(pp_enteriter)
#endif
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.iterix = SvIV(sv);
- cx->blk_loop.itermax = SvIV(right);
+ cx->blk_loop.lval_max_u.itermax = SvIV(right);
#ifdef DEBUGGING
/* for correct -Dstv display */
cx->blk_oldsp = sp - PL_stack_base;
#endif
}
else {
- cx->blk_loop.iterlval = newSVsv(sv);
- (void) SvPV_force_nolen(cx->blk_loop.iterlval);
+ cx->blk_loop.lval_max_u.iterlval = newSVsv(sv);
+ (void) SvPV_force_nolen(cx->blk_loop.lval_max_u.iterlval);
(void) SvPV_nolen_const(right);
}
}
else if (PL_op->op_private & OPpITER_REVERSED) {
- cx->blk_loop.itermax = 0xDEADBEEF;
cx->blk_loop.iterix = AvFILL(cx->blk_loop.ary_min_u.iterary) + 1;
}
diff --git a/pp_hot.c b/pp_hot.c
index f963f0cff9..4e55f2678b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1917,7 +1917,7 @@ PP(pp_iter)
/* iterate ($min .. $max) */
if (CxTYPE(cx) != CXt_LOOP_LAZYIV) {
/* string increment */
- register SV* cur = cx->blk_loop.iterlval;
+ register SV* cur = cx->blk_loop.lval_max_u.iterlval;
STRLEN maxlen = 0;
const char *max =
SvOK((SV*)av) ?
@@ -1945,8 +1945,7 @@ PP(pp_iter)
RETPUSHNO;
}
/* integer increment */
- assert(!cx->blk_loop.iterlval);
- if (cx->blk_loop.iterix > cx->blk_loop.itermax)
+ if (cx->blk_loop.iterix > cx->blk_loop.lval_max_u.itermax)
RETPUSHNO;
/* don't risk potential race */
@@ -1966,10 +1965,10 @@ PP(pp_iter)
/* Handle end of range at IV_MAX */
if ((cx->blk_loop.iterix == IV_MIN) &&
- (cx->blk_loop.itermax == IV_MAX))
+ (cx->blk_loop.lval_max_u.itermax == IV_MAX))
{
cx->blk_loop.iterix++;
- cx->blk_loop.itermax++;
+ cx->blk_loop.lval_max_u.itermax++;
}
RETPUSHYES;
@@ -2014,7 +2013,7 @@ PP(pp_iter)
else
sv = &PL_sv_undef;
if (av != PL_curstack && sv == &PL_sv_undef) {
- SV *lv = cx->blk_loop.iterlval;
+ SV *lv = cx->blk_loop.lval_max_u.iterlval;
if (lv && SvREFCNT(lv) > 1) {
SvREFCNT_dec(lv);
lv = NULL;
@@ -2022,7 +2021,7 @@ PP(pp_iter)
if (lv)
SvREFCNT_dec(LvTARG(lv));
else {
- lv = cx->blk_loop.iterlval = newSV_type(SVt_PVLV);
+ lv = cx->blk_loop.lval_max_u.iterlval = newSV_type(SVt_PVLV);
LvTYPE(lv) = 'y';
sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
}
diff --git a/scope.c b/scope.c
index e02a302812..c78c33c76a 100644
--- a/scope.c
+++ b/scope.c
@@ -1104,7 +1104,7 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERSAVE = 0x%"UVxf"\n",
PTR2UV(cx->blk_loop.itersave));
PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERLVAL = 0x%"UVxf"\n",
- PTR2UV(cx->blk_loop.iterlval));
+ PTR2UV(cx->blk_loop.lval_max_u.iterlval));
break;
case CXt_SUBST:
diff --git a/sv.c b/sv.c
index 514a775750..39b2359d4f 100644
--- a/sv.c
+++ b/sv.c
@@ -10557,8 +10557,9 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
ncx->blk_loop.oldcomppad);
ncx->blk_loop.itersave = sv_dup_inc(ncx->blk_loop.itersave,
param);
- ncx->blk_loop.iterlval = sv_dup_inc(ncx->blk_loop.iterlval,
- param);
+ if (CxTYPE(ncx) != CXt_LOOP_LAZYIV)
+ ncx->blk_loop.lval_max_u.iterlval
+ = sv_dup_inc(ncx->blk_loop.lval_max_u.iterlval, param);
break;
case CXt_FORMAT:
ncx->blk_format.cv = cv_dup(ncx->blk_format.cv, param);