In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/ba5248fcde21acfb9d93220ec07256804525c18e?hp=94d4006a6dfdde1becb6ac3d43bd51a5b9ffd95f>
- Log ----------------------------------------------------------------- commit ba5248fcde21acfb9d93220ec07256804525c18e Author: Daniel Dragan <bul...@hotmail.com> Date: Wed Jun 4 23:17:39 2014 -0400 remove 1 read of interp var from PUSHMARK PL_markstack_ptr was read once to do the ++ and comparison. Then after the markstack_grow call, or not, depending on the branch. The code reads PL_markstack_ptr a 2nd time. It has to be reread in case (or always does) markstack_grow reallocs the mark stack. markstack_grow has a void retval. That is a waste of a register. Let us put it to use to return the new PL_markstack_ptr. In markstack_grow the contents that will be assigned to PL_markstack_ptr are already in a register. So let the I32* flow out from markstack_grow to its caller. In VC2003 32 bit asm, mark_stack_entry is register eax. The retval of markstack_grow is in eax. So the assignment "=" in "mark_stack_entry = markstack_grow();" has no overhead. Since the other, not extend branch, is function call free, "(mark_stack_entry = ++PL_markstack_ptr)" assigns to eax. Ultimatly with this patch a 3 byte mov instruction is saved for each instance of PUSHMARK, and 1 interp var read is removed. I observed 42 callers of markstack_grow with my disassembler, so theoretically 3*42 bytes of machine code was removed for me. Perl_pp_pushmark dropped from 0x2b to 0x28 bytes of x86 VC 2003 machine code. [perl #122034] ----------------------------------------------------------------------- Summary of changes: embed.fnc | 2 +- pp.h | 7 ++++--- proto.h | 2 +- scope.c | 5 +++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/embed.fnc b/embed.fnc index 50bb964..22205d8 100644 --- a/embed.fnc +++ b/embed.fnc @@ -851,7 +851,7 @@ p |int |magic_wipepack |NN SV* sv|NN MAGIC* mg pod |SV* |magic_methcall |NN SV *sv|NN const MAGIC *mg \ |NN SV *meth|U32 flags \ |U32 argc|... -Ap |void |markstack_grow +Ap |I32 * |markstack_grow #if defined(USE_LOCALE_COLLATE) p |int |magic_setcollxfrm|NN SV* sv|NN MAGIC* mg : Defined in locale.c, used only in sv.c diff --git a/pp.h b/pp.h index 3623a38..a7e936c 100644 --- a/pp.h +++ b/pp.h @@ -57,9 +57,10 @@ Refetch the stack pointer. Used after a callback. See L<perlcall>. #define PUSHMARK(p) \ STMT_START { \ - if (UNLIKELY(++PL_markstack_ptr == PL_markstack_max)) \ - markstack_grow(); \ - *PL_markstack_ptr = (I32)((p) - PL_stack_base);\ + I32 * mark_stack_entry; \ + if (UNLIKELY((mark_stack_entry = ++PL_markstack_ptr) == PL_markstack_max)) \ + mark_stack_entry = markstack_grow(); \ + *mark_stack_entry = (I32)((p) - PL_stack_base); \ } STMT_END #define TOPMARK (*PL_markstack_ptr) diff --git a/proto.h b/proto.h index 3b882d8..27981e9 100644 --- a/proto.h +++ b/proto.h @@ -2535,7 +2535,7 @@ PERL_CALLCONV Malloc_t Perl_malloc(MEM_SIZE nbytes) __attribute__malloc__ __attribute__warn_unused_result__; -PERL_CALLCONV void Perl_markstack_grow(pTHX); +PERL_CALLCONV I32 * Perl_markstack_grow(pTHX); PERL_CALLCONV SV* Perl_mess(pTHX_ const char* pat, ...) __attribute__format__(__printf__,pTHX_1,pTHX_2) __attribute__nonnull__(pTHX_1); diff --git a/scope.c b/scope.c index 07f24b7..76e023a 100644 --- a/scope.c +++ b/scope.c @@ -110,7 +110,7 @@ Perl_pop_scope(pTHX) LEAVE_SCOPE(oldsave); } -void +I32 * Perl_markstack_grow(pTHX) { dVAR; @@ -118,8 +118,9 @@ Perl_markstack_grow(pTHX) const I32 newmax = GROW(oldmax); Renew(PL_markstack, newmax, I32); - PL_markstack_ptr = PL_markstack + oldmax; PL_markstack_max = PL_markstack + newmax; + PL_markstack_ptr = PL_markstack + oldmax; + return PL_markstack_ptr; } void -- Perl5 Master Repository