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

ruby-changes:69004

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:19:39 +0900 (JST)
Subject: [ruby-changes:69004] 684e84df7c (master): Use rb_ivar_get() for general case of getivar (#17)

https://git.ruby-lang.org/ruby.git/commit/?id=684e84df7c

From 684e84df7cdfd47d2b66d717369121337a2bd32d Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Thu, 29 Apr 2021 11:47:19 -0400
Subject: Use rb_ivar_get() for general case of getivar (#17)

* Use rb_ivar_get() for general case of getivar

Pretty straight forward. Buys about 1% coverage on railsbench.

* Update yjit_codegen.c

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@g...>
---
 bootstraptest/test_yjit.rb | 27 +++++++++++++++++++++++++++
 yjit_codegen.c             | 23 +++++++++++++++++++++--
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 6bf0f53e9e..6ac31f8134 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -656,6 +656,33 @@ assert_equal '[100, 299]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L656
   [bar(ins), bar(oth)]
 }
 
+# get ivar on object, then on hash
+assert_equal '[42, 100]', %q{
+  class Hash
+    attr_accessor :foo
+  end
+
+  class A
+    attr_reader :foo
+
+    def initialize
+      @foo = 42
+    end
+  end
+
+  def use(val)
+    val.foo
+  end
+
+
+  h = {}
+  h.foo = 100
+  obj = A.new
+
+  use(obj)
+  [use(obj), use(h)]
+}
+
 # get ivar on String
 assert_equal '[nil, nil, 42, 42]', %q{
   # @foo to exercise the getinstancevariable instruction
diff --git a/yjit_codegen.c b/yjit_codegen.c
index ace2df622d..99e77fc82f 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -924,8 +924,27 @@ gen_get_ivar(jitstate_t *jit, ctx_t *ctx, const int max_chain_depth, VALUE compt https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L924
     //       Eventually, we can encode whether an object is T_OBJECT or not
     //       inside object shapes.
     if (rb_get_alloc_func(comptime_val_klass) != rb_class_allocate_instance) {
-        GEN_COUNTER_INC(cb, getivar_not_object);
-        return YJIT_CANT_COMPILE;
+        // General case. Call rb_ivar_get(). No need to reconstruct interpreter
+        // state since the routine never raises exceptions or allocate objects
+        // visibile to Ruby.
+        // VALUE rb_ivar_get(VALUE obj, ID id)
+        ADD_COMMENT(cb, "call rb_ivar_get()");
+        yjit_save_regs(cb);
+        mov(cb, C_ARG_REGS[0], REG0);
+        mov(cb, C_ARG_REGS[1], imm_opnd((int64_t)ivar_name));
+        call_ptr(cb, REG1, (void *)rb_ivar_get);
+        yjit_load_regs(cb);
+
+        if (!reg0_opnd.is_self) {
+            (void)ctx_stack_pop(ctx, 1);
+        }
+        // Push the ivar on the stack
+        x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN);
+        mov(cb, out_opnd, RAX);
+
+        // Jump to next instruction. This allows guard chains to share the same successor.
+        jit_jump_to_next_insn(jit, ctx);
+        return YJIT_END_BLOCK;
     }
     RUBY_ASSERT(BUILTIN_TYPE(comptime_receiver) == T_OBJECT); // because we checked the allocator
 
-- 
cgit v1.2.1


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

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