summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C. Anderson <ian@iancanderson.com>2021-10-25 10:40:33 -0400
committerGitHub <noreply@github.com>2021-10-25 10:40:33 -0400
commite943511455acfd70dc3bd085038969a11802d688 (patch)
treec2a49aec9b1657a16ec7820976cad0a11f96cf1f
parent1c0c8d5da2abc84a56ca4b66b73e0c262df0fbbe (diff)
YJIT: Implement duphash (#5009)
`duphash` showed up in the top-20 most frequent exit ops for @jhawthorn's benchmark that renders github.com/about The implementation was almost exactly the same as `duparray` Co-authored-by: John Hawthorn <john@hawthorn.email> Co-authored-by: John Hawthorn <john@hawthorn.email>
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
-rw-r--r--bootstraptest/test_yjit.rb10
-rw-r--r--common.mk1
-rw-r--r--yjit_codegen.c21
3 files changed, 32 insertions, 0 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 183b19c3eb..c94c710c4d 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -2268,3 +2268,13 @@ assert_equal "true", %q{
expected == events
}
+
+# duphash
+assert_equal '{:foo=>123}', %q{
+ def foo
+ {foo: 123}
+ end
+
+ foo
+ foo
+}
diff --git a/common.mk b/common.mk
index c3c599d24d..1fc5922710 100644
--- a/common.mk
+++ b/common.mk
@@ -16903,6 +16903,7 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/class.h
yjit.$(OBJEXT): $(top_srcdir)/internal/compile.h
yjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
+yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
yjit.$(OBJEXT): $(top_srcdir)/internal/object.h
yjit.$(OBJEXT): $(top_srcdir)/internal/re.h
diff --git a/yjit_codegen.c b/yjit_codegen.c
index be4d7f0165..374786571c 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -3,6 +3,7 @@
#include "gc.h"
#include "internal/compile.h"
#include "internal/class.h"
+#include "internal/hash.h"
#include "internal/object.h"
#include "internal/sanitizers.h"
#include "internal/string.h"
@@ -895,6 +896,25 @@ gen_duparray(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
return YJIT_KEEP_COMPILING;
}
+// dup hash
+static codegen_status_t
+gen_duphash(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
+{
+ VALUE hash = jit_get_arg(jit, 0);
+
+ // Save the PC and SP because we are allocating
+ jit_prepare_routine_call(jit, ctx, REG0);
+
+ // call rb_hash_resurrect(VALUE hash);
+ jit_mov_gc_ptr(jit, cb, C_ARG_REGS[0], hash);
+ call_ptr(cb, REG0, (void *)rb_hash_resurrect);
+
+ x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_HASH);
+ mov(cb, stack_ret, RAX);
+
+ return YJIT_KEEP_COMPILING;
+}
+
VALUE rb_vm_splat_array(VALUE flag, VALUE ary);
// call to_a on the array on the stack
@@ -4640,6 +4660,7 @@ yjit_init_codegen(void)
yjit_reg_op(BIN(adjuststack), gen_adjuststack);
yjit_reg_op(BIN(newarray), gen_newarray);
yjit_reg_op(BIN(duparray), gen_duparray);
+ yjit_reg_op(BIN(duphash), gen_duphash);
yjit_reg_op(BIN(splatarray), gen_splatarray);
yjit_reg_op(BIN(expandarray), gen_expandarray);
yjit_reg_op(BIN(newhash), gen_newhash);