ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: alanwucanada@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:90377] [Ruby trunk Bug#15303] Return tracepoint doesn't fire when tailcall optimization is applied
Date: Sat, 08 Dec 2018 06:33:22 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-75487.20181208063317.924c3cd0663c1cb3@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-15303.20181114191300@ruby-lang.org

Issue #15303 has been updated by alanwu (Alan Wu).

File no-tco-no-problem.patch added

ko1 (Koichi Sasada) wrote:
> Cancel tailcall opt when `return` event is specified.

I think anyone who goes through all the trouble to enable tailcall elimination right now relies on it to avoid stack overflow.
Why else would someone use it? It doesn't make your program faster, it's cumbersome to enable, and it erases part of your stack trace which makes debugging harder.

Making this change seems to me replacing a problem with a different one. It is a problem that affects way less people admittedly, but I feel that it would be punishing functional programmers for the benefit of everyone else.

If we just want to fix the problem most people have today, i.e., byebug's `next` command's breakage, making Forwardable not use TCO is good enough. It will still be broken for tailcall optimized code, but at least most people won't run into this problem.
That might be the most pragmatic "fix", and it's a simple one. With it, we can keep ignoring this problem and wait till someone complains.

----------------------------------------
Bug #15303: Return tracepoint doesn't fire when tailcall optimization is applied
https://bugs.ruby-lang.org/issues/15303#change-75487

* Author: alanwu (Alan Wu)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0dev (2018-11-14 trunk 65727) [x86_64-darwin17]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
After a tailcall, the "return" tracepoint event is only fired once. Normally, after a call at the end of a method, the return event is fired twice, once for the callee returning and once for the caller returning.
The following script outputs 
~~~
:call
:call
:call
:return
~~~

~~~ ruby
method_source = <<-RB
def toy(n)
   return if n == 2
   toy(n+1)
end
RB

iseq = RubyVM::InstructionSequence.compile(method_source, tailcall_optimization: true)
#puts iseq.disasm
iseq.eval

trace = TracePoint.new(:call, :return) do |tp|
    p tp.event
end

trace.enable
toy(0)
~~~

The "return" event behaves more like a "stack frame pop" event currently. I don't think it's feasible/desirable to have the same behavior when TCO is applied, but it would be nice if there was some way for the tracepoint to know a tail call is going to happen.
I'm raising this issue because the popular debugger "byebug" relies on these events to track execution in various stack frames. https://github.com/deivid-rodriguez/byebug/issues/481
Forwardable explicitly uses TCO which triggers this issue.


---Files--------------------------------
no-tco-no-problem.patch (520 Bytes)


-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2018-12-08  6:33 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-15303.20181114191300@ruby-lang.org>
2018-11-14 19:13 ` [ruby-core:89797] [Ruby trunk Bug#15303] Return tracepoint doesn't fire when tailcall optimization is applied alanwucanada
2018-12-05  7:03 ` [ruby-core:90300] " ko1
2018-12-05 15:50 ` [ruby-core:90317] " alanwucanada
2018-12-05 16:33 ` [ruby-core:90318] " ko1
2018-12-05 16:50 ` [ruby-core:90319] " alanwucanada
2018-12-05 17:02 ` [ruby-core:90321] " ko1
2018-12-05 17:19 ` [ruby-core:90323] " alanwucanada
2018-12-08  1:31 ` [ruby-core:90376] " ko1
2018-12-08  6:33 ` alanwucanada [this message]
2018-12-11 22:20 ` [ruby-core:90428] " deivid.rodriguez
2018-12-12  6:06 ` [ruby-core:90437] " ko1
2018-12-12 12:07 ` [ruby-core:90446] " deivid.rodriguez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-75487.20181208063317.924c3cd0663c1cb3@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).