diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb index 29a66b4913..a266c11665 100644 --- a/lib/ruby_vm/mjit/insn_compiler.rb +++ b/lib/ruby_vm/mjit/insn_compiler.rb @@ -2114,7 +2114,7 @@ module RubyVM::MJIT # and so only have to do this once at compile time this is fine to always # check and side exit. comptime_recv = jit.peek_at_stack(argc) - unless comptime_recv.kind_of?(current_defined_class) + unless C.rb_obj_is_kind_of(comptime_recv, current_defined_class) return CantCompile end @@ -2125,6 +2125,12 @@ module RubyVM::MJIT return CantCompile end + # workaround -- TODO: Why does this happen? + if me.to_i == cme.to_i + asm.incr_counter(:invokesuper_same_me) + return CantCompile + end + # Check that we'll be able to write this method dispatch before generating checks cme_def_type = cme.def.type if cme_def_type != C.VM_METHOD_TYPE_ISEQ && cme_def_type != C.VM_METHOD_TYPE_CFUNC diff --git a/lib/ruby_vm/mjit/stats.rb b/lib/ruby_vm/mjit/stats.rb index 22be01fe34..55146be479 100644 --- a/lib/ruby_vm/mjit/stats.rb +++ b/lib/ruby_vm/mjit/stats.rb @@ -35,6 +35,7 @@ module RubyVM::MJIT $stderr.puts("***MJIT: Printing MJIT statistics on exit***") print_counters(stats, prefix: 'send_', prompt: 'method call exit reasons') + print_counters(stats, prefix: 'invokesuper_', prompt: 'invokesuper exit reasons') print_counters(stats, prefix: 'getivar_', prompt: 'getinstancevariable exit reasons') print_counters(stats, prefix: 'optaref_', prompt: 'opt_aref exit reasons') print_counters(stats, prefix: 'optgetconst_', prompt: 'opt_getconstant_path exit reasons') diff --git a/mjit_c.h b/mjit_c.h index dde744b0e0..d3d48fd19e 100644 --- a/mjit_c.h +++ b/mjit_c.h @@ -164,6 +164,7 @@ MJIT_RUNTIME_COUNTERS( send_guard_float, invokesuper_me_changed, + invokesuper_same_me, getivar_megamorphic, getivar_not_heap, diff --git a/mjit_c.rb b/mjit_c.rb index 7e7dc187ce..f8914c35ad 100644 --- a/mjit_c.rb +++ b/mjit_c.rb @@ -226,6 +226,14 @@ module RubyVM::MJIT # :nodoc: all Primitive.cexpr! 'rb_class_get_superclass(klass)' end + def ID2SYM(id) + Primitive.cexpr! 'ID2SYM((ID)NUM2SIZET(id))' + end + + def rb_obj_is_kind_of(obj, c) + Primitive.cexpr! 'rb_obj_is_kind_of(obj, c)' + end + #======================================================================================== # # Old stuff @@ -1262,6 +1270,7 @@ module RubyVM::MJIT # :nodoc: all send_guard_symbol: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_symbol)")], send_guard_float: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_float)")], invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), invokesuper_me_changed)")], + invokesuper_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), invokesuper_same_me)")], getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_megamorphic)")], getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_not_heap)")], getivar_not_t_object: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_not_t_object)")],