ruby-changes:74482
From: Takashi <ko1@a...>
Date: Mon, 14 Nov 2022 13:36:11 +0900 (JST)
Subject: [ruby-changes:74482] 3dd4e381fe (master): Reduce the number of branches in jit_exec (#6722)
https://git.ruby-lang.org/ruby.git/commit/?id=3dd4e381fe From 3dd4e381fe3c7faf886145ad7ab2152c6b199d69 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Sun, 13 Nov 2022 20:35:35 -0800 Subject: Reduce the number of branches in jit_exec (#6722) * Reduce the number of branches in jit_exec * Address build failure in some configurations * Refactor yjit.h --- vm.c | 53 +++++++++++++++++++++++------------------------------ yjit.h | 2 +- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/vm.c b/vm.c index 87c6b47825..d540aa1c8b 100644 --- a/vm.c +++ b/vm.c @@ -378,7 +378,7 @@ extern VALUE rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, V https://github.com/ruby/ruby/blob/trunk/vm.c#L378 const rb_callable_method_entry_t *me); static VALUE vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, int kw_splat, VALUE block_handler); -#if USE_MJIT +#if USE_MJIT || USE_YJIT # ifdef MJIT_HEADER NOINLINE(static COLDFUNC VALUE mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body)); # else @@ -412,46 +412,39 @@ mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_ise https://github.com/ruby/ruby/blob/trunk/vm.c#L412 static inline VALUE jit_exec(rb_execution_context_t *ec) { + // Increment the ISEQ's call counter const rb_iseq_t *iseq = ec->cfp->iseq; struct rb_iseq_constant_body *body = ISEQ_BODY(iseq); - bool yjit_enabled = false; -# ifndef MJIT_HEADER - // Don't want to compile with YJIT or use code generated by YJIT - // when running inside code generated by MJIT. - yjit_enabled = rb_yjit_enabled_p(); -# endif - - if (mjit_call_p || yjit_enabled) { + bool yjit_enabled = rb_yjit_enabled_p(); + if (yjit_enabled || mjit_call_p) { body->total_calls++; } + else { + return Qundef; + } -# ifndef MJIT_HEADER - if (yjit_enabled && !mjit_call_p && body->total_calls == rb_yjit_call_threshold()) { - // If we couldn't generate any code for this iseq, then return - // Qundef so the interpreter will handle the call. - if (!rb_yjit_compile_iseq(iseq, ec)) { + // Trigger JIT compilation as needed + jit_func_t func; + if (yjit_enabled) { + if (body->total_calls == rb_yjit_call_threshold()) { + // If we couldn't generate any code for this iseq, then return + // Qundef so the interpreter will handle the call. + if (!rb_yjit_compile_iseq(iseq, ec)) { + return Qundef; + } + } + // YJIT tried compiling this function once before and couldn't do + // it, so return Qundef so the interpreter handles it. + if ((func = body->jit_func) == 0) { return Qundef; } } -# endif - - if (!(mjit_call_p || yjit_enabled)) - return Qundef; - - jit_func_t func = body->jit_func; - - // YJIT tried compiling this function once before and couldn't do - // it, so return Qundef so the interpreter handles it. - if (yjit_enabled && func == 0) { - return Qundef; - } - - if (UNLIKELY((uintptr_t)func <= LAST_JIT_ISEQ_FUNC)) { + else if (UNLIKELY((uintptr_t)(func = body->jit_func) <= LAST_JIT_ISEQ_FUNC)) { return mjit_check_iseq(ec, iseq, body); } - // Under SystemV x64 calling convention: ec -> RDI, cfp -> RSI - return func(ec, ec->cfp); + // Call the JIT code + return func(ec, ec->cfp); // SystemV x64 calling convention: ec -> RDI, cfp -> RSI } #endif diff --git a/yjit.h b/yjit.h index 7884aef18d..5f2722639f 100644 --- a/yjit.h +++ b/yjit.h @@ -15,7 +15,7 @@ https://github.com/ruby/ruby/blob/trunk/yjit.h#L15 # define YJIT_STATS RUBY_DEBUG #endif -#if USE_YJIT +#if USE_YJIT && !defined(MJIT_HEADER) // MJIT and YJIT can't be enabled simultaneously // We generate x86 or arm64 assembly #if defined(_WIN32) ? defined(_M_AMD64) : (defined(__x86_64__) || defined(__aarch64__)) -- cgit v1.2.3 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/