[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]