summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2011-07-18 20:14:10 +0100
committerDavid Mitchell <davem@iabyn.com>2011-07-18 20:24:42 +0100
commitf11ca51e41e898a77f1fd33b9e0371e69b1be73a (patch)
tree71338052cd58ae1032cd6973d07e97d4a61a025a
parenteba804b9d4475c6d8d4728933792c5b7ca90fbf5 (diff)
downloadperl-f11ca51e41e898a77f1fd33b9e0371e69b1be73a.tar.gz
Perl_rpeep: undo tail recursion optimisation
commit 3c78429c102e0fe2ad30c60dfe52636b6071ef19 reduced the depth of recursion in rpeep(), by deferring recursion into branches until a bit later (so that the recursive call to rpeep was then likely to be shallow). However, it went one step further: when the chain of op_next's had been exhausted in the main loop, it processed any remaining deferrred branches in the main loop rather than recursing. All nice and efficient, but it broke the expectation that someone who had hooked into rpeep could follow the chain of op_nexts in each call and visit *all* ops. This commit removes that optimisation and restores the rpeep hook expectancy. This shouldn't have any major effect on the depth of recursion, and its minor inefficiency doesn't really matter for a one-time compilation-time pass.
-rw-r--r--ext/XS-APItest/t/peep.t6
-rw-r--r--op.c3
2 files changed, 5 insertions, 4 deletions
diff --git a/ext/XS-APItest/t/peep.t b/ext/XS-APItest/t/peep.t
index 87d749b7ff..bfcc9ebd3b 100644
--- a/ext/XS-APItest/t/peep.t
+++ b/ext/XS-APItest/t/peep.t
@@ -23,7 +23,8 @@ is($rrecord->[0], 'affe');
# A deep-enough nesting of conditionals defeats the deferring mechanism
# and triggers recursion. Note that this test is sensitive to the details
# rpeep: the main thing it is testing is that rpeep is called more than
-# peep; the details are less important.
+# peep, and that all branches are covered; the order of branch calling is
+# less important.
my $code = q[my ($a,$b); $a =];
$code .= qq{ \$b ? "foo$_" :} for (1..10);
@@ -33,4 +34,5 @@ eval $code;
XS::APItest::peep_disable;
is_deeply($record, [ "foo11" ]);
-is_deeply($rrecord, [ qw(foo1 foo2 foo3 foo4 foo5 foo6 foo11) ]);
+is_deeply($rrecord, [
+ qw(foo1 foo2 foo3 foo4 foo5 foo6 foo10 foo9 foo8 foo7 foo11) ]);
diff --git a/op.c b/op.c
index e7cff45467..6a94db44f8 100644
--- a/op.c
+++ b/op.c
@@ -9338,8 +9338,7 @@ Perl_rpeep(pTHX_ register OP *o)
while (!o) {
if (defer_ix < 0)
break;
- o = defer_queue[(defer_base + defer_ix--) % MAX_DEFERRED];
- oldop = NULL;
+ CALL_RPEEP(defer_queue[(defer_base + defer_ix--) % MAX_DEFERRED]);
}
if (!o)
break;