Skip to content
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

Closed
p5pRT opened this issue Sep 26, 2015 · 6 comments
Closed

[PATCH] Perl_eval_sv/Perl_call_sv stack manipulation patches #14942

p5pRT opened this issue Sep 26, 2015 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 26, 2015

Migrated from rt.perl.org#126196 (status was 'resolved')

Searchable as RT126196$

@p5pRT
Copy link
Author

p5pRT commented Sep 26, 2015

From @bulk88

Created by @bulk88

See attached patches. I tried a Win32 debugging heap (gflags) and
-DSTRESS_REALLOC on non-DEBUGGING perl smoke and it passed.

Perl Info

Flags:
            category=core
            severity=low

Site configuration information for perl 5.23.0:

Configured by Owner at Mon Jun 29 03:16:56 2015.

Summary of my perl5 (revision 5 version 23 subversion 0) configuration:
          Derived from: 63602a3fc27a417daf3c532b6a11ae6eba2a072a
          Platform:
            osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
            uname=''
            config_args='undef'
            hint=recommended, useposix=true, d_sigaction=undef
            useithreads=define, usemultiplicity=define
            use64bitint=undef, use64bitall=undef, uselongdouble=undef
            usemymalloc=n, bincompat5005=undef
          Compiler:
            cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG -GL
-DWIN32
-D_CONSOLE -DNO_STRICT  -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -D_USE_32BIT_TIME_T',
            optimize='-O1 -MD -Zi -DNDEBUG -GL',
            cppflags='-DWIN32'
            ccversion='13.10.6030', gccversion='', gccosandvers=''
            intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234,
doublekind=3
            d_longlong=undef, longlongsize=8, d_longdbl=define,
longdblsize=8,
longdblkind=0
            ivtype='long', ivsize=4, nvtype='double', nvsize=8,
Off_t='__int64', lseeksize=8
            alignbytes=8, prototype=define
          Linker and Libraries:
            ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf
-ltcg 		-libpath:"c:\perl\lib\CORE" 		-machine:x86'
            libpth=\lib
            libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
            perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
            libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl523.lib
            gnulibc_version=''
          Dynamic Linking:
            dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
            cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug
-opt:ref,icf -ltcg 		-libpath:"c:\perl\lib\CORE" 		-machine:x86'

Locally applied patches:
            uncommitted-changes


@INC for perl 5.23.0:
            C:/perl521/srcnewb4opt/lib
            .


Environment for perl 5.23.0:
            HOME (unset)
            LANG (unset)
            LANGUAGE (unset)
            LD_LIBRARY_PATH (unset)
            LOGDIR (unset)
            PATH=C:\sperl\c\bin;C:\WINDOWS\system32;C:\Program
Files\Microsoft
Visual Studio .NET 2003\Vc7\bin;C:\Program Files\Microsoft Visual Studio
.NET 2003\Common7\IDE;C:\WINDOWS;C:\Program Files\Git\cmd;C:\Program
Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;C:\perl\bin
            PERL_BADLANG (unset)
            PERL_JSON_BACKEND=Cpanel::JSON::XS
            PERL_YAML_BACKEND=YAML
            SHELL (unset)











@p5pRT
Copy link
Author

p5pRT commented Sep 26, 2015

From @bulk88

0001-remove-repeated-PL_stack_sp-derefs-in-Perl_eval_sv-P.patch
From 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

@p5pRT
Copy link
Author

p5pRT commented Sep 26, 2015

From @bulk88

0002-Perl_call_sv-move-EXTEND-into-branch-that-needs-it.patch
From 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

@p5pRT
Copy link
Author

p5pRT commented Oct 12, 2015

From @tonycoz

On Sat Sep 26 02​:00​:35 2015, bulk88 wrote​:

See attached patches. I tried a Win32 debugging heap (gflags) and
-DSTRESS_REALLOC on non-DEBUGGING perl smoke and it passed.

Thanks, applied as 5b434c7 and 8c9009a.

Tony

@p5pRT
Copy link
Author

p5pRT commented Oct 12, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT p5pRT closed this as completed Oct 12, 2015
@p5pRT
Copy link
Author

p5pRT commented Oct 12, 2015

@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
Projects
None yet
Development

No branches or pull requests

1 participant