summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-10-13 17:02:39 +0100
committerDavid Mitchell <davem@iabyn.com>2015-10-18 12:04:27 +0100
commita68090fe12f676d7c874585fc2727765c009ab06 (patch)
tree977833cffdf360c5de9d2ec700ed78e7c2acb11d /pp.c
parent395391414ee1260c2b34a5f6a353908cc9d48d3f (diff)
downloadperl-a68090fe12f676d7c874585fc2727765c009ab06.tar.gz
optimise save/restore of PL_delaymagic.
A few places (pp_push, pp_unshift, pp_aassign) have to set PL_delaymagic on entry, and restore it on exit. These are hot pieces of code. Rather than using ENTER/SAVEI16(PL_delaymagic)/LEAVE, add an extra field to the jumpenv struct, and make the JUMPENV_PUSH / POP macros automatically save and restore this var. This means that pp_push etc only need to do a local save: U16 old_delaymagic = PL_delaymagic; PL_delaymagic = DM_DELAY; .... PL_delaymagic = old_delaymagic; and in case of an exception being raised, PL_delaymagic still gets restored. This transfers the cost of saving PL_delaymagic from each call to pp_aassign etc to each time a new run level is invoked. The latter should be much less frequent. Note that prior to this commit, pp_aassign wasn't actually saving and restoring PL_delaymagic; it was just setting it to 0 at the end. So this commit also makes pp_aassign safe against PL_delaymagic re-entrancy like pp_push and pp_unshift already were.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/pp.c b/pp.c
index b84747a6cc..6e9995af2a 100644
--- a/pp.c
+++ b/pp.c
@@ -5443,9 +5443,11 @@ PP(pp_push)
/* SPAGAIN; not needed: SP is assigned to immediately below */
}
else {
+ /* PL_delaymagic is restored by JUMPENV_POP on dieing, so we
+ * only need to save locally, not on the save stack */
+ U16 old_delaymagic = PL_delaymagic;
+
if (SvREADONLY(ary) && MARK < SP) Perl_croak_no_modify();
- ENTER;
- SAVEI16(PL_delaymagic);
PL_delaymagic = DM_DELAY;
for (++MARK; MARK <= SP; MARK++) {
SV *sv;
@@ -5457,7 +5459,7 @@ PP(pp_push)
}
if (PL_delaymagic & DM_ARRAY_ISA)
mg_set(MUTABLE_SV(ary));
- LEAVE;
+ PL_delaymagic = old_delaymagic;
}
SP = ORIGMARK;
if (OP_GIMME(PL_op, 0) != G_VOID) {
@@ -5497,10 +5499,12 @@ PP(pp_unshift)
/* SPAGAIN; not needed: SP is assigned to immediately below */
}
else {
+ /* PL_delaymagic is restored by JUMPENV_POP on dieing, so we
+ * only need to save locally, not on the save stack */
+ U16 old_delaymagic = PL_delaymagic;
SSize_t i = 0;
+
av_unshift(ary, SP - MARK);
- ENTER;
- SAVEI16(PL_delaymagic);
PL_delaymagic = DM_DELAY;
while (MARK < SP) {
SV * const sv = newSVsv(*++MARK);
@@ -5508,7 +5512,7 @@ PP(pp_unshift)
}
if (PL_delaymagic & DM_ARRAY_ISA)
mg_set(MUTABLE_SV(ary));
- LEAVE;
+ PL_delaymagic = old_delaymagic;
}
SP = ORIGMARK;
if (OP_GIMME(PL_op, 0) != G_VOID) {