MJIT: Refactor invokebuiltin_delegate_leave
You shouldn't assume bf->compiler is always non-zero. While struct aref/aset is no longer a builtin function since https://github.com/ruby/ruby/pull/5131, it seems like you could still load such an iseq binary. The refactored code fallbacks to compile_insn_default correctly when bf->compiler is zero.
This commit is contained in:
parent
6844bcc6b4
commit
a22c684c59
@ -202,40 +202,23 @@ module RubyVM::MJIT
|
|||||||
if src = compile_ivar(insn.name, stack_size, pos, status, operands, body)
|
if src = compile_ivar(insn.name, stack_size, pos, status, operands, body)
|
||||||
return src, next_pos, finish_p, compile_insns
|
return src, next_pos, finish_p, compile_insns
|
||||||
end
|
end
|
||||||
when :invokebuiltin, :opt_invokebuiltin_delegate
|
|
||||||
if src = compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
|
|
||||||
return src, next_pos, finish_p, compile_insns
|
|
||||||
end
|
|
||||||
when :opt_getconstant_path
|
when :opt_getconstant_path
|
||||||
if src = compile_getconstant_path(stack_size, pos, insn_len, operands, status)
|
if src = compile_getconstant_path(stack_size, pos, insn_len, operands, status)
|
||||||
return src, next_pos, finish_p, compile_insns
|
return src, next_pos, finish_p, compile_insns
|
||||||
end
|
end
|
||||||
when :leave, :opt_invokebuiltin_delegate_leave
|
when :invokebuiltin, :opt_invokebuiltin_delegate, :opt_invokebuiltin_delegate_leave
|
||||||
src = +''
|
if src = compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
|
||||||
|
|
||||||
# opt_invokebuiltin_delegate_leave also implements leave insn. We need to handle it here for inlining.
|
|
||||||
if insn.name == :opt_invokebuiltin_delegate_leave
|
if insn.name == :opt_invokebuiltin_delegate_leave
|
||||||
if invokebuiltin_src = compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
|
src << compile_leave(stack_size, pos, inlined_iseq_p)
|
||||||
src << invokebuiltin_src
|
finish_p = true
|
||||||
end
|
end
|
||||||
else
|
return src, next_pos, finish_p, compile_insns
|
||||||
|
end
|
||||||
|
when :leave
|
||||||
if stack_size != 1
|
if stack_size != 1
|
||||||
$stderr.puts "MJIT warning: Unexpected JIT stack_size on leave: #{stack_size}" # TODO: check mjit_opts?
|
raise "Unexpected JIT stack_size on leave: #{stack_size}"
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
end
|
src = compile_leave(stack_size, pos, inlined_iseq_p)
|
||||||
|
|
||||||
# Skip vm_pop_frame for inlined call
|
|
||||||
unless inlined_iseq_p
|
|
||||||
# Cancel on interrupts to make leave insn leaf
|
|
||||||
src << " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"
|
|
||||||
src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
|
|
||||||
src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
|
|
||||||
src << " rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);\n"
|
|
||||||
src << " }\n"
|
|
||||||
src << " ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(reg_cfp);\n" # vm_pop_frame
|
|
||||||
end
|
|
||||||
src << " return stack[0];\n"
|
|
||||||
finish_p = true
|
finish_p = true
|
||||||
return src, next_pos, finish_p, compile_insns
|
return src, next_pos, finish_p, compile_insns
|
||||||
end
|
end
|
||||||
@ -424,6 +407,21 @@ module RubyVM::MJIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compile_leave(stack_size, pos, inlined_iseq_p)
|
||||||
|
src = +''
|
||||||
|
# Skip vm_pop_frame for inlined call
|
||||||
|
unless inlined_iseq_p
|
||||||
|
# Cancel on interrupts to make leave insn leaf
|
||||||
|
src << " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"
|
||||||
|
src << " reg_cfp->sp = vm_base_ptr(reg_cfp) + #{stack_size};\n"
|
||||||
|
src << " reg_cfp->pc = original_body_iseq + #{pos};\n"
|
||||||
|
src << " rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);\n"
|
||||||
|
src << " }\n"
|
||||||
|
src << " ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(reg_cfp);\n" # vm_pop_frame
|
||||||
|
end
|
||||||
|
src << " return stack[0];\n"
|
||||||
|
end
|
||||||
|
|
||||||
def compile_getconstant_path(stack_size, pos, insn_len, operands, status)
|
def compile_getconstant_path(stack_size, pos, insn_len, operands, status)
|
||||||
ice = C.IC.new(operands[0]).entry
|
ice = C.IC.new(operands[0]).entry
|
||||||
if !status.compile_info.disable_const_cache && ice
|
if !status.compile_info.disable_const_cache && ice
|
||||||
|
Loading…
x
Reference in New Issue
Block a user