diff --git a/mjit_compile.c b/mjit_compile.c index fe75b45141..589ac50c85 100644 --- a/mjit_compile.c +++ b/mjit_compile.c @@ -114,6 +114,23 @@ fastpath_applied_iseq_p(const CALL_INFO ci, const CALL_CACHE cc, const rb_iseq_t && vm_call_iseq_optimizable_p(ci, cc); // CC_SET_FASTPATH condition } +// Return true if an object of the klass may be a special const. See: rb_class_of +static bool +maybe_special_const_class_p(const VALUE klass) +{ + if (klass == rb_cFalseClass + || klass == rb_cNilClass + || klass == rb_cTrueClass + || klass == rb_cInteger + || klass == rb_cSymbol + || klass == rb_cFloat) { + return true; + } + else { + return false; + } +} + static int compile_case_dispatch_each(VALUE key, VALUE value, VALUE arg) { diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb index d1f4692b5f..8c1c1c094d 100644 --- a/tool/ruby_vm/views/_mjit_compile_send.erb +++ b/tool/ruby_vm/views/_mjit_compile_send.erb @@ -34,9 +34,11 @@ fprintf(f, "{\n"); % # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things. + bool opt_class_of = !maybe_special_const_class_p(captured_cc->klass); // If true, use RBASIC_CLASS instead of CLASS_OF to reduce code size fprintf(f, " const struct rb_callcache *cc = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)captured_cc); fprintf(f, " const rb_callable_method_entry_t *cc_cme = (const rb_callable_method_entry_t *)0x%"PRIxVALUE";\n", (VALUE)vm_cc_cme(captured_cc)); - fprintf(f, " if (UNLIKELY(!vm_cc_valid_p(cc, cc_cme, CLASS_OF(stack[%d])))) {\n", b->stack_size + sp_inc - 1); + fprintf(f, " const VALUE recv = stack[%d];\n", b->stack_size + sp_inc - 1); + fprintf(f, " if (UNLIKELY(%s || !vm_cc_valid_p(cc, cc_cme, %s(recv)))) {\n", opt_class_of ? "RB_SPECIAL_CONST_P(recv)" : "false", opt_class_of ? "RBASIC_CLASS" : "CLASS_OF"); fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); fprintf(f, " goto send_cancel;\n");