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

ruby-changes:69477

From: John <ko1@a...>
Date: Wed, 27 Oct 2021 23:55:57 +0900 (JST)
Subject: [ruby-changes:69477] a6104b392a (master): YJIT: Support newhash with values (#5029)

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

From a6104b392ab347c323c93a51fb3b95c3c2cc9e8f Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Wed, 27 Oct 2021 07:55:43 -0700
Subject: YJIT: Support newhash with values (#5029)

* YJIT: Implement newhash with values

* YJIT: Add test of duphash

* Fix compilation on macos/clang
---
 bootstraptest/test_yjit.rb | 10 ++++++++++
 test/ruby/test_yjit.rb     | 10 ++++++++++
 yjit_codegen.c             | 37 ++++++++++++++++++++++++++++---------
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index c94c710c4dd..0a3aa81860d 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -2278,3 +2278,13 @@ assert_equal '{:foo=>123}', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L2278
   foo
   foo
 }
+
+# newhash
+assert_equal '{:foo=>2}', %q{
+  def foo
+    {foo: 1+1}
+  end
+
+  foo
+  foo
+}
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index 9b26e6c37f2..7b8cde6c0cd 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -85,6 +85,16 @@ class TestYJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_yjit.rb#L85
     assert_compiles('e = 5; (..e)', insns: %i[newrange], result: ..5)
   end
 
+  def test_compile_duphash
+    assert_compiles('{ two: 2 }', insns: %i[duphash], result: { two: 2 })
+  end
+
+  def test_compile_newhash
+    assert_compiles('{}', insns: %i[newhash], result: {})
+    assert_compiles('{ two: 1 + 1 }', insns: %i[newhash], result: { two: 2 })
+    assert_compiles('{ 1 + 1 => :two }', insns: %i[newhash], result: { 2 => :two })
+  end
+
   def test_compile_opt_nil_p
     assert_compiles('nil.nil?', insns: %i[opt_nil_p], result: true)
     assert_compiles('false.nil?', insns: %i[opt_nil_p], result: false)
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 374786571c0..b0d799c0132 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -1078,23 +1078,42 @@ gen_expandarray(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1078
 static codegen_status_t
 gen_newhash(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
 {
-    rb_num_t n = (rb_num_t)jit_get_arg(jit, 0);
+    int32_t num = (int32_t)jit_get_arg(jit, 0);
 
-    if (n == 0) {
-        // Save the PC and SP because we are allocating
-        jit_prepare_routine_call(jit, ctx, REG0);
+    // Save the PC and SP because we are allocating
+    jit_prepare_routine_call(jit, ctx, REG0);
 
-        // val = rb_hash_new();
-        call_ptr(cb, REG0, (void *)rb_hash_new);
+    if (num) {
+        // val = rb_hash_new_with_size(num / 2);
+        mov(cb, C_ARG_REGS[0], imm_opnd(num / 2));
+        call_ptr(cb, REG0, (void *)rb_hash_new_with_size);
+
+        // save the allocated hash as we want to push it after insertion
+        push(cb, RAX);
+        push(cb, RAX); // alignment
+
+        // rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);
+        mov(cb, C_ARG_REGS[0], imm_opnd(num));
+        lea(cb, C_ARG_REGS[1], ctx_stack_opnd(ctx, num - 1));
+        mov(cb, C_ARG_REGS[2], RAX);
+        call_ptr(cb, REG0, (void *)rb_hash_bulk_insert);
 
+        pop(cb, RAX); // alignment
+        pop(cb, RAX);
+
+        ctx_stack_pop(ctx, num);
         x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_HASH);
         mov(cb, stack_ret, RAX);
-
-        return YJIT_KEEP_COMPILING;
     }
     else {
-        return YJIT_CANT_COMPILE;
+        // val = rb_hash_new();
+        call_ptr(cb, REG0, (void *)rb_hash_new);
+
+        x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_HASH);
+        mov(cb, stack_ret, RAX);
     }
+
+    return YJIT_KEEP_COMPILING;
 }
 
 static codegen_status_t
-- 
cgit v1.2.1


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

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