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

ruby-changes:69882

From: Eileen <ko1@a...>
Date: Wed, 24 Nov 2021 04:09:44 +0900 (JST)
Subject: [ruby-changes:69882] 459f9e3df8 (master): Add setclassvariable to yjit (#5127)

https://git.ruby-lang.org/ruby.git/commit/?id=459f9e3df8

From 459f9e3df8e8080d8c44aed3636a337e6ee64132 Mon Sep 17 00:00:00 2001
From: "Eileen M. Uchitelle" <eileencodes@u...>
Date: Tue, 23 Nov 2021 14:09:24 -0500
Subject: Add setclassvariable to yjit (#5127)

Implements setclassvariable in yjit. Note that this version is not
faster than the standard version because we aren't handling the inline
cache in assembly. This is still important to implement because it will
prevent yjit from exiting in methods that call both a cvar setter and
other code that yjit can compile.

Co-authored-by: Aaron Patterson tenderlove@r...
---
 test/ruby/test_yjit.rb |  5 +++++
 vm_insnhelper.c        |  6 ++++++
 yjit_codegen.c         | 21 +++++++++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index a571432ccdc..d951f79cfc7 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -52,6 +52,11 @@ class TestYJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_yjit.rb#L52
     assert_in_out_err([yjit_child_env, '-e p RubyVM::YJIT.enabled?'], '', ['true'])
   end
 
+  def test_compile_setclassvariable
+    script = 'class Foo; def self.foo; @@foo = 1; end; end; Foo.foo'
+    assert_compiles(script, insns: %i[setclassvariable], result: 1)
+  end
+
   def test_compile_getclassvariable
     script = 'class Foo; @@foo = 1; def self.foo; @@foo; end; end; Foo.foo'
     assert_compiles(script, insns: %i[getclassvariable], result: 1)
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index d1930d146c9..348bfea5aae 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1367,6 +1367,12 @@ vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *reg_cfp, ID https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1367
     update_classvariable_cache(iseq, klass, id, ic);
 }
 
+void
+rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic)
+{
+    vm_setclassvariable(iseq, cfp, id, val, ic);
+}
+
 static inline VALUE
 vm_getinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, IVC ic)
 {
diff --git a/yjit_codegen.c b/yjit_codegen.c
index c34c56a972d..add1e2012af 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -4488,6 +4488,26 @@ gen_getclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L4488
     return YJIT_KEEP_COMPILING;
 }
 
+VALUE
+rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic);
+
+static codegen_status_t
+gen_setclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb)
+{
+    // rb_vm_setclassvariable can raise exceptions.
+    jit_prepare_routine_call(jit, ctx, REG0);
+
+    mov(cb, C_ARG_REGS[0], member_opnd(REG_CFP, rb_control_frame_t, iseq));
+    mov(cb, C_ARG_REGS[1], REG_CFP);
+    mov(cb, C_ARG_REGS[2], imm_opnd(jit_get_arg(jit, 0)));
+    mov(cb, C_ARG_REGS[3], ctx_stack_pop(ctx, 1));
+    mov(cb, C_ARG_REGS[4], imm_opnd(jit_get_arg(jit, 1)));
+
+    call_ptr(cb, REG0, (void *)rb_vm_setclassvariable);
+
+    return YJIT_KEEP_COMPILING;
+}
+
 static codegen_status_t
 gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
 {
@@ -4886,6 +4906,7 @@ yjit_init_codegen(void) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L4906
     yjit_reg_op(BIN(toregexp), gen_toregexp);
     yjit_reg_op(BIN(getspecial), gen_getspecial);
     yjit_reg_op(BIN(getclassvariable), gen_getclassvariable);
+    yjit_reg_op(BIN(setclassvariable), gen_setclassvariable);
 
     yjit_method_codegen_table = st_init_numtable();
 
-- 
cgit v1.2.1


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

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