From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS4713 221.184.0.0/13 X-Spam-Status: No, score=-4.1 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id 496FB211B3 for ; Wed, 5 Dec 2018 07:03:50 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 906C1120C64; Wed, 5 Dec 2018 16:03:48 +0900 (JST) Received: from o1678948x4.outbound-mail.sendgrid.net (o1678948x4.outbound-mail.sendgrid.net [167.89.48.4]) by neon.ruby-lang.org (Postfix) with ESMTPS id 18FB2120C1C for ; Wed, 5 Dec 2018 16:03:45 +0900 (JST) Received: by filter0030p3las1.sendgrid.net with SMTP id filter0030p3las1-17528-5C07784F-25 2018-12-05 07:03:43.583711982 +0000 UTC m=+130204.217022051 Received: from herokuapp.com (ec2-54-162-99-180.compute-1.amazonaws.com [54.162.99.180]) by ismtpd0038p1iad2.sendgrid.net (SG) with ESMTP id z2BKOZAuRI2WOLxwhx2Qmw for ; Wed, 05 Dec 2018 07:03:43.337 +0000 (UTC) Date: Wed, 05 Dec 2018 07:03:44 +0000 (UTC) From: ko1@atdot.net To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 65693 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 15303 X-Redmine-Issue-Author: alanwu X-Redmine-Sender: ko1 X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS7uy/+/B6emjwCENTj35oNVa7598WgKTTRC9J Qd89ffMfPQPqZiO3RRxEvpoi16k5PI8fQpQAVLCIWCr6WOLdxqDN73HS2ChNs598tu5HtBUgyW1S8m qamLv9VMjWbVB5B4ZSg/pBFMEI0o801EQ7MM X-ML-Name: ruby-core X-Mail-Count: 90300 Subject: [ruby-core:90300] [Ruby trunk Bug#15303] Return tracepoint doesn't fire when tailcall optimization is applied X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #15303 has been updated by ko1 (Koichi Sasada). hi, how about to call `return` event hook at tailcall? There is no need to introduce new API proposed at [Bug #15313]. ``` def bar end iseq = RubyVM::InstructionSequence.new("def foo; bar; end", __FILE__, __FILE__, __LINE__, tailcall_optimization: true) iseq.eval TracePoint.new(:call, :return){|tp| p tp}.enable{ foo } #=> # # # # ``` patch: ``` diff --git a/compile.c b/compile.c index d97cf4e8c6..696e127b9a 100644 --- a/compile.c +++ b/compile.c @@ -3144,13 +3144,15 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal if (piobj) { struct rb_call_info *ci = (struct rb_call_info *)piobj->operands[0]; - if (IS_INSN_ID(piobj, send) || IS_INSN_ID(piobj, invokesuper)) { - if (piobj->operands[2] == 0) { /* no blockiseq */ - ci->flag |= VM_CALL_TAILCALL; + if (IS_INSN_ID(piobj, send) || IS_INSN_ID(piobj, invokesuper)) { + if (piobj->operands[2] == 0) { /* no blockiseq */ + goto change_to_tailcall; } } else { + change_to_tailcall: ci->flag |= VM_CALL_TAILCALL; + piobj->insn_info.events = RUBY_EVENT_RETURN; } } } ``` ---------------------------------------- Bug #15303: Return tracepoint doesn't fire when tailcall optimization is applied https://bugs.ruby-lang.org/issues/15303#change-75407 * 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. -- https://bugs.ruby-lang.org/