summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2012-11-20 17:36:54 -0500
committerFather Chrysostomos <sprout@cpan.org>2012-11-21 06:04:11 -0800
commit4cc783efe0ed9495ebcbefd8494083a4b6160e6f (patch)
tree2219434786bdd0f06e01dd2d1c523da125866c17 /pp_hot.c
parent2a5bd8731bfdd9308c12fac06faa637e38b5eeb5 (diff)
downloadperl-4cc783efe0ed9495ebcbefd8494083a4b6160e6f.tar.gz
refactor pp_stringify and pp_and
pp_stringify: First, move all the SP/stack operations to before the first call in pp_stringify (sv_copypv), this allows SP to never be saved across any calls. SETTARG calls set magic, so that still has to be done. SETs does not ++/-- SP, so no need to do a PUTBACK. PL_op is read twice, once for TARG, once for NORMAL. No point in caching it through the sv_copypv call since its not worth saving a non-vol to C stack (x86) just to avoid 2 mem acesses. This opcode now only has 2 vars saved across sv_copypv, my_perl and TARG. pp_stringify dropped from 0x3F to 0x3C for me after these changes, 32 bit x86 VC 2003. pp_and: Do the PERL_ASYNC_CHECK before anything else, calcing SP before PERL_ASYNC_CHECK would mean saving it across the potential call. SvTRUE macro checks its param for NULL. This SV * came off the Perl stack, it will not be null since pp_and is not a core sub (see S_maybe_add_coresub) and will not be called from pp_coreargs (pp_coreargs places (SV *)NULLs on Perl stack). So create a SvTRUE_NN macro that does not check for NULL, this saves a branch. Since the Perl stack is only touched twice, don't create a local SP. See comment in code. This saves another variable to not be saved across the sv_2bool_flags and removed PUTBACK instructions. PL_op is only read once or twice (compiler choice) right before the 2 returns. There is only 1 variable saved across any calls in pp_and now, and that is my_perl. dSP also was not use to prevent an accidental use of a ++/-- SP macro in pp_and in the future since there is no PUTBACK now. I guess for a SPARC with register windowing and no direct memory instructions, accessing PL_stack_sp twice will take more instructions 2 reads and a write to PL_stack_sp vs 1 read and 1 write to PL_stack_sp with a dSP design. On SPARC, with a register window, cross call regs have no cost per reg cost aslong as you dont exceed their max number. For me, pp_and went from 0x112 to 0xFF after this commit. Prior to dSP removal, it was down to 0x109. SvTRUE_NN was named after SvREFCNT_inc_NN. There remains an inefficiency in pp_and on non-GCC compilers due to SvPVXtrue using PL_Xpv which will be dealt with in another commit.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/pp_hot.c b/pp_hot.c
index d5354345f7..977e22fafc 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -85,9 +85,12 @@ PP(pp_pushmark)
PP(pp_stringify)
{
dVAR; dSP; dTARGET;
- sv_copypv(TARG,TOPs);
- SETTARG;
- RETURN;
+ SV * const sv = TOPs;
+ SETs(TARG);
+ sv_copypv(TARG, sv);
+ SvSETMAGIC(TARG);
+ /* no PUTBACK, SETs doesn't inc/dec SP */
+ return NORMAL;
}
PP(pp_gv)
@@ -99,14 +102,22 @@ PP(pp_gv)
PP(pp_and)
{
- dVAR; dSP;
+ dVAR;
PERL_ASYNC_CHECK();
- if (!SvTRUE(TOPs))
- RETURN;
- else {
- if (PL_op->op_type == OP_AND)
- --SP;
- RETURNOP(cLOGOP->op_other);
+ {
+ /* SP is not used to remove a variable that is saved across the
+ sv_2bool_flags call in SvTRUE_NN, if a RISC/CISC or low/high machine
+ register or load/store vs direct mem ops macro is introduced, this
+ should be a define block between direct PL_stack_sp and dSP operations,
+ presently, using PL_stack_sp is bias towards CISC cpus */
+ SV * const sv = *PL_stack_sp;
+ if (!SvTRUE_NN(sv))
+ return NORMAL;
+ else {
+ if (PL_op->op_type == OP_AND)
+ --PL_stack_sp;
+ return cLOGOP->op_other;
+ }
}
}