mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
YJIT: Support newhash with values (#5029)
* YJIT: Implement newhash with values * YJIT: Add test of duphash * Fix compilation on macos/clang
This commit is contained in:
parent
5086c25f60
commit
a6104b392a
Notes:
git
2021-10-27 23:56:04 +09:00
Merged-By: maximecb <maximecb@ruby-lang.org>
3 changed files with 48 additions and 9 deletions
|
@ -2278,3 +2278,13 @@ assert_equal '{:foo=>123}', %q{
|
|||
foo
|
||||
foo
|
||||
}
|
||||
|
||||
# newhash
|
||||
assert_equal '{:foo=>2}', %q{
|
||||
def foo
|
||||
{foo: 1+1}
|
||||
end
|
||||
|
||||
foo
|
||||
foo
|
||||
}
|
||||
|
|
|
@ -85,6 +85,16 @@ class TestYJIT < Test::Unit::TestCase
|
|||
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)
|
||||
|
|
|
@ -1078,23 +1078,42 @@ gen_expandarray(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
|
|||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
// 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;
|
||||
}
|
||||
else {
|
||||
return YJIT_CANT_COMPILE;
|
||||
}
|
||||
return YJIT_KEEP_COMPILING;
|
||||
}
|
||||
|
||||
static codegen_status_t
|
||||
|
|
Loading…
Reference in a new issue