diff options
author | David Mitchell <davem@iabyn.com> | 2015-10-13 17:02:39 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2015-10-18 12:04:27 +0100 |
commit | a68090fe12f676d7c874585fc2727765c009ab06 (patch) | |
tree | 977833cffdf360c5de9d2ec700ed78e7c2acb11d /pp_hot.c | |
parent | 395391414ee1260c2b34a5f6a353908cc9d48d3f (diff) | |
download | perl-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_hot.c')
-rw-r--r-- | pp_hot.c | 5 |
1 files changed, 4 insertions, 1 deletions
@@ -1174,6 +1174,9 @@ PP(pp_aassign) SSize_t i; int magic; U32 lval; + /* 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; #ifdef DEBUGGING bool fake = 0; #endif @@ -1545,7 +1548,7 @@ PP(pp_aassign) PERL_UNUSED_VAR(tmp_egid); #endif } - PL_delaymagic = 0; + PL_delaymagic = old_delaymagic; if (gimme == G_VOID) SP = firstrelem - 1; |