Skip to content

Commit

Permalink
RJIT: Implement toregexp
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Mar 19, 2023
1 parent d189f8d commit 9c2792c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
46 changes: 44 additions & 2 deletions lib/ruby_vm/rjit/insn_compiler.rb
Expand Up @@ -18,7 +18,7 @@ def compile(jit, ctx, asm, insn)
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)
Expand Down Expand Up @@ -784,7 +784,49 @@ def anytostring(jit, ctx, asm)
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]
Expand Down
1 change: 1 addition & 0 deletions rjit_c.c
Expand Up @@ -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"

Expand Down
12 changes: 12 additions & 0 deletions rjit_c.rb
Expand Up @@ -449,6 +449,10 @@ def C.rb_rjit_global_events
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
Expand All @@ -465,6 +469,10 @@ def C.rb_ary_store
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
Expand Down Expand Up @@ -565,6 +573,10 @@ def C.rb_reg_match_pre
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
Expand Down
3 changes: 3 additions & 0 deletions tool/rjit/bindgen.rb
Expand Up @@ -538,6 +538,9 @@ def push_target(target)
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
Expand Down

0 comments on commit 9c2792c

Please sign in to comment.