summaryrefslogtreecommitdiff
path: root/lib/ruby_vm/rjit
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ruby_vm/rjit')
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb52
-rw-r--r--lib/ruby_vm/rjit/stats.rb1
2 files changed, 50 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')