summaryrefslogtreecommitdiff
path: root/intrpvar.h
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 /intrpvar.h
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 'intrpvar.h')
-rw-r--r--intrpvar.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/intrpvar.h b/intrpvar.h
index 79bddeb8e2..7dc4be4e87 100644
--- a/intrpvar.h
+++ b/intrpvar.h
@@ -76,7 +76,22 @@ PERLVAR(I, curpm, PMOP *) /* what to do \ interps in REs from */
PERLVAR(I, tainting, bool) /* doing taint checks */
PERLVAR(I, tainted, bool) /* using variables controlled by $< */
+
+/* PL_delaymagic is currently used for two purposes: to assure simultaneous
+ * updates in ($<,$>) = ..., and to assure atomic update in push/unshift
+ * @ISA, It works like this: a few places such as pp_push set the DM_DELAY
+ * flag; then various places such as av_store() skip mg_set(ary) if this
+ * flag is set, and various magic vtable methods set flags like
+ * DM_ARRAY_ISA if they've seen something of that ilk. Finally when
+ * control returns to pp_push or whatever, it sees if any of those flags
+ * have been set, and if so finally calls mg_set().
+ *
+ * NB: PL_delaymagic is automatically saved and restored by JUMPENV_PUSH
+ * / POP. This removes the need to do ENTER/SAVEI16(PL_delaymagic)/LEAVE
+ * in hot code like pp_push.
+ */
PERLVAR(I, delaymagic, U16) /* ($<,$>) = ... */
+
PERLVAR(I, localizing, U8) /* are we processing a local() list? */
PERLVAR(I, in_eval, U8) /* trap "fatal" errors? */
PERLVAR(I, defgv, GV *) /* the *_ glob */