summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2020-06-27 18:10:47 +0100
committerTony Cook <tony@develop-help.com>2020-12-09 12:00:56 +1100
commit8462890b4373d480bea3ff2c274614e9a78cbdc4 (patch)
treecdc6b9140665fcb04be0c3c45a31a929f0d125b0
parentc07463d862e4832cc6a94200a77a3170ef2dca18 (diff)
downloadperl-8462890b4373d480bea3ff2c274614e9a78cbdc4.tar.gz
Implement SAVEt_STRLEN_SMALL
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.
-rw-r--r--scope.c20
-rw-r--r--scope.h65
-rw-r--r--sv.c1
3 files changed, 51 insertions, 35 deletions
diff --git a/scope.c b/scope.c
index cea1500e6a..19281d12a7 100644
--- 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 5b611c2cad..a7dee134f8 100644
--- a/scope.h
+++ b/scope.h
@@ -38,44 +38,45 @@
#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 486f07dcd5..4d89ce0aa9 100644
--- 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 */