diff options
Diffstat (limited to 'lib/ruby_vm/rjit')
-rw-r--r-- | lib/ruby_vm/rjit/insn_compiler.rb | 52 | ||||
-rw-r--r-- | lib/ruby_vm/rjit/stats.rb | 1 |
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') |