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

ruby-changes:68652

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:11:43 +0900 (JST)
Subject: [ruby-changes:68652] 11c1daea17 (master): Add to the MicroJIT scraper an example that passes ec

https://git.ruby-lang.org/ruby.git/commit/?id=11c1daea17

From 11c1daea172df21af30be24d645040d8de9d461d Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Mon, 19 Oct 2020 17:45:43 -0400
Subject: Add to the MicroJIT scraper an example that passes ec

---
 iseq.c                                             |  7 +++++
 iseq.h                                             |  1 +
 tool/ruby_vm/models/micro_jit.rb                   | 35 +++++++++++++++++-----
 .../models/micro_jit/example_instructions.rb       | 10 +++++--
 tool/ruby_vm/views/ujit_examples.inc.erb           |  7 +++--
 tool/ruby_vm/views/vm.inc.erb                      |  2 +-
 6 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/iseq.c b/iseq.c
index 6b8f3d0e2c..d4d5261c3c 100644
--- a/iseq.c
+++ b/iseq.c
@@ -3495,6 +3495,13 @@ rb_ujit_empty_func(rb_control_frame_t *cfp) https://github.com/ruby/ruby/blob/trunk/iseq.c#L3495
     return NULL;
 }
 
+VALUE *
+rb_ujit_empty_func_with_ec(rb_control_frame_t *cfp, rb_execution_context_t *ec)
+{
+    // see rb_ujit_empty_func
+    return NULL;
+}
+
 void
 rb_iseq_trace_set_all(rb_event_flag_t turnon_events)
 {
diff --git a/iseq.h b/iseq.h
index 9b5eb138ad..cd939a0684 100644
--- a/iseq.h
+++ b/iseq.h
@@ -316,6 +316,7 @@ VALUE rb_iseq_defined_string(enum defined_type type); https://github.com/ruby/ruby/blob/trunk/iseq.h#L316
 VALUE rb_iseq_local_variables(const rb_iseq_t *iseq);
 
 NOINLINE(VALUE *rb_ujit_empty_func(rb_control_frame_t *cfp));
+NOINLINE(VALUE *rb_ujit_empty_func_with_ec(rb_control_frame_t *cfp, rb_execution_context_t *ec));
 
 
 RUBY_SYMBOL_EXPORT_END
diff --git a/tool/ruby_vm/models/micro_jit.rb b/tool/ruby_vm/models/micro_jit.rb
index b2ce26cb3a..63815a85a0 100644
--- a/tool/ruby_vm/models/micro_jit.rb
+++ b/tool/ruby_vm/models/micro_jit.rb
@@ -128,20 +128,23 @@ module RubyVM::MicroJIT https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/micro_jit.rb#L128
       raise "found an unrecognized \"#{unrecognized[1]}\" instruction in the example. List of recognized instructions: #{acceptable_mnemonics.join(', ')}" if unrecognized
       raise 'found multiple jmp instructions' if handler_instructions.count { |_, mnemonic, _| mnemonic == 'jmp' } > 1
       raise "the jmp instruction seems to be relative which isn't copiable" if instructions[jmp_idx][0].split.size > 4
+      raise 'no call instructions found' if handler_instructions.count { |_, mnemonic, _| mnemonic == 'call' } == 0
       raise 'found multiple call instructions' if handler_instructions.count { |_, mnemonic, _| mnemonic == 'call' } > 1
       call_idx = handler_instructions.find_index { |_, mnemonic, _| mnemonic == 'call' }
 
 
-      @pre_call_bytes = []
-      @post_call_bytes = []
+      pre_call_bytes = []
+      post_call_bytes = []
 
       handler_instructions.take(call_idx).each do |bytes, mnemonic, _|
-        @pre_call_bytes += bytes.split
+        pre_call_bytes += bytes.split
       end
 
       handler_instructions[call_idx + 1, handler_instructions.size].each do |bytes, _, _|
-        @post_call_bytes += bytes.split
+        post_call_bytes += bytes.split
       end
+
+      [pre_call_bytes, post_call_bytes]
     end
 
     def darwin_scrape(instruction_id)
@@ -166,8 +169,19 @@ module RubyVM::MicroJIT https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/micro_jit.rb#L169
       disassemble(handler_offset)
     end
 
-    def scrape
-      instruction_id = RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example' }
+    def make_result(success, pre_call, post_call, pre_call_with_ec, post_call_with_ec)
+      [success ? 1 : 0,
+       [
+         ['ujit_pre_call_bytes', comma_separated_hex_string(pre_call)],
+         ['ujit_post_call_bytes', comma_separated_hex_string(post_call)],
+         ['ujit_pre_call_with_ec_bytes', comma_separated_hex_string(pre_call_with_ec)],
+         ['ujit_post_call_with_ec_bytes', comma_separated_hex_string(post_call_with_ec)]
+       ]
+      ]
+    end
+
+    def scrape_instruction(instruction_id)
+      raise unless instruction_id.is_a?(Integer)
       case target_platform
       when :darwin
         darwin_scrape(instruction_id)
@@ -176,10 +190,15 @@ module RubyVM::MicroJIT https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/micro_jit.rb#L190
       else
         raise 'Unkonwn platform. Only Mach-O on macOS and ELF on Linux are supported'
       end
-      [true, comma_separated_hex_string(@pre_call_bytes), comma_separated_hex_string(@post_call_bytes)]
+    end
+
+    def scrape
+      pre, post = scrape_instruction(RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example' })
+      pre_with_ec, post_with_ec = scrape_instruction(RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example_with_ec' })
+      make_result(true, pre, post, pre_with_ec, post_with_ec)
     rescue => e
       print_warning("scrape failed: #{e.message}")
-      [false, '0xcc', '0xcc']
+      make_result(false, ['cc'], ['cc'], ['cc'], ['cc'])
     end
 
     def print_warning(text)
diff --git a/tool/ruby_vm/models/micro_jit/example_instructions.rb b/tool/ruby_vm/models/micro_jit/example_instructions.rb
index 5117d1c519..111346f6e9 100644
--- a/tool/ruby_vm/models/micro_jit/example_instructions.rb
+++ b/tool/ruby_vm/models/micro_jit/example_instructions.rb
@@ -13,10 +13,11 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/micro_jit/example_instructions.rb#L13
 class RubyVM::MicroJIT::ExampleInstructions
   include RubyVM::CEscape
 
-  attr_reader :name
+  attr_reader :name, :call_line
 
-  def initialize name
+  def initialize(name, call_line)
     @name = name
+    @call_line = call_line
   end
 
   def pretty_name
@@ -63,7 +64,10 @@ class RubyVM::MicroJIT::ExampleInstructions https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/micro_jit/example_instructions.rb#L64
     false
   end
 
-  @all_examples = [new('ujit_call_example')]
+  @all_examples = [
+    new('ujit_call_example', 'reg_pc = rb_ujit_empty_func(GET_CFP());'),
+    new('ujit_call_example_with_ec', 'reg_pc = rb_ujit_empty_func_with_ec(GET_CFP(), ec);')
+  ]
 
   def self.to_a
     @all_examples
diff --git a/tool/ruby_vm/views/ujit_examples.inc.erb b/tool/ruby_vm/views/ujit_examples.inc.erb
index 5fefcd4674..af0561f852 100644
--- a/tool/ruby_vm/views/ujit_examples.inc.erb
+++ b/tool/ruby_vm/views/ujit_examples.inc.erb
@@ -12,7 +12,8 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/ujit_examples.inc.erb#L12
     edit: __FILE__,
 } -%>
 
-% success, pre_call_bytes, post_call_bytes = RubyVM::MicroJIT.scrape
+% success, byte_arrays = RubyVM::MicroJIT.scrape
 static const uint8_t ujit_scrape_successful = <%= success %>;
-static const uint8_t ujit_pre_call_bytes[] = { <%= pre_call_bytes %> };
-static const uint8_t ujit_post_call_bytes[] = { <%= post_call_bytes %> };
+% byte_arrays.each do |(name, bytes)|
+static const uint8_t <%= name %>[] = { <%= bytes %> };
+% end
diff --git a/tool/ruby_vm/views/vm.inc.erb b/tool/ruby_vm/views/vm.inc.erb
index 91e0b930c0..235eb30b11 100644
--- a/tool/ruby_vm/views/vm.inc.erb
+++ b/tool/ruby_vm/views/vm.inc.erb
@@ -32,7 +32,7 @@ INSN_ENTRY(<%= insn.name %>) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/vm.inc.erb#L32
 #if USE_MACHINE_REGS
     // assumes USE_MACHINE_REGS, aka reg_pc setup,
     // aka #define SET_PC(x) (reg_cfp->pc = reg_pc = (x))
-    reg_pc = rb_ujit_empty_func(GET_CFP());
+    <%= insn.call_line %>
 #endif
     END_INSN(<%= insn.name %>);
 }
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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