This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Don’t call an early-returning destructor
authorFather Chrysostomos <sprout@cpan.org>
Mon, 21 Nov 2011 16:40:34 +0000 (08:40 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 21 Nov 2011 16:40:34 +0000 (08:40 -0800)
This speeds things up 2.8 times in my naïve benchmarks.

This applies to code like:

    use constant DEBUG => 1;
    DESTROY { return unless DEBUG; ... }

which gets optimised down to:

    DESTROY { return; ... }

Adding such a destructor will now have almost no impact on speed in
production.

sv.c

diff --git a/sv.c b/sv.c
index ba656a9..0095e07 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6303,11 +6303,19 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) {
                /* A constant subroutine can have no side effects, so
                   don't bother calling it.  */
                && !CvCONST(destructor)
-               /* Don't bother calling an empty destructor */
+               /* Don't bother calling an empty destructor or one that
+                  returns immediately. */
                && (CvISXSUB(destructor)
                || (CvSTART(destructor)
                    && (CvSTART(destructor)->op_next->op_type
-                                       != OP_LEAVESUB))))
+                                       != OP_LEAVESUB)
+                   && (CvSTART(destructor)->op_next->op_type
+                                       != OP_PUSHMARK
+                       || CvSTART(destructor)->op_next->op_next->op_type
+                                       != OP_RETURN
+                      )
+                  ))
+              )
            {
                SV* const tmpref = newRV(sv);
                SvREADONLY_on(tmpref); /* DESTROY() could be naughty */