summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2014-06-04 23:17:39 -0400
committerTony Cook <tony@develop-help.com>2014-06-09 10:11:19 +1000
commitba5248fcde21acfb9d93220ec07256804525c18e (patch)
tree8513fc452f279ecad1f828028aca927dd99be72e
parent94d4006a6dfdde1becb6ac3d43bd51a5b9ffd95f (diff)
downloadperl-ba5248fcde21acfb9d93220ec07256804525c18e.tar.gz
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]
-rw-r--r--embed.fnc2
-rw-r--r--pp.h7
-rw-r--r--proto.h2
-rw-r--r--scope.c5
4 files changed, 9 insertions, 7 deletions
diff --git a/embed.fnc b/embed.fnc
index 50bb964b2b..22205d8520 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 3623a38f0f..a7e936ccaf 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 3b882d813f..27981e94f1 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 07f24b7998..76e023ae59 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