RJIT: Use case-in for exhaustive matches

This commit is contained in:
Takashi Kokubun 2023-03-11 22:13:57 -08:00
parent fe34db5a1b
commit 846fc356cb
3 changed files with 20 additions and 33 deletions

View File

@ -3119,23 +3119,20 @@ module RubyVM::RJIT
def jit_call_method(jit, ctx, asm, mid, argc, flags, cme, block_handler, known_recv_class, send_shift: 0) def jit_call_method(jit, ctx, asm, mid, argc, flags, cme, block_handler, known_recv_class, send_shift: 0)
# The main check of vm_call_method before vm_call_method_each_type # The main check of vm_call_method before vm_call_method_each_type
case C::METHOD_ENTRY_VISI(cme) case C::METHOD_ENTRY_VISI(cme)
when C::METHOD_VISI_PUBLIC in C::METHOD_VISI_PUBLIC
# You can always call public methods # You can always call public methods
when C::METHOD_VISI_PRIVATE in C::METHOD_VISI_PRIVATE
# Allow only callsites without a receiver # Allow only callsites without a receiver
if flags & C::VM_CALL_FCALL == 0 if flags & C::VM_CALL_FCALL == 0
asm.incr_counter(:send_private) asm.incr_counter(:send_private)
return CantCompile return CantCompile
end end
when C::METHOD_VISI_PROTECTED in C::METHOD_VISI_PROTECTED
# If the method call is an FCALL, it is always valid # If the method call is an FCALL, it is always valid
if flags & C::VM_CALL_FCALL == 0 if flags & C::VM_CALL_FCALL == 0
# otherwise we need an ancestry check to ensure the receiver is valid to be called as protected # otherwise we need an ancestry check to ensure the receiver is valid to be called as protected
jit_protected_callee_ancestry_guard(asm, cme, side_exit(jit, ctx)) jit_protected_callee_ancestry_guard(asm, cme, side_exit(jit, ctx))
end end
else
# TODO: Change them to a constant and use case-in instead
raise 'unreachable'
end end
# Get a compile-time receiver # Get a compile-time receiver
@ -3168,40 +3165,37 @@ module RubyVM::RJIT
# @param asm [RubyVM::RJIT::Assembler] # @param asm [RubyVM::RJIT::Assembler]
def jit_call_method_each_type(jit, ctx, asm, argc, flags, cme, comptime_recv, recv_opnd, block_handler, known_recv_class, send_shift:) def jit_call_method_each_type(jit, ctx, asm, argc, flags, cme, comptime_recv, recv_opnd, block_handler, known_recv_class, send_shift:)
case cme.def.type case cme.def.type
when C::VM_METHOD_TYPE_ISEQ in C::VM_METHOD_TYPE_ISEQ
iseq = def_iseq_ptr(cme.def) iseq = def_iseq_ptr(cme.def)
jit_call_iseq_setup(jit, ctx, asm, cme, flags, argc, iseq, block_handler, send_shift:) jit_call_iseq_setup(jit, ctx, asm, cme, flags, argc, iseq, block_handler, send_shift:)
when C::VM_METHOD_TYPE_NOTIMPLEMENTED in C::VM_METHOD_TYPE_NOTIMPLEMENTED
asm.incr_counter(:send_notimplemented) asm.incr_counter(:send_notimplemented)
return CantCompile return CantCompile
when C::VM_METHOD_TYPE_CFUNC in C::VM_METHOD_TYPE_CFUNC
jit_call_cfunc(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:) jit_call_cfunc(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
when C::VM_METHOD_TYPE_ATTRSET in C::VM_METHOD_TYPE_ATTRSET
asm.incr_counter(:send_attrset) asm.incr_counter(:send_attrset)
return CantCompile return CantCompile
when C::VM_METHOD_TYPE_IVAR in C::VM_METHOD_TYPE_IVAR
jit_call_ivar(jit, ctx, asm, cme, flags, argc, comptime_recv, recv_opnd, send_shift:) jit_call_ivar(jit, ctx, asm, cme, flags, argc, comptime_recv, recv_opnd, send_shift:)
when C::VM_METHOD_TYPE_MISSING in C::VM_METHOD_TYPE_MISSING
asm.incr_counter(:send_missing) asm.incr_counter(:send_missing)
return CantCompile return CantCompile
when C::VM_METHOD_TYPE_BMETHOD in C::VM_METHOD_TYPE_BMETHOD
jit_call_bmethod(jit, ctx, asm, argc, flags, cme, comptime_recv, recv_opnd, block_handler, known_recv_class, send_shift:) jit_call_bmethod(jit, ctx, asm, argc, flags, cme, comptime_recv, recv_opnd, block_handler, known_recv_class, send_shift:)
when C::VM_METHOD_TYPE_ALIAS in C::VM_METHOD_TYPE_ALIAS
jit_call_alias(jit, ctx, asm, argc, flags, cme, comptime_recv, recv_opnd, block_handler, known_recv_class, send_shift:) jit_call_alias(jit, ctx, asm, argc, flags, cme, comptime_recv, recv_opnd, block_handler, known_recv_class, send_shift:)
when C::VM_METHOD_TYPE_OPTIMIZED in C::VM_METHOD_TYPE_OPTIMIZED
jit_call_optimized(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:) jit_call_optimized(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
when C::VM_METHOD_TYPE_UNDEF in C::VM_METHOD_TYPE_UNDEF
asm.incr_counter(:send_undef) asm.incr_counter(:send_undef)
return CantCompile return CantCompile
when C::VM_METHOD_TYPE_ZSUPER in C::VM_METHOD_TYPE_ZSUPER
asm.incr_counter(:send_zsuper) asm.incr_counter(:send_zsuper)
return CantCompile return CantCompile
when C::VM_METHOD_TYPE_REFINED in C::VM_METHOD_TYPE_REFINED
asm.incr_counter(:send_refined) asm.incr_counter(:send_refined)
return CantCompile return CantCompile
else
asm.incr_counter(:send_unknown_type)
return CantCompile
end end
end end
@ -3457,21 +3451,18 @@ module RubyVM::RJIT
end end
case cme.def.body.optimized.type case cme.def.body.optimized.type
when C::OPTIMIZED_METHOD_TYPE_SEND in C::OPTIMIZED_METHOD_TYPE_SEND
jit_call_opt_send(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:) jit_call_opt_send(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
when C::OPTIMIZED_METHOD_TYPE_CALL in C::OPTIMIZED_METHOD_TYPE_CALL
jit_call_opt_call(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:) jit_call_opt_call(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
when C::OPTIMIZED_METHOD_TYPE_BLOCK_CALL in C::OPTIMIZED_METHOD_TYPE_BLOCK_CALL
asm.incr_counter(:send_optimized_block_call) asm.incr_counter(:send_optimized_block_call)
return CantCompile return CantCompile
when C::OPTIMIZED_METHOD_TYPE_STRUCT_AREF in C::OPTIMIZED_METHOD_TYPE_STRUCT_AREF
jit_call_opt_struct_aref(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:) jit_call_opt_struct_aref(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)
when C::OPTIMIZED_METHOD_TYPE_STRUCT_ASET in C::OPTIMIZED_METHOD_TYPE_STRUCT_ASET
asm.incr_counter(:send_optimized_struct_aset) asm.incr_counter(:send_optimized_struct_aset)
return CantCompile return CantCompile
else
asm.incr_counter(:send_optimized_unknown_type)
return CantCompile
end end
end end

View File

@ -37,7 +37,6 @@ RJIT_RUNTIME_COUNTERS(
send_undef, send_undef,
send_zsuper, send_zsuper,
send_refined, send_refined,
send_unknown_type,
send_stackoverflow, send_stackoverflow,
send_arity, send_arity,
send_c_tracing, send_c_tracing,
@ -75,7 +74,6 @@ RJIT_RUNTIME_COUNTERS(
send_optimized_blockarg, send_optimized_blockarg,
send_optimized_block_call, send_optimized_block_call,
send_optimized_struct_aset, send_optimized_struct_aset,
send_optimized_unknown_type,
send_bmethod_not_iseq, send_bmethod_not_iseq,
send_bmethod_blockarg, send_bmethod_blockarg,

View File

@ -1097,7 +1097,6 @@ module RubyVM::RJIT # :nodoc: all
send_undef: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_undef)")], send_undef: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_undef)")],
send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_zsuper)")], send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_zsuper)")],
send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_refined)")], send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_refined)")],
send_unknown_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_unknown_type)")],
send_stackoverflow: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_stackoverflow)")], send_stackoverflow: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_stackoverflow)")],
send_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_arity)")], send_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_arity)")],
send_c_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_c_tracing)")], send_c_tracing: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_c_tracing)")],
@ -1129,7 +1128,6 @@ module RubyVM::RJIT # :nodoc: all
send_optimized_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_blockarg)")], send_optimized_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_blockarg)")],
send_optimized_block_call: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_block_call)")], send_optimized_block_call: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_block_call)")],
send_optimized_struct_aset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_struct_aset)")], send_optimized_struct_aset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_struct_aset)")],
send_optimized_unknown_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_optimized_unknown_type)")],
send_bmethod_not_iseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_not_iseq)")], send_bmethod_not_iseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_not_iseq)")],
send_bmethod_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_blockarg)")], send_bmethod_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), send_bmethod_blockarg)")],
invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_me_changed)")], invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_me_changed)")],