diff options
author | Daniel Dragan <bulk88@hotmail.com> | 2012-11-20 17:36:54 -0500 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-11-21 06:04:11 -0800 |
commit | 4cc783efe0ed9495ebcbefd8494083a4b6160e6f (patch) | |
tree | 2219434786bdd0f06e01dd2d1c523da125866c17 /pp_hot.c | |
parent | 2a5bd8731bfdd9308c12fac06faa637e38b5eeb5 (diff) | |
download | perl-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.c | 31 |
1 files changed, 21 insertions, 10 deletions
@@ -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; + } } } |