cut out/inline wrapper calls of sv_*catpvf*
authorDaniel Dragan <bulk88@hotmail.com>
Thu, 26 Dec 2013 19:18:16 +0000 (14:18 -0500)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 29 Dec 2013 14:03:29 +0000 (06:03 -0800)
these wrappers use 1 or 2 indirect calls to reach the guts of Perl's
format string engine. Win64 and ARM (and I assume other 4 register regcall
platforms) compilers can't easily tailcall or optimize these due to
sv_vcatpvfn_flags > 4 args and strlen calls. They allocate lots of C
stack and set up new frames and copy args over. So just call the core
format string function directly.

Not all paths to sv_vcatpvfn_flags were optimized since they have no CORE
or CPAN grep usage. sv_vcatpvf has usage, sv_catpvf_mg* have none but were
done anyway because they sound like they would be commonly used.

sv.c

diff --git a/sv.c b/sv.c
index c2ee630..93d6a1a 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -10171,7 +10171,7 @@ Perl_sv_catpvf_nocontext(SV *const sv, const char *const pat, ...)
     PERL_ARGS_ASSERT_SV_CATPVF_NOCONTEXT;
 
     va_start(args, pat);
-    sv_vcatpvf(sv, pat, &args);
+    sv_vcatpvfn_flags(sv, pat, strlen(pat), &args, NULL, 0, NULL, SV_GMAGIC|SV_SMAGIC);
     va_end(args);
 }
 
@@ -10189,7 +10189,8 @@ Perl_sv_catpvf_mg_nocontext(SV *const sv, const char *const pat, ...)
     PERL_ARGS_ASSERT_SV_CATPVF_MG_NOCONTEXT;
 
     va_start(args, pat);
-    sv_vcatpvf_mg(sv, pat, &args);
+    sv_vcatpvfn_flags(sv, pat, strlen(pat), &args, NULL, 0, NULL, SV_GMAGIC|SV_SMAGIC);
+    SvSETMAGIC(sv);
     va_end(args);
 }
 #endif
@@ -10215,7 +10216,7 @@ Perl_sv_catpvf(pTHX_ SV *const sv, const char *const pat, ...)
     PERL_ARGS_ASSERT_SV_CATPVF;
 
     va_start(args, pat);
-    sv_vcatpvf(sv, pat, &args);
+    sv_vcatpvfn_flags(sv, pat, strlen(pat), &args, NULL, 0, NULL, SV_GMAGIC|SV_SMAGIC);
     va_end(args);
 }
 
@@ -10235,7 +10236,7 @@ Perl_sv_vcatpvf(pTHX_ SV *const sv, const char *const pat, va_list *const args)
 {
     PERL_ARGS_ASSERT_SV_VCATPVF;
 
-    sv_vcatpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL);
+    sv_vcatpvfn_flags(sv, pat, strlen(pat), args, NULL, 0, NULL, SV_GMAGIC|SV_SMAGIC);
 }
 
 /*
@@ -10254,7 +10255,8 @@ Perl_sv_catpvf_mg(pTHX_ SV *const sv, const char *const pat, ...)
     PERL_ARGS_ASSERT_SV_CATPVF_MG;
 
     va_start(args, pat);
-    sv_vcatpvf_mg(sv, pat, &args);
+    sv_vcatpvfn_flags(sv, pat, strlen(pat), &args, NULL, 0, NULL, SV_GMAGIC|SV_SMAGIC);
+    SvSETMAGIC(sv);
     va_end(args);
 }