This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Implement SAVEt_STRLEN_SMALL
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>
Sat, 27 Jun 2020 17:10:47 +0000 (18:10 +0100)
committerTony Cook <tony@develop-help.com>
Wed, 9 Dec 2020 01:00:56 +0000 (12:00 +1100)
Most uses of SAVEt_STRLEN actually store small values; often zero.
Rather than using an entire U64-sized element for these values, it saves
space to use the same "SMALL" mechanism as other numerical values, like
SAVEt_INT_SMALL.

scope.c
scope.h
sv.c

diff --git a/scope.c b/scope.c
index cea1500..19281d1 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -512,14 +512,22 @@ Perl_save_I32(pTHX_ I32 *intp)
 void
 Perl_save_strlen(pTHX_ STRLEN *ptr)
 {
+    const IV i = *ptr;
+    UV type = ((I32)((U32)i << SAVE_TIGHT_SHIFT) | SAVEt_STRLEN_SMALL);
+    int size = 2;
     dSS_ADD;
 
     PERL_ARGS_ASSERT_SAVE_STRLEN;
 
-    SS_ADD_IV(*ptr);
+    if (UNLIKELY((I32)(type >> SAVE_TIGHT_SHIFT) != i)) {
+        SS_ADD_IV(*ptr);
+        type = SAVEt_STRLEN;
+        size++;
+    }
+
     SS_ADD_PTR(ptr);
-    SS_ADD_UV(SAVEt_STRLEN);
-    SS_ADD_END(3);
+    SS_ADD_UV(type);
+    SS_ADD_END(size);
 }
 
 void
@@ -840,6 +848,7 @@ static const U8 arg_counts[] = {
     1, /* SAVEt_STACK_POS          */
     1, /* SAVEt_READONLY_OFF       */
     1, /* SAVEt_FREEPADNAME        */
+    1, /* SAVEt_STRLEN_SMALL       */
     2, /* SAVEt_AV                 */
     2, /* SAVEt_DESTRUCTOR         */
     2, /* SAVEt_DESTRUCTOR_X       */
@@ -1045,6 +1054,11 @@ Perl_leave_scope(pTHX_ I32 base)
            *(int*)a1.any_ptr = (int)a0.any_i32;
            break;
 
+        case SAVEt_STRLEN_SMALL:
+           a0 = ap[0];
+           *(STRLEN*)a0.any_ptr = (STRLEN)(uv >> SAVE_TIGHT_SHIFT);
+            break;
+
        case SAVEt_STRLEN:                      /* STRLEN/size_t ref */
             a0 = ap[0]; a1 = ap[1];
            *(STRLEN*)a1.any_ptr = (STRLEN)a0.any_iv;
diff --git a/scope.h b/scope.h
index 5b611c2..a7dee13 100644 (file)
--- a/scope.h
+++ b/scope.h
 #define SAVEt_STACK_POS                20
 #define SAVEt_READONLY_OFF     21
 #define SAVEt_FREEPADNAME      22
+#define SAVEt_STRLEN_SMALL      23
 
 /* two args */
 
-#define SAVEt_AV               23
-#define SAVEt_DESTRUCTOR       24
-#define SAVEt_DESTRUCTOR_X     25
-#define SAVEt_GENERIC_PVREF    26
-#define SAVEt_GENERIC_SVREF    27
-#define SAVEt_GP               28
-#define SAVEt_GVSV             29
-#define SAVEt_HINTS            30
-#define SAVEt_HPTR             31
-#define SAVEt_HV               32
-#define SAVEt_I32              33
-#define SAVEt_INT              34
-#define SAVEt_ITEM             35
-#define SAVEt_IV               36
-#define SAVEt_LONG             37
-#define SAVEt_PPTR             38
-#define SAVEt_SAVESWITCHSTACK  39
-#define SAVEt_SHARED_PVREF     40
-#define SAVEt_SPTR             41
-#define SAVEt_STRLEN           42
-#define SAVEt_SV               43
-#define SAVEt_SVREF            44
-#define SAVEt_VPTR             45
-#define SAVEt_ADELETE          46
-#define SAVEt_APTR             47
+#define SAVEt_AV               24
+#define SAVEt_DESTRUCTOR       25
+#define SAVEt_DESTRUCTOR_X     26
+#define SAVEt_GENERIC_PVREF    27
+#define SAVEt_GENERIC_SVREF    28
+#define SAVEt_GP               29
+#define SAVEt_GVSV             30
+#define SAVEt_HINTS            31
+#define SAVEt_HPTR             32
+#define SAVEt_HV               33
+#define SAVEt_I32              34
+#define SAVEt_INT              35
+#define SAVEt_ITEM             36
+#define SAVEt_IV               37
+#define SAVEt_LONG             38
+#define SAVEt_PPTR             39
+#define SAVEt_SAVESWITCHSTACK  40
+#define SAVEt_SHARED_PVREF     41
+#define SAVEt_SPTR             42
+#define SAVEt_STRLEN           43
+#define SAVEt_SV               44
+#define SAVEt_SVREF            45
+#define SAVEt_VPTR             46
+#define SAVEt_ADELETE          47
+#define SAVEt_APTR             48
 
 /* three args */
 
-#define SAVEt_HELEM            48
-#define SAVEt_PADSV_AND_MORTALIZE 49
-#define SAVEt_SET_SVFLAGS      50
-#define SAVEt_GVSLOT           51
-#define SAVEt_AELEM            52
-#define SAVEt_DELETE           53
-#define SAVEt_HINTS_HH         54
+#define SAVEt_HELEM            49
+#define SAVEt_PADSV_AND_MORTALIZE 50
+#define SAVEt_SET_SVFLAGS      51
+#define SAVEt_GVSLOT           52
+#define SAVEt_AELEM            53
+#define SAVEt_DELETE           54
+#define SAVEt_HINTS_HH         55
 
 
 #define SAVEf_SETMAGIC         1
diff --git a/sv.c b/sv.c
index 486f07d..4d89ce0 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -14850,6 +14850,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            /* FALLTHROUGH */
+       case SAVEt_STRLEN_SMALL:
        case SAVEt_INT_SMALL:
        case SAVEt_I32_SMALL:
        case SAVEt_I16:                         /* I16 reference */