зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
ea278ddd92
Коммит
3dd4e381fe
53
vm.c
53
vm.c
|
@ -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);
|
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);
|
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
|
# 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));
|
NOINLINE(static COLDFUNC VALUE mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body));
|
||||||
# else
|
# else
|
||||||
|
@ -412,46 +412,39 @@ mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_ise
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
jit_exec(rb_execution_context_t *ec)
|
jit_exec(rb_execution_context_t *ec)
|
||||||
{
|
{
|
||||||
|
// Increment the ISEQ's call counter
|
||||||
const rb_iseq_t *iseq = ec->cfp->iseq;
|
const rb_iseq_t *iseq = ec->cfp->iseq;
|
||||||
struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
|
struct rb_iseq_constant_body *body = ISEQ_BODY(iseq);
|
||||||
bool yjit_enabled = false;
|
bool yjit_enabled = rb_yjit_enabled_p();
|
||||||
# ifndef MJIT_HEADER
|
if (yjit_enabled || mjit_call_p) {
|
||||||
// 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) {
|
|
||||||
body->total_calls++;
|
body->total_calls++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return Qundef;
|
||||||
|
}
|
||||||
|
|
||||||
# ifndef MJIT_HEADER
|
// Trigger JIT compilation as needed
|
||||||
if (yjit_enabled && !mjit_call_p && body->total_calls == rb_yjit_call_threshold()) {
|
jit_func_t func;
|
||||||
// If we couldn't generate any code for this iseq, then return
|
if (yjit_enabled) {
|
||||||
// Qundef so the interpreter will handle the call.
|
if (body->total_calls == rb_yjit_call_threshold()) {
|
||||||
if (!rb_yjit_compile_iseq(iseq, ec)) {
|
// 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;
|
return Qundef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif
|
else if (UNLIKELY((uintptr_t)(func = body->jit_func) <= LAST_JIT_ISEQ_FUNC)) {
|
||||||
|
|
||||||
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)) {
|
|
||||||
return mjit_check_iseq(ec, iseq, body);
|
return mjit_check_iseq(ec, iseq, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Under SystemV x64 calling convention: ec -> RDI, cfp -> RSI
|
// Call the JIT code
|
||||||
return func(ec, ec->cfp);
|
return func(ec, ec->cfp); // SystemV x64 calling convention: ec -> RDI, cfp -> RSI
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
2
yjit.h
2
yjit.h
|
@ -15,7 +15,7 @@
|
||||||
# define YJIT_STATS RUBY_DEBUG
|
# define YJIT_STATS RUBY_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_YJIT
|
#if USE_YJIT && !defined(MJIT_HEADER) // MJIT and YJIT can't be enabled simultaneously
|
||||||
|
|
||||||
// We generate x86 or arm64 assembly
|
// We generate x86 or arm64 assembly
|
||||||
#if defined(_WIN32) ? defined(_M_AMD64) : (defined(__x86_64__) || defined(__aarch64__))
|
#if defined(_WIN32) ? defined(_M_AMD64) : (defined(__x86_64__) || defined(__aarch64__))
|
||||||
|
|
Загрузка…
Ссылка в новой задаче