Skip to content

Commit

Permalink
Reduce the number of branches in jit_exec
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Nov 13, 2022
1 parent 68e0523 commit caf20b3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 28 deletions.
49 changes: 21 additions & 28 deletions vm.c
Expand Up @@ -378,7 +378,7 @@ extern VALUE rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, V
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
Expand Down Expand Up @@ -412,41 +412,34 @@ mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_ise
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 compilation for each JIT
mjit_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;

mjit_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);
}

Expand Down
4 changes: 4 additions & 0 deletions yjit.h
Expand Up @@ -25,7 +25,11 @@
#endif

// Expose these as declarations since we are building YJIT.
#ifdef MJIT_HEADER // MJIT and YJIT can't be enabled simultaneously
static inline bool rb_yjit_enabled_p(void) { return false; }
#else
bool rb_yjit_enabled_p(void);
#endif
unsigned rb_yjit_call_threshold(void);
void rb_yjit_invalidate_all_method_lookup_assumptions(void);
void rb_yjit_method_lookup_change(VALUE klass, ID mid);
Expand Down

0 comments on commit caf20b3

Please sign in to comment.