summaryrefslogtreecommitdiff
path: root/lib/ruby_vm
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-02-21 00:32:37 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 23:28:59 -0800
commit15cea7fd0d729a7646707e386d2e2b43d52f0421 (patch)
treed91475414bd49e6604aa21d0d8835530a2707340 /lib/ruby_vm
parent4d85f21ee806910db4661a4112c556618ee14a99 (diff)
Implement newhash
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7448
Diffstat (limited to 'lib/ruby_vm')
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb48
1 files changed, 45 insertions, 3 deletions
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index b9850f3302..469b5b6cac 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -22,7 +22,7 @@ module RubyVM::MJIT
asm.incr_counter(:mjit_insns_count)
asm.comment("Insn: #{insn.name}")
- # 57/101
+ # 58/101
case insn.name
when :nop then nop(jit, ctx, asm)
when :getlocal then getlocal(jit, ctx, asm)
@@ -57,7 +57,7 @@ module RubyVM::MJIT
when :expandarray then expandarray(jit, ctx, asm)
# concatarray
when :splatarray then splatarray(jit, ctx, asm)
- # newhash
+ when :newhash then newhash(jit, ctx, asm)
# newrange
when :pop then pop(jit, ctx, asm)
when :dup then dup(jit, ctx, asm)
@@ -474,7 +474,49 @@ module RubyVM::MJIT
KeepCompiling
end
- # newhash
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
+ # @param asm [RubyVM::MJIT::Assembler]
+ def newhash(jit, ctx, asm)
+ num = jit.operand(0)
+
+ # Save the PC and SP because we are allocating
+ jit_prepare_routine_call(jit, ctx, asm)
+
+ if num != 0
+ # val = rb_hash_new_with_size(num / 2);
+ asm.mov(C_ARGS[0], num / 2)
+ asm.call(C.rb_hash_new_with_size)
+
+ # Save the allocated hash as we want to push it after insertion
+ asm.push(C_RET)
+ asm.push(C_RET) # x86 alignment
+
+ # Get a pointer to the values to insert into the hash
+ asm.lea(:rcx, ctx.stack_opnd(num - 1))
+
+ # rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);
+ asm.mov(C_ARGS[0], num)
+ asm.mov(C_ARGS[1], :rcx)
+ asm.mov(C_ARGS[2], C_RET)
+ asm.call(C.rb_hash_bulk_insert)
+
+ asm.pop(:rax)
+ asm.pop(:rax)
+
+ ctx.stack_pop(num)
+ stack_ret = ctx.stack_push
+ asm.mov(stack_ret, :rax)
+ else
+ # val = rb_hash_new();
+ asm.call(C.rb_hash_new)
+ stack_ret = ctx.stack_push
+ asm.mov(stack_ret, C_RET)
+ end
+
+ KeepCompiling
+ end
+
# newrange
# @param jit [RubyVM::MJIT::JITState]