ruby-changes:67205
From: Jeremy <ko1@a...>
Date: Sun, 22 Aug 2021 02:15:16 +0900 (JST)
Subject: [ruby-changes:67205] 48c8df9e0e (master): Allow tracing of optimized methods
https://git.ruby-lang.org/ruby.git/commit/?id=48c8df9e0e From 48c8df9e0eb295af06d593ce37ce1933c0ee1d90 Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Sat, 21 Aug 2021 10:15:01 -0700 Subject: Allow tracing of optimized methods This updates the trace instructions to directly dispatch to opt_send_without_block. So this should cause no slowdown in non-trace mode. To enable the tracing of the optimized methods, RUBY_EVENT_C_CALL and RUBY_EVENT_C_RETURN are added as events to the specialized instructions. Fixes [Bug #14870] Co-authored-by: Takashi Kokubun <takashikkbn@g...> --- compile.c | 1 + iseq.h | 2 ++ spec/ruby/core/tracepoint/inspect_spec.rb | 7 ++--- test/ruby/test_optimization.rb | 45 +++++++++++++++++++++++++++++++ tool/ruby_vm/views/_trace_instruction.erb | 7 ++++- 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/compile.c b/compile.c index d73a42a..3663430 100644 --- a/compile.c +++ b/compile.c @@ -3441,6 +3441,7 @@ insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id) https://github.com/ruby/ruby/blob/trunk/compile.c#L3441 { iobj->insn_id = insn_id; iobj->operand_size = insn_len(insn_id) - 1; + iobj->insn_info.events |= RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN; if (insn_id == BIN(opt_neq)) { VALUE original_ci = iobj->operands[0]; diff --git a/iseq.h b/iseq.h index b792e13..25c130e 100644 --- a/iseq.h +++ b/iseq.h @@ -74,6 +74,8 @@ ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size) https://github.com/ruby/ruby/blob/trunk/iseq.h#L74 RUBY_EVENT_END | \ RUBY_EVENT_CALL | \ RUBY_EVENT_RETURN| \ + RUBY_EVENT_C_CALL| \ + RUBY_EVENT_C_RETURN| \ RUBY_EVENT_B_CALL| \ RUBY_EVENT_B_RETURN| \ RUBY_EVENT_COVERAGE_LINE| \ diff --git a/spec/ruby/core/tracepoint/inspect_spec.rb b/spec/ruby/core/tracepoint/inspect_spec.rb index 06bed9c..67e2ad1 100644 --- a/spec/ruby/core/tracepoint/inspect_spec.rb +++ b/spec/ruby/core/tracepoint/inspect_spec.rb @@ -65,11 +65,12 @@ describe 'TracePoint#inspect' do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/tracepoint/inspect_spec.rb#L65 it 'returns a String showing the event, method, path and line for a :c_call event' do inspect = nil line = nil - TracePoint.new(:c_call) { |tp| + tp = TracePoint.new(:c_call) { |tp| next unless TracePointSpec.target_thread? inspect ||= tp.inspect - }.enable do - line = __LINE__ + 1 + } + line = __LINE__ + 2 + tp.enable do [0, 1].max end diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb index b0090d6..226fb44 100644 --- a/test/ruby/test_optimization.rb +++ b/test/ruby/test_optimization.rb @@ -150,6 +150,51 @@ class TestRubyOptimization < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L150 assert_redefine_method('String', '-@', 'assert_nil(-"foo")') end + def test_trace_optimized_methods + bug14870 = "[ruby-core:87638]" + expected = [:-@, :max, :min, :+, :-, :*, :/, :%, :==, :<, :<=, :>, :>=, :<<, + :&, :|, :[], :[]=, :length, :empty?, :nil?, :succ, :!, :=~] + [:c_call, :c_return].each do |type| + methods = [] + tp = TracePoint.new(type) { |tp| methods << tp.method_id } + tp.enable do + x = "a"; -x + [1].max + [1].min + x = 42 + 2 + x = 42 - 2 + x = 42 * 2 + x = 42 / 2 + x = 42 % 2 + x == 42 + x < 42 + x <= 42 + x > 42 + x >= 42 + x = x << 1 + x = x & 1 + x = x | 1 + x = []; x[1] + x[1] = 2 + x.length + x.empty? + x.nil? + x = 1; x.succ + !x + x = 'a'; x =~ /a/ + end + assert_equal(expected, methods, bug14870) + end + + methods = [] + tp = TracePoint.new(:c_call, :c_return) { |tp| methods << tp.method_id } + tp.enable do + x = 1 + x != 42 + end + assert_equal([:!=, :==, :==, :!=], methods, bug14870) + end + def test_string_freeze_saves_memory n = 16384 data = '.'.freeze diff --git a/tool/ruby_vm/views/_trace_instruction.erb b/tool/ruby_vm/views/_trace_instruction.erb index d604e03..3588207 100644 --- a/tool/ruby_vm/views/_trace_instruction.erb +++ b/tool/ruby_vm/views/_trace_instruction.erb @@ -11,6 +11,11 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_trace_instruction.erb#L11 INSN_ENTRY(<%= insn.name %>) { vm_trace(ec, GET_CFP()); - DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>); +% if insn.name =~ +% /\Atrace_opt_(plus|minus|mult|div|mod|eq|neq|lt|le|gt|ge|ltlt|and|or|aref|aset|length|size|empty_p|nil_p|succ|not|regexpmatch2)\z/ +% jump_dest = "opt_send_without_block" +% end + <%= 'ADD_PC(1);' if insn.name == 'trace_opt_neq' %> + DISPATCH_ORIGINAL_INSN(<%= jump_dest || insn.jump_destination %>); END_INSN(<%= insn.name %>); } -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/