about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2020-09-11 07:32:31 +0000
committerEric Wong <e@80x24.org>2020-09-12 20:29:11 +0000
commitd11feea98718f2abb109af4216a36bdbd21b7191 (patch)
tree1f6f83caf21d52f61524e935fa53dcbb6f789877
parent0a1e15ad863782650a36025b9d52a6e9de5eadf3 (diff)
downloadpublic-inbox-d11feea98718f2abb109af4216a36bdbd21b7191.tar.gz
treewide: avoid `goto &NAME' for tail recursion
While Perl implements tail recursion via `goto' which allows
avoiding warnings on deep recursion.  It doesn't (as of 5.28)
optimize the speed of such dispatches, though it may reduce
ephemeral memory usage.

Make the code less alien to hackers coming from other languages
by using normal subroutine dispatch.  It's actually slightly
faster in micro benchmarks due to the complexity of `goto &NAME'.
-rw-r--r--lib/PublicInbox/DS.pm4
-rw-r--r--lib/PublicInbox/Eml.pm2
-rw-r--r--lib/PublicInbox/ExtMsg.pm6
-rw-r--r--lib/PublicInbox/SolverGit.pm32
-rw-r--r--lib/PublicInbox/V2Writable.pm4
-rw-r--r--lib/PublicInbox/View.pm2
-rw-r--r--lib/PublicInbox/Watch.pm4
7 files changed, 27 insertions, 27 deletions
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index 661be1fd..9c278307 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -244,7 +244,7 @@ sub reap_pids {
 }
 
 # reentrant SIGCHLD handler (since reap_pids is not reentrant)
-sub enqueue_reap { $reap_armed //= requeue(\&reap_pids) }
+sub enqueue_reap () { $reap_armed //= requeue(\&reap_pids) }
 
 sub in_loop () { $in_loop }
 
@@ -629,7 +629,7 @@ sub dwaitpid ($$$) {
         push @$wait_pids, [ @_ ]; # [ $pid, $cb, $arg ]
 
         # We could've just missed our SIGCHLD, cover it, here:
-        goto &enqueue_reap; # tail recursion
+        enqueue_reap();
 }
 
 sub _run_later () {
diff --git a/lib/PublicInbox/Eml.pm b/lib/PublicInbox/Eml.pm
index 1fecd41b..571edc5c 100644
--- a/lib/PublicInbox/Eml.pm
+++ b/lib/PublicInbox/Eml.pm
@@ -129,7 +129,7 @@ sub new {
 sub new_sub {
         my (undef, $ref) = @_;
         # special case for messages like <85k5su9k59.fsf_-_@lola.goethe.zz>
-        $$ref =~ /\A(\r?\n)/s or goto &new;
+        $$ref =~ /\A(\r?\n)/s or return new(undef, $ref);
         my $hdr = substr($$ref, 0, $+[0], ''); # sv_chop on $$ref
         bless { hdr => \$hdr, crlf => $1, bdy => $ref }, __PACKAGE__;
 }
diff --git a/lib/PublicInbox/ExtMsg.pm b/lib/PublicInbox/ExtMsg.pm
index ce1a47bb..03faf3a1 100644
--- a/lib/PublicInbox/ExtMsg.pm
+++ b/lib/PublicInbox/ExtMsg.pm
@@ -125,12 +125,12 @@ sub ext_msg {
 sub event_step {
         my ($ctx, $sync) = @_;
         # can't find a partial match in current inbox, try the others:
-        my $ibx = shift @{$ctx->{again}} or goto \&finalize_partial;
+        my $ibx = shift @{$ctx->{again}} or return finalize_partial($ctx);
         my $mids = search_partial($ibx, $ctx->{mid}) or
                         return ($sync ? undef : PublicInbox::DS::requeue($ctx));
         $ctx->{n_partial} += scalar(@$mids);
         push @{$ctx->{partial}}, [ $ibx, $mids ];
-        $ctx->{n_partial} >= PARTIAL_MAX ? goto(\&finalize_partial)
+        $ctx->{n_partial} >= PARTIAL_MAX ? finalize_partial($ctx)
                         : ($sync ? undef : PublicInbox::DS::requeue($ctx));
 }
 
@@ -156,7 +156,7 @@ sub finalize_exact {
                 # synchronous fall-through
                 $ctx->event_step while @{$ctx->{again}};
         }
-        goto \&finalize_partial;
+        finalize_partial($ctx);
 }
 
 sub finalize_partial {
diff --git a/lib/PublicInbox/SolverGit.pm b/lib/PublicInbox/SolverGit.pm
index ae3997ca..83f7a4ee 100644
--- a/lib/PublicInbox/SolverGit.pm
+++ b/lib/PublicInbox/SolverGit.pm
@@ -517,16 +517,16 @@ sub di_url ($$) {
 }
 
 sub retry_current {
-        # my ($self, $want) = @_;
-        push @{$_[0]->{todo}}, $_[1];
-        goto \&next_step # retry solve_existing
+        my ($self, $want) = @_;
+        push @{$self->{todo}}, $want;
+        next_step($self); # retry solve_existing
 }
 
-sub try_harder {
+sub try_harder ($$) {
         my ($self, $want) = @_;
 
         # do we have more inboxes to try?
-        goto \&retry_current if scalar @{$want->{try_ibxs}};
+        return retry_current($self, $want) if scalar @{$want->{try_ibxs}};
 
         my $cur_want = $want->{oid_b};
         if (length($cur_want) > $OID_MIN) { # maybe a shorter OID will work
@@ -534,7 +534,7 @@ sub try_harder {
                 chop($cur_want);
                 dbg($self, "retrying $want->{oid_b} as $cur_want");
                 $want->{oid_b} = $cur_want;
-                goto \&retry_current; # retry with shorter abbrev
+                return retry_current($self, $want); # retry with shorter abbrev
         }
 
         dbg($self, "could not find $cur_want");
@@ -564,9 +564,9 @@ sub extract_diffs_done {
                         my $job = { oid_b => $src, path_b => $di->{path_a} };
                         push @{$self->{todo}}, $job;
                 }
-                goto \&next_step; # onto the next todo item
+                return next_step($self); # onto the next todo item
         }
-        goto \&try_harder;
+        try_harder($self, $want);
 }
 
 sub extract_diff_async {
@@ -578,9 +578,8 @@ sub extract_diff_async {
                 PublicInbox::Eml->new($bref)->each_part(\&extract_diff, $x, 1);
         }
 
-        scalar(@{$want->{try_smsgs}}) ?
-                retry_current($self, $want) :
-                extract_diffs_done($self, $want);
+        scalar(@{$want->{try_smsgs}}) ? retry_current($self, $want)
+                                        : extract_diffs_done($self, $want);
 }
 
 sub resolve_patch ($$) {
@@ -605,7 +604,8 @@ sub resolve_patch ($$) {
                         }
                 }
 
-                goto(scalar @$msgs ? \&retry_current : \&extract_diffs_done);
+                return scalar(@$msgs) ? retry_current($self, $want)
+                                        : extract_diffs_done($self, $want);
         }
 
         # see if we can find the blob in an existing git repo:
@@ -626,9 +626,9 @@ sub resolve_patch ($$) {
                         return;
                 }
                 mark_found($self, $cur_want, $existing);
-                goto \&next_step; # onto patch application
+                return next_step($self); # onto patch application
         } elsif ($existing > 0) {
-                goto \&retry_current;
+                return retry_current($self, $want);
         } else { # $existing == 0: we may retry if inbox scan (below) fails
                 delete $want->{try_gits};
         }
@@ -640,9 +640,9 @@ sub resolve_patch ($$) {
                 $want->{try_smsgs} = $msgs;
                 $want->{cur_ibx} = $ibx;
                 $self->{tmp_diffs} = [];
-                goto \&retry_current;
+                return retry_current($self, $want);
         }
-        goto \&try_harder;
+        try_harder($self, $want);
 }
 
 # this API is designed to avoid creating self-referential structures;
diff --git a/lib/PublicInbox/V2Writable.pm b/lib/PublicInbox/V2Writable.pm
index a1f6048f..b8abfa94 100644
--- a/lib/PublicInbox/V2Writable.pm
+++ b/lib/PublicInbox/V2Writable.pm
@@ -1267,8 +1267,8 @@ sub xapian_only {
 # public, called by public-inbox-index
 sub index_sync {
         my ($self, $opt) = @_;
-        $opt //= $_[1] //= {};
-        goto \&xapian_only if $opt->{xapian_only};
+        $opt //= {};
+        return xapian_only($self, $opt) if $opt->{xapian_only};
 
         my $pr = $opt->{-progress};
         my $epoch_max;
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 3055da20..1d5119cd 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -386,7 +386,7 @@ sub next_in_queue ($$) {
 
 sub stream_thread_i { # PublicInbox::WwwStream::getline callback
         my ($ctx, $eml) = @_;
-        goto &thread_eml_entry if $eml; # tail recursion
+        return thread_eml_entry($ctx, $eml) if $eml;
         return unless exists($ctx->{skel});
         my $ghost_ok = $ctx->{nr}++;
         while (1) {
diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm
index 0f41dff2..8bbce929 100644
--- a/lib/PublicInbox/Watch.pm
+++ b/lib/PublicInbox/Watch.pm
@@ -651,7 +651,7 @@ sub event_step {
                 PublicInbox::Sigfd::sig_setmask($oldset);
                 die $@ if $@;
         }
-        goto(&fs_scan_step) if $self->{mdre};
+        fs_scan_step($self) if $self->{mdre};
 }
 
 sub watch_imap_fetch_all ($$) {
@@ -1066,7 +1066,7 @@ sub fs_scan_step {
 sub scan {
         my ($self, $op) = @_;
         push @{$self->{ops}}, $op;
-        goto &fs_scan_step;
+        fs_scan_step($self);
 }
 
 sub _importer_for {