summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-02-20 19:20:09 +0000
committerNicholas Clark <nick@ccl4.org>2010-05-05 05:01:10 +0100
commit89abef211f482f5f37aeb9b02c71c4452feb5c34 (patch)
tree29cb0d350843d47f0916a3206af812b0c536a817 /scope.c
parentc0b977fd793319b0b362593c57555d28997fae84 (diff)
downloadperl-89abef211f482f5f37aeb9b02c71c4452feb5c34.tar.gz
When saving I32s, if the value is small enough save it with the type.
This uses a new type, SAVEt_I32_SMALL.
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/scope.c b/scope.c
index 57c00b697f..15081c7cd2 100644
--- a/scope.c
+++ b/scope.c
@@ -426,10 +426,16 @@ void
Perl_save_I32(pTHX_ I32 *intp)
{
dVAR;
+ const UV shifted = (UV)*intp << SAVE_TIGHT_SHIFT;
PERL_ARGS_ASSERT_SAVE_I32;
- save_pushi32ptr(*intp, intp, SAVEt_I32);
+ if ((I32)(shifted >> SAVE_TIGHT_SHIFT) == *intp) {
+ SSCHECK(2);
+ SSPUSHPTR(intp);
+ SSPUSHUV(SAVEt_I32_SMALL | shifted);
+ } else
+ save_pushi32ptr(*intp, intp, SAVEt_I32);
}
/* Cannot use save_sptr() to store a char* since the SV** cast will
@@ -804,6 +810,10 @@ Perl_leave_scope(pTHX_ I32 base)
ptr = SSPOPPTR;
*(bool*)ptr = cBOOL(uv >> 8);
break;
+ case SAVEt_I32_SMALL:
+ ptr = SSPOPPTR;
+ *(I32*)ptr = (I32)(uv >> SAVE_TIGHT_SHIFT);
+ break;
case SAVEt_I32: /* I32 reference */
ptr = SSPOPPTR;
#ifdef PERL_DEBUG_READONLY_OPS