remove eval's usage of SvSCREAM
authorDavid Mitchell <davem@iabyn.com>
Thu, 10 Nov 2016 14:44:10 +0000 (14:44 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 12 Nov 2016 16:15:09 +0000 (16:15 +0000)
Currently the SvSCREAM flag is set on the sv pointed to by
cx->blk_eval.cur_text, to indicate that it is ref counted.

Instead, use a spare bit in the blk_u16 field of the eval context.
This is to reduce the number of odd special cases for the SvSCREAM flag.

cop.h
inline.h
sv.c
sv.h
toke.c

diff --git a/cop.h b/cop.h
index b371379..0443e24 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -640,8 +640,11 @@ struct block_eval {
    blku_gimme is actually also only 2 bits, so could be merged with something.
 */
 
-#define CxOLD_IN_EVAL(cx)      (((cx)->blk_u16) & 0x7F)
-#define CxOLD_OP_TYPE(cx)      (((cx)->blk_u16) >> 7)
+/* blk_u16 bit usage for eval contexts: */
+
+#define CxOLD_IN_EVAL(cx)      (((cx)->blk_u16) & 0x3F) /* saved PL in_eval */
+#define CxEVAL_TXT_REFCNTED(cx)        (((cx)->blk_u16) & 0x40) /* cur_text rc++ */
+#define CxOLD_OP_TYPE(cx)      (((cx)->blk_u16) >> 7)   /* type of eval op */
 
 /* loop context */
 struct block_loop {
@@ -961,6 +964,7 @@ L<perlcall>.
 #define EVAL_KEEPERR   4       /* set by Perl_call_sv if G_KEEPERR */
 #define EVAL_INREQUIRE 8       /* The code is being required. */
 #define EVAL_RE_REPARSING 0x10 /* eval_sv() called with G_RE_REPARSING */
+/* if adding extra bits, make sure they can fit in CxOLD_OP_TYPE() */
 
 /* Support for switching (stack and block) contexts.
  * This ensures magic doesn't invalidate local stack and cx pointers.
index adcd85d..5d516da 100644 (file)
--- a/inline.h
+++ b/inline.h
@@ -1490,9 +1490,9 @@ S_cx_pusheval(pTHX_ PERL_CONTEXT *cx, OP *retop, SV *namesv)
     cx->blk_eval.cv            = NULL; /* later set by doeval_compile() */
     cx->blk_eval.cur_top_env   = PL_top_env;
 
-    assert(!(PL_in_eval     & ~ 0x7F));
+    assert(!(PL_in_eval     & ~ 0x3F));
     assert(!(PL_op->op_type & ~0x1FF));
-    cx->blk_u16 = (PL_in_eval & 0x7F) | ((U16)PL_op->op_type << 7);
+    cx->blk_u16 = (PL_in_eval & 0x3F) | ((U16)PL_op->op_type << 7);
 }
 
 
@@ -1505,9 +1505,10 @@ S_cx_popeval(pTHX_ PERL_CONTEXT *cx)
     assert(CxTYPE(cx) == CXt_EVAL);
 
     PL_in_eval = CxOLD_IN_EVAL(cx);
+    assert(!(PL_in_eval & 0xc0));
     PL_eval_root = cx->blk_eval.old_eval_root;
     sv = cx->blk_eval.cur_text;
-    if (sv && SvSCREAM(sv)) {
+    if (sv && CxEVAL_TXT_REFCNTED(cx)) {
         cx->blk_eval.cur_text = NULL;
         SvREFCNT_dec_NN(sv);
     }
diff --git a/sv.c b/sv.c
index b2403e3..78b3169 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -14150,7 +14150,7 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
            case CXt_EVAL:
                ncx->blk_eval.old_namesv = sv_dup_inc(ncx->blk_eval.old_namesv,
                                                      param);
-                /* XXX should this sv_dup_inc? Or only if SvSCREAM ???? */
+                /* XXX should this sv_dup_inc? Or only if CxEVAL_TXT_REFCNTED ???? */
                ncx->blk_eval.cur_text  = sv_dup(ncx->blk_eval.cur_text, param);
                ncx->blk_eval.cv = cv_dup(ncx->blk_eval.cv, param);
                 /* XXX what do do with cur_top_env ???? */
diff --git a/sv.h b/sv.h
index d45a4a9..0c1a42d 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -370,7 +370,6 @@ perform the upgrade if necessary.  See C<L</svtype>>.
 #define SVp_NOK                0x00002000  /* has valid non-public numeric value */
 #define SVp_POK                0x00004000  /* has valid non-public pointer value */
 #define SVp_SCREAM     0x00008000  /* method name is DOES */
-                                    /* eval cx text is ref counted */
 #define SVphv_CLONEABLE        SVp_SCREAM  /* PVHV (stashes) clone its objects */
 #define SVpgv_GP       SVp_SCREAM  /* GV has a valid GP */
 #define SVprv_PCS_IMPORTED  SVp_SCREAM  /* RV is a proxy for a constant
diff --git a/toke.c b/toke.c
index ac7b5f3..2bc9fb2 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9716,7 +9716,7 @@ S_scan_heredoc(pTHX_ char *s)
             && cx->blk_eval.cur_text == linestr)
         {
            cx->blk_eval.cur_text = newSVsv(linestr);
-           SvSCREAM_on(cx->blk_eval.cur_text);
+           cx->blk_u16 |= 0x40; /* indicate cur_text is ref counted */
        }
        /* Copy everything from s onwards back to d. */
        Move(s,d,bufend-s + 1,char);