diff options
-rw-r--r-- | lib/ruby_vm/rjit/insn_compiler.rb | 46 | ||||
-rw-r--r-- | rjit_c.c | 1 | ||||
-rw-r--r-- | rjit_c.rb | 12 | ||||
-rwxr-xr-x | tool/rjit/bindgen.rb | 3 |
4 files changed, 60 insertions, 2 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb index a66b5c88ef..03b33e9971 100644 --- a/lib/ruby_vm/rjit/insn_compiler.rb +++ b/lib/ruby_vm/rjit/insn_compiler.rb @@ -18,7 +18,7 @@ module RubyVM::RJIT asm.incr_counter(:rjit_insns_count) asm.comment("Insn: #{insn.name}") - # 80/102 + # 81/102 case insn.name when :nop then nop(jit, ctx, asm) when :getlocal then getlocal(jit, ctx, asm) @@ -784,7 +784,49 @@ module RubyVM::RJIT KeepCompiling end - # toregexp + # @param jit [RubyVM::RJIT::JITState] + # @param ctx [RubyVM::RJIT::Context] + # @param asm [RubyVM::RJIT::Assembler] + def toregexp(jit, ctx, asm) + opt = jit.operand(0, signed: true) + cnt = jit.operand(1) + + # Save the PC and SP because this allocates an object and could + # raise an exception. + jit_prepare_routine_call(jit, ctx, asm) + + asm.lea(:rax, ctx.sp_opnd(-C.VALUE.size * cnt)) # values_ptr + ctx.stack_pop(cnt) + + asm.mov(C_ARGS[0], 0) + asm.mov(C_ARGS[1], cnt) + asm.mov(C_ARGS[2], :rax) # values_ptr + asm.call(C.rb_ary_tmp_new_from_values) + + # Save the array so we can clear it later + asm.push(C_RET) + asm.push(C_RET) # Alignment + + asm.mov(C_ARGS[0], ary) + asm.mov(C_ARGS[1], opt) + asm.call(C.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 + asm.pop(:rcx) # Alignment + asm.pop(:rcx) # ary + + # The value we want to push on the stack is in RAX right now + stack_ret = ctx.stack_push + asm.mov(stack_ret, C_RET) + + # Clear the temp array. + asm.mov(C_ARGS[0], :rcx) # ary + asm.call(C.rb_ary_clear) + + KeepCompiling + end + # intern # @param jit [RubyVM::RJIT::JITState] @@ -495,6 +495,7 @@ extern bool rb_vm_ic_hit_p(IC ic, const VALUE *reg_ep); extern rb_event_flag_t rb_rjit_global_events; extern void rb_vm_setinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, VALUE val, IVC ic); extern VALUE rb_vm_throw(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VALUE throwobj); +extern VALUE rb_reg_new_ary(VALUE ary, int opt); #include "rjit_c.rbinc" @@ -449,6 +449,10 @@ module RubyVM::RJIT # :nodoc: all Primitive.cexpr! %q{ SIZET2NUM(rb_rjit_global_events) } end + def C.rb_ary_clear + Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_clear) } + end + def C.rb_ary_entry_internal Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_entry_internal) } end @@ -465,6 +469,10 @@ module RubyVM::RJIT # :nodoc: all Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_store) } end + def C.rb_ary_tmp_new_from_values + Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_ary_tmp_new_from_values) } + end + def C.rb_backref_get Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_backref_get) } end @@ -565,6 +573,10 @@ module RubyVM::RJIT # :nodoc: all Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_match_pre) } end + def C.rb_reg_new_ary + Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_new_ary) } + end + def C.rb_reg_nth_match Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_reg_nth_match) } end diff --git a/tool/rjit/bindgen.rb b/tool/rjit/bindgen.rb index 52d338e1a9..7cc97d3e3f 100755 --- a/tool/rjit/bindgen.rb +++ b/tool/rjit/bindgen.rb @@ -538,6 +538,9 @@ generator = BindingGenerator.new( rb_reg_nth_match rb_gvar_get rb_range_new + rb_ary_tmp_new_from_values + rb_reg_new_ary + rb_ary_clear ], types: %w[ CALL_DATA |