зеркало из https://github.com/github/ruby.git
RJIT: Implement toregexp
This commit is contained in:
Родитель
d189f8d870
Коммит
9c2792c3d3
|
@ -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]
|
||||
|
|
1
rjit_c.c
1
rjit_c.c
|
@ -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"
|
||||
|
||||
|
|
12
rjit_c.rb
12
rjit_c.rb
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче