summaryrefslogtreecommitdiff
path: root/toke.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-08-31 20:13:21 -0700
committerFather Chrysostomos <sprout@cpan.org>2014-09-15 06:19:32 -0700
commit2eaf799e74b14dc77b90d5484a3fd4ceac12b46a (patch)
treed472277495cf7140a2aec82d0593edfa9ed3b0fb /toke.c
parentc831c5ee90b91c179042ccda588910ba60808970 (diff)
downloadperl-2eaf799e74b14dc77b90d5484a3fd4ceac12b46a.tar.gz
Avoid creating GVs when subs are declared
This patch changes ‘sub foo {...}’ declarations to store subroutine references in the stash, to save memory. Typeglobs still notionally exist. Accessing CvGV(cv) will reify them. Hence, currently the savings are lost when a sub call is compiled. $ ./miniperl -e 'sub foo{} BEGIN { warn $::{foo} } foo(); BEGIN { warn $::{foo} }' CODE(0x7f8ef082ad98) at -e line 1. *main::foo at -e line 1. This optimisation is skipped if the subroutine declaration contains a package separator. Concerning the changes in caller.t, this code: sub foo { print +(caller(0))[3],"\n" } my $fooref = delete $::{foo}; $fooref -> (); used to crash in 5.7.3 or thereabouts. It was fixed by 16658 (aka 07b8c804e8) to produce ‘(unknown)’ instead. Then in 5.13.3 it was changed (by 803f274) to produce ‘main::__ANON__’ instead. So the tests are really checking that we don’t get a crash. I think it is acceptable that it has now changed to ‘main::foo’.
Diffstat (limited to 'toke.c')
-rw-r--r--toke.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/toke.c b/toke.c
index ea022f9512..8a8d187e80 100644
--- a/toke.c
+++ b/toke.c
@@ -6552,7 +6552,11 @@ Perl_yylex(pTHX)
rv2cv_op =
newCVREF(OPpMAY_RETURN_CONSTANT<<8, const_op);
cv = lex
- ? isGV(gv) ? GvCV(gv) : (CV *)gv
+ ? isGV(gv)
+ ? GvCV(gv)
+ : SvROK(gv) && SvTYPE(SvRV(gv)) == SVt_PVCV
+ ? (CV *)SvRV(gv)
+ : (CV *)gv
: rv2cv_op_cv(rv2cv_op, RV2CVOPCV_RETURN_STUB);
}