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

ruby-changes:69060

From: eileencodes <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:42 +0900 (JST)
Subject: [ruby-changes:69060] 2ba090a1f9 (master): Add toregexp to yjit

https://git.ruby-lang.org/ruby.git/commit/?id=2ba090a1f9

From 2ba090a1f9258035b40374f9ff9da3ff920701cd Mon Sep 17 00:00:00 2001
From: eileencodes <eileencodes@g...>
Date: Tue, 10 Aug 2021 09:10:34 -0400
Subject: Add toregexp to yjit

The FIXME is there so we remember to investigate why insns clears the
temporary array. Is this necessary? If it's not we can remove it from
both.

Co-authored-by: Aaron Patterson <tenderlove@r...>
---
 common.mk              |  1 +
 test/ruby/test_yjit.rb |  4 ++++
 yjit_codegen.c         | 43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git a/common.mk b/common.mk
index 76d62915f6..5ccc9a389d 100644
--- a/common.mk
+++ b/common.mk
@@ -16721,6 +16721,7 @@ yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/compilers.h https://github.com/ruby/ruby/blob/trunk/common.mk#L16721
 yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/gc.h
 yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/imemo.h
 yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/object.h
+yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/re.h
 yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/serial.h
 yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
 yjit_codegen.$(OBJEXT): $(top_srcdir)/internal/string.h
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index 8160042cb9..1f5f99f9a8 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -67,6 +67,10 @@ class TestYJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_yjit.rb#L67
     assert_no_exits('"i am a string #{true}"')
   end
 
+  def test_compile_regexp
+    assert_no_exits('/#{true}/')
+  end
+
   def test_getlocal_with_level
     assert_compiles(<<~RUBY, insns: %i[getlocal opt_plus], result: [[7]])
       def foo(foo, bar)
diff --git a/yjit_codegen.c b/yjit_codegen.c
index fc4d46a329..3f9169a74b 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -10,6 +10,7 @@ https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L10
 #include "internal/object.h"
 #include "internal/string.h"
 #include "internal/variable.h"
+#include "internal/re.h"
 #include "insns_info.inc"
 #include "yjit.h"
 #include "yjit_iface.h"
@@ -3520,6 +3521,47 @@ gen_tostring(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3521
     return YJIT_KEEP_COMPILING;
 }
 
+static codegen_status_t
+gen_toregexp(jitstate_t* jit, ctx_t* ctx)
+{
+    rb_num_t opt = jit_get_arg(jit, 0);
+    rb_num_t cnt = jit_get_arg(jit, 1);
+
+    // Save the PC and SP because this allocates an object and could
+    // raise an exception.
+    jit_save_pc(jit, REG0);
+    jit_save_sp(jit, ctx);
+
+    x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(sizeof(VALUE) * (uint32_t)cnt));
+    ctx_stack_pop(ctx, cnt);
+
+    mov(cb, C_ARG_REGS[0], imm_opnd(0));
+    mov(cb, C_ARG_REGS[1], imm_opnd(cnt));
+    lea(cb, C_ARG_REGS[2], values_ptr);
+    call_ptr(cb, REG0, (void *)&rb_ary_tmp_new_from_values);
+
+    // Save the array so we can clear it later
+    push(cb, RAX);
+    push(cb, RAX); // Alignment
+    mov(cb, C_ARG_REGS[0], RAX);
+    mov(cb, C_ARG_REGS[1], imm_opnd(opt));
+    call_ptr(cb, REG0, (void *)&rb_reg_new_ary);
+
+    // The actual regex is in RAX now.  Pop the temp array from
+    // rb_ary_tmp_new_from_values into C arg regs so we can clear it
+    pop(cb, REG1); // Alignment
+    pop(cb, C_ARG_REGS[0]);
+
+    // The value we want to push on the stack is in RAX right now
+    x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
+    mov(cb, stack_ret, RAX);
+
+    // Clear the temp array.
+    call_ptr(cb, REG0, (void *)&rb_ary_clear);
+
+    return YJIT_KEEP_COMPILING;
+}
+
 static codegen_status_t
 gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx)
 {
@@ -3758,6 +3800,7 @@ yjit_init_codegen(void) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3800
     yjit_reg_op(BIN(getglobal), gen_getglobal);
     yjit_reg_op(BIN(setglobal), gen_setglobal);
     yjit_reg_op(BIN(tostring), gen_tostring);
+    yjit_reg_op(BIN(toregexp), gen_toregexp);
 
     yjit_method_codegen_table = st_init_numtable();
 
-- 
cgit v1.2.1


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

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