This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Minimise the size of padname + string buffer
authorFather Chrysostomos <sprout@cpan.org>
Fri, 28 Nov 2014 22:35:40 +0000 (14:35 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 30 Nov 2014 19:48:42 +0000 (11:48 -0800)
If we define the struct a little differently, we can begin the string
buffer two bytes into a pointer, rather than pointer-aligned.  In case
some platforms can compare pointer-aligned string faster, I added a
#define to allow that.  But on 64-bit darwin the speed is identical
either way:

$ time ./miniperl -e 'eval q|my$a;|x50000 . q|eval q<my $A>|'

I ran this three times in each mode, and the average of the user times
differed by less than 1%.

pad.h

diff --git a/pad.h b/pad.h
index e19c7a8..7ee8a1c 100644 (file)
--- a/pad.h
+++ b/pad.h
@@ -45,26 +45,46 @@ struct padnamelist {
     U32                xpadnl_refcnt;
 };
 
+/* PERL_PADNAME_MINIMAL uses less memory, but on some platforms
+   PERL_PADNAME_ALIGNED may be faster, so platform-specific hints can
+   define one or the other.  */
+#if defined(PERL_PADNAME_MINIMAL) && defined (PERL_PADNAME_ALIGNED)
+#  error PERL_PADNAME_MINIMAL and PERL_PADNAME_ALIGNED are exclusive
+#endif
+
+#if !defined(PERL_PADNAME_MINIMAL) && !defined(PERL_PADNAME_ALIGNED)
+#  define PERL_PADNAME_ALIGNED
+#endif
+
+#define _PADNAME_BASE \
+    char *     xpadn_pv;               \
+    HV *       xpadn_ourstash;         \
+    union {                            \
+       HV *    xpadn_typestash;        \
+       CV *    xpadn_protocv;          \
+    } xpadn_type_u;                    \
+    U32                xpadn_low;              \
+    U32                xpadn_high;             \
+    U32                xpadn_refcnt;           \
+    int                xpadn_gen;              \
+    U8         xpadn_len;              \
+    U8         xpadn_flags
+
 struct padname {
-    char *     xpadn_pv;
-    HV *       xpadn_ourstash;
-    union {
-       HV *    xpadn_typestash;
-       CV *    xpadn_protocv;
-    } xpadn_type_u;
-    U32                xpadn_low;
-    U32                xpadn_high;
-    U32                xpadn_refcnt;
-    int                xpadn_gen;
-    U8         xpadn_len;
-    U8         xpadn_flags;
+    _PADNAME_BASE;
 };
 
 struct padname_with_str {
+#ifdef PERL_PADNAME_MINIMAL
+    _PADNAME_BASE;
+#else
     struct padname     xpadn_padname;
+#endif
     char               xpadn_str[1];
 };
 
+#undef _PADNAME_BASE
+
 #define PADNAME_FROM_PV(s) \
     ((PADNAME *)((s) - STRUCT_OFFSET(struct padname_with_str, xpadn_str)))