Store a pointer to the op in struct block_loop, rather than the
Nicholas Clark [Sun, 17 Sep 2006 00:06:53 +0000 (00:06 +0000)]
pointers to last and redo. (for ithreads also drop the next pointer,
as pp_ctl.c doesn't re-write it for ithreads). This shrinks the struct
to 40 bytes on ILP32 systems, and therefore struct block to 64 bytes.

p4raw-id: //depot/perl@28858

cop.h
pp_ctl.c
scope.c
sv.c

diff --git a/cop.h b/cop.h
index a630b64..66b7ffb 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -393,13 +393,14 @@ struct block_eval {
 struct block_loop {
     char *     label;
     I32                resetsp;
-    OP *       redo_op;
-    OP *       next_op;
-    OP *       last_op;
+    LOOP *     my_op;  /* My op, that contains redo, next and last ops.  */
+    /* (except for non_ithreads we need to modify next_op in pp_ctl.c, hence
+       why next_op is conditionally defined below.)  */
 #ifdef USE_ITHREADS
     void *     iterdata;
     PAD                *oldcomppad;
 #else
+    OP *       next_op;
     SV **      itervar;
 #endif
     SV *       itersave;
@@ -432,12 +433,19 @@ struct block_loop {
            cx->blk_loop.itersave = NULL;
 #endif
 
+#ifdef USE_ITHREADS
+#  define PUSHLOOP_OP_NEXT             /* No need to do anything.  */
+#  define CX_LOOP_NEXTOP_GET(cx)       ((cx)->blk_loop.my_op->op_nextop + 0)
+#else
+#  define PUSHLOOP_OP_NEXT             cx->blk_loop.next_op = cLOOP->op_nextop
+#  define CX_LOOP_NEXTOP_GET(cx)       ((cx)->blk_loop.next_op + 0)
+#endif
+
 #define PUSHLOOP(cx, dat, s)                                           \
        cx->blk_loop.label = PL_curcop->cop_label;                      \
        cx->blk_loop.resetsp = s - PL_stack_base;                       \
-       cx->blk_loop.redo_op = cLOOP->op_redoop;                        \
-       cx->blk_loop.next_op = cLOOP->op_nextop;                        \
-       cx->blk_loop.last_op = cLOOP->op_lastop;                        \
+       cx->blk_loop.my_op = cLOOP;                                     \
+       PUSHLOOP_OP_NEXT;                                               \
        cx->blk_loop.iterlval = NULL;                                   \
        cx->blk_loop.iterary = NULL;                                    \
        cx->blk_loop.iterix = -1;                                       \
index 15a1491..c1df86e 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2113,7 +2113,7 @@ PP(pp_last)
     case CXt_LOOP:
        pop2 = CXt_LOOP;
        newsp = PL_stack_base + cx->blk_loop.resetsp;
-       nextop = cx->blk_loop.last_op->op_next;
+       nextop = cx->blk_loop.my_op->op_lastop->op_next;
        break;
     case CXt_SUB:
        pop2 = CXt_SUB;
@@ -2196,7 +2196,7 @@ PP(pp_next)
     if (PL_scopestack_ix < inner)
        leave_scope(PL_scopestack[PL_scopestack_ix]);
     PL_curcop = cx->blk_oldcop;
-    return cx->blk_loop.next_op;
+    return CX_LOOP_NEXTOP_GET(cx);
 }
 
 PP(pp_redo)
@@ -2220,7 +2220,7 @@ PP(pp_redo)
     if (cxix < cxstack_ix)
        dounwind(cxix);
 
-    redo_op = cxstack[cxix].blk_loop.redo_op;
+    redo_op = cxstack[cxix].blk_loop.my_op->op_redoop;
     if (redo_op->op_type == OP_ENTER) {
        /* pop one less context to avoid $x being freed in while (my $x..) */
        cxstack_ix++;
@@ -4245,7 +4245,7 @@ PP(pp_break)
     PL_curcop = cx->blk_oldcop;
 
     if (CxFOREACH(cx))
-       return cx->blk_loop.next_op;
+       return CX_LOOP_NEXTOP_GET(cx);
     else
        return cx->blk_givwhen.leave_op;
 }
diff --git a/scope.c b/scope.c
index a2a0f3a..8923104 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -1069,12 +1069,10 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
                cx->blk_loop.label);
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.RESETSP = %ld\n",
                (long)cx->blk_loop.resetsp);
-       PerlIO_printf(Perl_debug_log, "BLK_LOOP.REDO_OP = 0x%"UVxf"\n",
-               PTR2UV(cx->blk_loop.redo_op));
+       PerlIO_printf(Perl_debug_log, "BLK_LOOP.MY_OP = 0x%"UVxf"\n",
+               PTR2UV(cx->blk_loop.my_op));
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.NEXT_OP = 0x%"UVxf"\n",
-               PTR2UV(cx->blk_loop.next_op));
-       PerlIO_printf(Perl_debug_log, "BLK_LOOP.LAST_OP = 0x%"UVxf"\n",
-               PTR2UV(cx->blk_loop.last_op));
+               PTR2UV(CX_LOOP_NEXTOP_GET(cx)));
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERIX = %ld\n",
                (long)cx->blk_loop.iterix);
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERARY = 0x%"UVxf"\n",
diff --git a/sv.c b/sv.c
index d0cf661..c82f2d6 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -10309,9 +10309,7 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
            case CXt_LOOP:
                ncx->blk_loop.label     = cx->blk_loop.label;
                ncx->blk_loop.resetsp   = cx->blk_loop.resetsp;
-               ncx->blk_loop.redo_op   = cx->blk_loop.redo_op;
-               ncx->blk_loop.next_op   = cx->blk_loop.next_op;
-               ncx->blk_loop.last_op   = cx->blk_loop.last_op;
+               ncx->blk_loop.my_op     = cx->blk_loop.my_op;
                ncx->blk_loop.iterdata  = (CxPADLOOP(cx)
                                           ? cx->blk_loop.iterdata
                                           : gv_dup((GV*)cx->blk_loop.iterdata, param));