Skip to content

Commit 740449b

Browse files
committed
add PL_curstackinfo->si_cxsubix field
This tracks the most recent sub/eval/format context pushed onto the context stack. Then make dopopto_cursub use it. The previous value is saved in the cxt struct, and is restored whenever the context is popped. This adds a tiny overhead for every sub call, but speeds up other operations, such as determining the caller context when returning a value from a sub - this has to be dpne for every sub call where the last expression is context sensitive, so its often a win.
1 parent 20550e1 commit 740449b

File tree

5 files changed

+21
-1
lines changed

5 files changed

+21
-1
lines changed

cop.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ C<*len>. Upon return, C<*flags> will be set to either C<SVf_UTF8> or 0.
585585
/* subroutine context */
586586
struct block_sub {
587587
OP * retop; /* op to execute on exit from sub */
588+
I32 old_cxsubix; /* previous value of si_cxsubix */
588589
/* Above here is the same for sub, format and eval. */
589590
PAD *prevcomppad; /* the caller's PL_comppad */
590591
CV * cv;
@@ -597,6 +598,7 @@ struct block_sub {
597598
/* format context */
598599
struct block_format {
599600
OP * retop; /* op to execute on exit from sub */
601+
I32 old_cxsubix; /* previous value of si_cxsubix */
600602
/* Above here is the same for sub, format and eval. */
601603
PAD *prevcomppad; /* the caller's PL_comppad */
602604
CV * cv;
@@ -663,6 +665,7 @@ struct block_format {
663665
/* eval context */
664666
struct block_eval {
665667
OP * retop; /* op to execute on exit from eval */
668+
I32 old_cxsubix; /* previous value of si_cxsubix */
666669
/* Above here is the same for sub, format and eval. */
667670
SV * old_namesv;
668671
OP * old_eval_root;
@@ -1026,6 +1029,7 @@ struct stackinfo {
10261029
struct stackinfo * si_next;
10271030
I32 si_cxix; /* current context index */
10281031
I32 si_cxmax; /* maximum allocated index */
1032+
I32 si_cxsubix; /* topmost sub/eval/format */
10291033
I32 si_type; /* type of runlevel */
10301034
I32 si_markoff; /* offset where markstack begins for us.
10311035
* currently used only with DEBUGGING,
@@ -1072,6 +1076,7 @@ typedef struct stackinfo PERL_SI;
10721076
} \
10731077
next->si_type = type; \
10741078
next->si_cxix = -1; \
1079+
next->si_cxsubix = -1; \
10751080
PUSHSTACK_INIT_HWM(next); \
10761081
AvFILLp(next->si_stack) = 0; \
10771082
SWITCHSTACK(PL_curstack,next->si_stack); \

inline.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,6 +2134,8 @@ Perl_cx_pushsub(pTHX_ PERL_CONTEXT *cx, CV *cv, OP *retop, bool hasargs)
21342134
PERL_ARGS_ASSERT_CX_PUSHSUB;
21352135

21362136
PERL_DTRACE_PROBE_ENTRY(cv);
2137+
cx->blk_sub.old_cxsubix = PL_curstackinfo->si_cxsubix;
2138+
PL_curstackinfo->si_cxsubix = cx - PL_curstackinfo->si_cxstack;
21372139
cx->blk_sub.cv = cv;
21382140
cx->blk_sub.olddepth = CvDEPTH(cv);
21392141
cx->blk_sub.prevcomppad = PL_comppad;
@@ -2160,6 +2162,7 @@ Perl_cx_popsub_common(pTHX_ PERL_CONTEXT *cx)
21602162
CvDEPTH(cv) = cx->blk_sub.olddepth;
21612163
cx->blk_sub.cv = NULL;
21622164
SvREFCNT_dec(cv);
2165+
PL_curstackinfo->si_cxsubix = cx->blk_sub.old_cxsubix;
21632166
}
21642167

21652168

@@ -2206,6 +2209,8 @@ Perl_cx_pushformat(pTHX_ PERL_CONTEXT *cx, CV *cv, OP *retop, GV *gv)
22062209
{
22072210
PERL_ARGS_ASSERT_CX_PUSHFORMAT;
22082211

2212+
cx->blk_format.old_cxsubix = PL_curstackinfo->si_cxsubix;
2213+
PL_curstackinfo->si_cxsubix= cx - PL_curstackinfo->si_cxstack;
22092214
cx->blk_format.cv = cv;
22102215
cx->blk_format.retop = retop;
22112216
cx->blk_format.gv = gv;
@@ -2239,6 +2244,7 @@ Perl_cx_popformat(pTHX_ PERL_CONTEXT *cx)
22392244
cx->blk_format.cv = NULL;
22402245
--CvDEPTH(cv);
22412246
SvREFCNT_dec_NN(cv);
2247+
PL_curstackinfo->si_cxsubix = cx->blk_format.old_cxsubix;
22422248
}
22432249

22442250

@@ -2247,6 +2253,8 @@ Perl_cx_pusheval(pTHX_ PERL_CONTEXT *cx, OP *retop, SV *namesv)
22472253
{
22482254
PERL_ARGS_ASSERT_CX_PUSHEVAL;
22492255

2256+
cx->blk_eval.old_cxsubix = PL_curstackinfo->si_cxsubix;
2257+
PL_curstackinfo->si_cxsubix= cx - PL_curstackinfo->si_cxstack;
22502258
cx->blk_eval.retop = retop;
22512259
cx->blk_eval.old_namesv = namesv;
22522260
cx->blk_eval.old_eval_root = PL_eval_root;
@@ -2282,6 +2290,7 @@ Perl_cx_popeval(pTHX_ PERL_CONTEXT *cx)
22822290
cx->blk_eval.old_namesv = NULL;
22832291
SvREFCNT_dec_NN(sv);
22842292
}
2293+
PL_curstackinfo->si_cxsubix = cx->blk_eval.old_cxsubix;
22852294
}
22862295

22872296

pp_ctl.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737
#define RUN_PP_CATCHABLY(thispp) \
3838
STMT_START { if (CATCH_GET) return docatch(thispp); } STMT_END
3939

40-
#define dopopto_cursub() dopoptosub_at(cxstack, cxstack_ix)
40+
#define dopopto_cursub() \
41+
(PL_curstackinfo->si_cxsubix >= 0 \
42+
? PL_curstackinfo->si_cxsubix \
43+
: dopoptosub_at(cxstack, cxstack_ix))
44+
4145
#define dopoptosub(plop) dopoptosub_at(cxstack, (plop))
4246

4347
PP(pp_wantarray)

scope.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Perl_new_stackinfo(pTHX_ I32 stitems, I32 cxitems)
8282
si->si_next = 0;
8383
si->si_cxmax = cxitems - 1;
8484
si->si_cxix = -1;
85+
si->si_cxsubix = -1;
8586
si->si_type = PERLSI_UNDEF;
8687
Newx(si->si_cxstack, cxitems, PERL_CONTEXT);
8788
/* Without any kind of initialising CX_PUSHSUBST()

sv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14690,6 +14690,7 @@ Perl_si_dup(pTHX_ PERL_SI *si, CLONE_PARAMS* param)
1469014690

1469114691
nsi->si_stack = av_dup_inc(si->si_stack, param);
1469214692
nsi->si_cxix = si->si_cxix;
14693+
nsi->si_cxsubix = si->si_cxsubix;
1469314694
nsi->si_cxmax = si->si_cxmax;
1469414695
nsi->si_cxstack = cx_dup(si->si_cxstack, si->si_cxix, si->si_cxmax, param);
1469514696
nsi->si_type = si->si_type;

0 commit comments

Comments
 (0)