]> git.vpit.fr Git - perl/modules/autovivification.git/commitdiff
In the rpeep replacement, don't check every op for recursion
authorVincent Pit <vince@profvince.com>
Sat, 12 Jul 2014 16:53:52 +0000 (18:53 +0200)
committerVincent Pit <vince@profvince.com>
Sat, 4 Oct 2014 15:18:53 +0000 (17:18 +0200)
When the rpeep is available (i.e. starting from perl 5.13.4), recursion in
the peephole optimizer replacement seemingly only happens for static
infinite loops (think for (;;) { }), even though the 'seen' pointer table
is checked for every op. This may cause slowdowns even outside of the scope
of the pragma. To mitigate this problem, only check for recursion on
nextstate, dbstate, and stub ops, since one of those three kind of ops must
occur in any loop/block (respectively for non-empty, non-empty debugging
and empty loops).

autovivification.xs

index a6bf2af1c79124370f9a643ee8800b810ea5a81e..7fc4a4e8241656de3dcfd310e2cdb4df03fa5132 100644 (file)
@@ -980,11 +980,22 @@ STATIC void a_peep_rec(pTHX_ OP *o, ptable *seen) {
   const a_op_info *oi = NULL;
   UV flags = 0;
 
+#if !A_HAS_RPEEP
   if (ptable_fetch(seen, o))
    break;
   ptable_seen_store(seen, o, o);
+#endif
 
   switch (o->op_type) {
+#if A_HAS_RPEEP
+   case OP_NEXTSTATE:
+   case OP_DBSTATE:
+   case OP_STUB:
+    if (ptable_fetch(seen, o))
+     return;
+    ptable_seen_store(seen, o, o);
+    break;
+#endif
    case OP_PADSV:
     if (o->op_ppaddr != a_pp_deref) {
      oi = a_map_fetch(o);