summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-12 22:27:43 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-12 23:38:11 -0700
commited269c81aa68ba87e9da2fe4c0c2227ea0689eca (patch)
treef078ed327aeca53de7f026a0d36894775ec75c5c
parentda9c84f859db292ab1127f7ca9b7741fff06557b (diff)
downloadruby-ed269c81aa68ba87e9da2fe4c0c2227ea0689eca.tar.gz
RJIT: Count invokeblock exit types
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb52
-rw-r--r--lib/ruby_vm/rjit/stats.rb1
-rw-r--r--rjit_c.h6
-rw-r--r--rjit_c.rb12
-rwxr-xr-xtool/rjit/bindgen.rb1
5 files changed, 69 insertions, 3 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb
index 83a3cf0389..ce3e8531a2 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}")
- # 73/102
+ # 74/102
case insn.name
when :nop then nop(jit, ctx, asm)
when :getlocal then getlocal(jit, ctx, asm)
@@ -80,7 +80,7 @@ module RubyVM::RJIT
# opt_newarray_max
when :opt_newarray_min then opt_newarray_min(jit, ctx, asm)
when :invokesuper then invokesuper(jit, ctx, asm)
- # invokeblock
+ when :invokeblock then invokeblock(jit, ctx, asm)
when :leave then leave(jit, ctx, asm)
# throw
when :jump then jump(jit, ctx, asm)
@@ -1242,7 +1242,44 @@ module RubyVM::RJIT
jit_call_general(jit, ctx, asm, mid, argc, flags, cme, block_handler, nil)
end
- # invokeblock
+ # @param jit [RubyVM::RJIT::JITState]
+ # @param ctx [RubyVM::RJIT::Context]
+ # @param asm [RubyVM::RJIT::Assembler]
+ def invokeblock(jit, ctx, asm)
+ unless jit.at_current_insn?
+ defer_compilation(jit, ctx, asm)
+ return EndBlock
+ end
+
+ # Get call info
+ cd = C.rb_call_data.new(jit.operand(0))
+ ci = cd.ci
+ argc = C.vm_ci_argc(ci)
+ flags = C.vm_ci_flag(ci)
+
+ # Get block_handler
+ cfp = jit.cfp
+ lep = C.rb_vm_ep_local_ep(cfp.ep)
+ comptime_handler = lep[C::VM_ENV_DATA_INDEX_SPECVAL]
+
+ # Handle each block_handler type
+ if comptime_handler == C::VM_BLOCK_HANDLER_NONE # no block given
+ asm.incr_counter(:invokeblock_none)
+ CantCompile
+ elsif comptime_handler & 0x3 == 0x1 # VM_BH_ISEQ_BLOCK_P
+ asm.incr_counter(:invokeblock_iseq)
+ CantCompile
+ elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P
+ asm.incr_counter(:invokeblock_ifunc)
+ CantCompile
+ elsif symbol?(comptime_handler)
+ asm.incr_counter(:invokeblock_symbol)
+ CantCompile
+ else # Proc
+ asm.incr_counter(:invokeblock_proc)
+ CantCompile
+ end
+ end
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
@@ -3924,10 +3961,19 @@ module RubyVM::RJIT
(C.to_value(obj) & C::RUBY_FLONUM_MASK) == C::RUBY_FLONUM_FLAG
end
+ def symbol?(obj)
+ static_symbol?(obj) || dynamic_symbol?(obj)
+ end
+
def static_symbol?(obj)
(C.to_value(obj) & 0xff) == C::RUBY_SYMBOL_FLAG
end
+ def dynamic_symbol?(obj)
+ return false if C::SPECIAL_CONST_P(obj)
+ C::RB_TYPE_P(obj, C::RUBY_T_SYMBOL)
+ end
+
def shape_too_complex?(obj)
C.rb_shape_get_shape_id(obj) == C::OBJ_TOO_COMPLEX_SHAPE_ID
end
diff --git a/lib/ruby_vm/rjit/stats.rb b/lib/ruby_vm/rjit/stats.rb
index 2fde44bc8e..65bb962aac 100644
--- a/lib/ruby_vm/rjit/stats.rb
+++ b/lib/ruby_vm/rjit/stats.rb
@@ -36,6 +36,7 @@ module RubyVM::RJIT
$stderr.puts("***RJIT: Printing RJIT statistics on exit***")
print_counters(stats, prefix: 'send_', prompt: 'method call exit reasons')
+ print_counters(stats, prefix: 'invokeblock_', prompt: 'invokeblock exit reasons')
print_counters(stats, prefix: 'invokesuper_', prompt: 'invokesuper exit reasons')
print_counters(stats, prefix: 'getblockpp_', prompt: 'getblockparamproxy exit reasons')
print_counters(stats, prefix: 'getivar_', prompt: 'getinstancevariable exit reasons')
diff --git a/rjit_c.h b/rjit_c.h
index 243e7da637..7190e6701a 100644
--- a/rjit_c.h
+++ b/rjit_c.h
@@ -81,6 +81,12 @@ RJIT_RUNTIME_COUNTERS(
invokesuper_me_changed,
invokesuper_same_me,
+ invokeblock_none,
+ invokeblock_iseq,
+ invokeblock_ifunc,
+ invokeblock_symbol,
+ invokeblock_proc,
+
getivar_megamorphic,
getivar_not_heap,
getivar_special_const,
diff --git a/rjit_c.rb b/rjit_c.rb
index aeab210f70..4cf7523c06 100644
--- a/rjit_c.rb
+++ b/rjit_c.rb
@@ -298,6 +298,12 @@ module RubyVM::RJIT # :nodoc: all
Primitive.cexpr! 'rjit_exit_traces()'
end
+ def rb_vm_ep_local_ep(ep)
+ _ep = ep.to_i
+ lep_addr = Primitive.cexpr! 'SIZET2NUM((size_t)rb_vm_ep_local_ep((const VALUE *)NUM2SIZET(_ep)))'
+ C.VALUE.new(lep_addr)
+ end
+
#
# Utilities: Not used by RJIT, but useful for debugging
#
@@ -364,6 +370,7 @@ module RubyVM::RJIT # :nodoc: all
C::RUBY_T_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_MASK) }
C::RUBY_T_MODULE = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_MODULE) }
C::RUBY_T_STRING = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_STRING) }
+ C::RUBY_T_SYMBOL = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_SYMBOL) }
C::SHAPE_CAPACITY_CHANGE = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_CAPACITY_CHANGE) }
C::SHAPE_FLAG_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FLAG_SHIFT) }
C::SHAPE_FROZEN = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FROZEN) }
@@ -1144,6 +1151,11 @@ module RubyVM::RJIT # :nodoc: all
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_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_same_me)")],
+ invokeblock_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_none)")],
+ invokeblock_iseq: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq)")],
+ invokeblock_ifunc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_ifunc)")],
+ invokeblock_symbol: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_symbol)")],
+ invokeblock_proc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_proc)")],
getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_megamorphic)")],
getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_not_heap)")],
getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_special_const)")],
diff --git a/tool/rjit/bindgen.rb b/tool/rjit/bindgen.rb
index cb43e33b0b..e201f3504e 100755
--- a/tool/rjit/bindgen.rb
+++ b/tool/rjit/bindgen.rb
@@ -415,6 +415,7 @@ generator = BindingGenerator.new(
RUBY_T_MASK
RUBY_T_MODULE
RUBY_T_STRING
+ RUBY_T_SYMBOL
SHAPE_CAPACITY_CHANGE
SHAPE_FLAG_SHIFT
SHAPE_FROZEN