New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PATCH] Perl_eval_sv/Perl_call_sv stack manipulation patches #14942
Labels
Comments
From @bulk88Created by @bulk88See attached patches. I tried a Win32 debugging heap (gflags) and Perl Info
|
From @bulk880001-remove-repeated-PL_stack_sp-derefs-in-Perl_eval_sv-P.patchFrom f7d8844b17b3028b3c2083c6fff2f5e3cdc5f4cb Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 25 Sep 2015 16:38:11 -0400
Subject: [PATCH 1/2] remove repeated PL_stack_sp derefs in
Perl_eval_sv/Perl_call_sv
Reduce scope of local SP and remove excessive reads and writes to
PL_stack_sp in Perl_eval_sv/Perl_call_sv. EXTEND macro refetches the
possibly realloced SP on its own, Perl_stack_grow returns the new SP as a
retval and therefore in a register. By using PL_stack_sp instead of
Perl_stack_grow, an extra redundant mem read is done. Also dont keep
SP around for long periods unused, it wastes a C stack slot or non-vol
reg and makes the callframe bigger. The EXTEND could be placed
in the !(flags & G_METHOD_NAMED) branch, but that will be done in another
patch for bisectability.
VC 2003 -O1 machine code sizes of the functions
Perl_eval_sv before 0x28a after 0x286
Perl_call_sv before 0x3cd after 0x3cb
The savings look small since in x86 "*var+=4" and "var+=4" are the same
number of bytes to encode the instruction, only the mod R/M bitfield vals
are different. RISC CPUs benefit more from this patch.
commit c106c2be8b "G_METHOD_NAMED flag for call_method and call_sv"
added skipping the push SV onto stack
The EXTEND and PL_stack_sp direct manipulation code is from
commit a0d0e21ea6 "perl 5.000". The reason is unknown why it did
"SV** sp = stack_sp;" and later "EXTEND(stack_sp, 1);" instead of using
SP, since EXTEND at that time, and to this day requires C auto sp be in
scope.
---
perl.c | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/perl.c b/perl.c
index 1bd2cbb..52a5ace 100644
--- a/perl.c
+++ b/perl.c
@@ -2696,7 +2696,7 @@ I32
Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
/* See G_* flags in cop.h */
{
- dVAR; dSP;
+ dVAR;
LOGOP myop; /* fake syntax tree node */
METHOP method_op;
I32 oldmark;
@@ -2726,9 +2726,14 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
SAVEOP();
PL_op = (OP*)&myop;
- EXTEND(PL_stack_sp, 1);
- if (!(flags & G_METHOD_NAMED))
- *++PL_stack_sp = sv;
+ {
+ dSP;
+ EXTEND(SP, 1);
+ if (!(flags & G_METHOD_NAMED)) {
+ PUSHs(sv);
+ PUTBACK;
+ }
+ }
oldmark = TOPMARK;
oldscope = PL_scopestack_ix;
@@ -2839,9 +2844,8 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
/* See G_* flags in cop.h */
{
dVAR;
- dSP;
UNOP myop; /* fake syntax tree node */
- VOL I32 oldmark = SP - PL_stack_base;
+ VOL I32 oldmark;
VOL I32 retval = 0;
int ret;
OP* const oldop = PL_op;
@@ -2857,8 +2861,13 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
SAVEOP();
PL_op = (OP*)&myop;
Zero(&myop, 1, UNOP);
- EXTEND(PL_stack_sp, 1);
- *++PL_stack_sp = sv;
+ {
+ dSP;
+ oldmark = SP - PL_stack_base;
+ EXTEND(SP, 1);
+ PUSHs(sv);
+ PUTBACK;
+ }
if (!(flags & G_NOARGS))
myop.op_flags = OPf_STACKED;
--
1.7.9.msysgit.0
|
From @bulk880002-Perl_call_sv-move-EXTEND-into-branch-that-needs-it.patchFrom fc41c78e1d6528daf39d9cfeae1b053f2705a10a Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 25 Sep 2015 16:52:56 -0400
Subject: [PATCH 2/2] Perl_call_sv move EXTEND into branch that needs it
If we aren't manipulating the stack, dont fetch it, check and possibly
extend it. There is a slight chance this EXTEND was covering up missing
EXTENDs somewhere else in Perl core or CPAN C code, if future bisects or
valgrind reports show that this EXTEND by 1 must always be done, this
patch can be reverted. pp_method_named contains a EXTEND/XPUSH* call,
pp_entersub requires 1 arg on stack so, both sides of the
"if (!(flags & G_METHOD_NAMED))" test will in theory make sure there is
1 free slot on the stack on entry to a SUB or XSUB.
See also
http://www.nntp.perl.org/group/perl.perl5.porters/2015/09/msg231329.html
---
perl.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/perl.c b/perl.c
index 52a5ace..8552bab 100644
--- a/perl.c
+++ b/perl.c
@@ -2726,13 +2726,11 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
SAVEOP();
PL_op = (OP*)&myop;
- {
+ if (!(flags & G_METHOD_NAMED)) {
dSP;
EXTEND(SP, 1);
- if (!(flags & G_METHOD_NAMED)) {
- PUSHs(sv);
- PUTBACK;
- }
+ PUSHs(sv);
+ PUTBACK;
}
oldmark = TOPMARK;
oldscope = PL_scopestack_ix;
--
1.7.9.msysgit.0
|
The RT System itself - Status changed from 'new' to 'open' |
@tonycoz - Status changed from 'open' to 'resolved' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Migrated from rt.perl.org#126196 (status was 'resolved')
Searchable as RT126196$
The text was updated successfully, but these errors were encountered: